Skip to content

Update document #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 9 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,16 @@ Linear algebra package for [rust-ndarray](https://github.com/bluss/rust-ndarray)

Examples
---------
See [examples](https://github.com/termoshtt/ndarray-linalg/tree/master/examples) directory.

```rust
extern crate ndarray;
extern crate ndarray_linalg;

use ndarray::prelude::*;
use ndarray_linalg::prelude::*;

fn main() {
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]);
let (e, vecs) = a.clone().eigh().unwrap();
println!("eigenvalues = \n{:?}", e);
println!("V = \n{:?}", vecs);
let av = a.dot(&vecs);
println!("AV = \n{:?}", av);
}
```
Versions
---------

See complete example at [src/bin/main.rs](src/bin/main.rs).
- v0.5.0 (not released)
- **Breaking Change** Rewrite all algorithms to support complex numbers and general `ArrayBase`

Progress
---------
Some algorithms have not been implemented yet. See [#6](https://github.com/termoshtt/ndarray-linalg/issues/6).
- v0.4.1
- ADD: assertion [#31](https://github.com/termoshtt/ndarray-linalg/pull/31)

Similar Projects
-----------------
- [linxal](https://github.com/masonium/linxal)
- v0.4.0
- MOD: use ndarray v0.9
2 changes: 2 additions & 0 deletions src/assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use ndarray::*;
use super::types::*;
use super::norm::*;

/// check two values are close in terms of the relative torrence
pub fn rclose<A, Tol>(test: A, truth: A, rtol: Tol) -> Result<Tol, Tol>
where A: Field + Absolute<Output = Tol>,
Tol: RealField
Expand All @@ -13,6 +14,7 @@ pub fn rclose<A, Tol>(test: A, truth: A, rtol: Tol) -> Result<Tol, Tol>
if dev < rtol { Ok(dev) } else { Err(dev) }
}

/// check two values are close in terms of the absolute torrence
pub fn aclose<A, Tol>(test: A, truth: A, atol: Tol) -> Result<Tol, Tol>
where A: Field + Absolute<Output = Tol>,
Tol: RealField
Expand Down
5 changes: 3 additions & 2 deletions src/cholesky.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Cholesky decomposition

use ndarray::*;
use num_traits::Zero;
Expand All @@ -6,8 +7,8 @@ use super::error::*;
use super::layout::*;
use super::triangular::IntoTriangular;

use impl2::LapackScalar;
pub use impl2::UPLO;
use lapack_traits::LapackScalar;
pub use lapack_traits::UPLO;

pub trait Cholesky<K> {
fn cholesky(self, UPLO) -> Result<K>;
Expand Down
5 changes: 3 additions & 2 deletions src/eigh.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Eigenvalue decomposition for Hermite matrices

use ndarray::*;

use super::error::*;
use super::layout::*;

use impl2::LapackScalar;
pub use impl2::UPLO;
use lapack_traits::LapackScalar;
pub use lapack_traits::UPLO;

pub trait Eigh<EigVal, EigVec> {
fn eigh(self, UPLO) -> Result<(EigVal, EigVec)>;
Expand Down
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ndarray::{Ixs, ShapeError};

pub type Result<T> = ::std::result::Result<T, LinalgError>;

/// Master Error type of this crate
#[derive(Debug, EnumError)]
pub enum LinalgError {
NotSquare(NotSquareError),
Expand All @@ -15,6 +16,7 @@ pub enum LinalgError {
Shape(ShapeError),
}

/// Error from LAPACK
#[derive(Debug, new)]
pub struct LapackError {
pub return_code: i32,
Expand All @@ -38,6 +40,7 @@ impl From<i32> for LapackError {
}
}

/// Error that matrix is not square
#[derive(Debug, new)]
pub struct NotSquareError {
pub rows: i32,
Expand All @@ -56,6 +59,7 @@ impl error::Error for NotSquareError {
}
}

/// Error that strides of the array is not supported
#[derive(Debug, new)]
pub struct StrideError {
pub s0: Ixs,
Expand All @@ -74,6 +78,7 @@ impl error::Error for StrideError {
}
}

/// Error that the memory is not aligned continously
#[derive(Debug, new)]
pub struct MemoryContError {}

Expand Down
3 changes: 3 additions & 0 deletions src/generate.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Generator functions for matrices

use ndarray::*;
use std::ops::*;
Expand All @@ -7,6 +8,7 @@ use super::layout::*;
use super::types::*;
use super::error::*;

/// Hermite conjugate matrix
pub fn conjugate<A, Si, So>(a: &ArrayBase<Si, Ix2>) -> ArrayBase<So, Ix2>
where A: Conjugate,
Si: Data<Elem = A>,
Expand All @@ -19,6 +21,7 @@ pub fn conjugate<A, Si, So>(a: &ArrayBase<Si, Ix2>) -> ArrayBase<So, Ix2>
a
}

/// Generate random array
pub fn random<A, S, Sh, D>(sh: Sh) -> ArrayBase<S, D>
where A: RandNormal,
S: DataOwned<Elem = A>,
Expand Down
2 changes: 1 addition & 1 deletion src/impl2/cholesky.rs → src/lapack_traits/cholesky.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! implement Cholesky decomposition
//! Cholesky decomposition

use lapack::c;

Expand Down
2 changes: 2 additions & 0 deletions src/impl2/eigh.rs → src/lapack_traits/eigh.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Eigenvalue decomposition for Hermite matrices

use lapack::c;
use num_traits::Zero;
Expand All @@ -8,6 +9,7 @@ use layout::Layout;

use super::{into_result, UPLO};

/// Wraps `*syev` for real and `*heev` for complex
pub trait Eigh_: AssociatedReal {
fn eigh(calc_eigenvec: bool, Layout, UPLO, a: &mut [Self]) -> Result<Vec<Self::Real>>;
}
Expand Down
2 changes: 2 additions & 0 deletions src/impl2/mod.rs → src/lapack_traits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Define traits wrapping LAPACK routines

pub mod opnorm;
pub mod qr;
Expand Down Expand Up @@ -33,6 +34,7 @@ pub fn into_result<T>(info: i32, val: T) -> Result<T> {
}
}

/// Upper/Lower specification for seveal usages
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum UPLO {
Expand Down
2 changes: 1 addition & 1 deletion src/impl2/opnorm.rs → src/lapack_traits/opnorm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implement Operator norms for matrices
//! Operator norms of matrices

use lapack::c;
use lapack::c::Layout::ColumnMajor as cm;
Expand Down
3 changes: 2 additions & 1 deletion src/impl2/qr.rs → src/lapack_traits/qr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implement QR decomposition
//! QR decomposition

use std::cmp::min;
use num_traits::Zero;
Expand All @@ -10,6 +10,7 @@ use layout::Layout;

use super::into_result;

/// Wraps `*geqrf` and `*orgqr` (`*ungqr` for complex numbers)
pub trait QR_: Sized {
fn householder(Layout, a: &mut [Self]) -> Result<Vec<Self>>;
fn q(Layout, a: &mut [Self], tau: &[Self]) -> Result<()>;
Expand Down
2 changes: 2 additions & 0 deletions src/impl2/solve.rs → src/lapack_traits/solve.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Solve linear problem using LU decomposition

use lapack::c;

Expand All @@ -9,6 +10,7 @@ use super::{Transpose, into_result};

pub type Pivot = Vec<i32>;

/// Wraps `*getrf`, `*getri`, and `*getrs`
pub trait Solve_: Sized {
fn lu(Layout, a: &mut [Self]) -> Result<Pivot>;
fn inv(Layout, a: &mut [Self], &Pivot) -> Result<()>;
Expand Down
7 changes: 6 additions & 1 deletion src/impl2/svd.rs → src/lapack_traits/svd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implement Operator norms for matrices
//! Singular-value decomposition

use lapack::c;
use num_traits::Zero;
Expand All @@ -17,12 +17,17 @@ enum FlagSVD {
No = b'N',
}

/// Result of SVD
pub struct SVDOutput<A: AssociatedReal> {
/// diagonal values
pub s: Vec<A::Real>,
/// Unitary matrix for destination space
pub u: Option<Vec<A>>,
/// Unitary matrix for departure space
pub vt: Option<Vec<A>>,
}

/// Wraps `*gesvd`
pub trait SVD_: AssociatedReal {
fn svd(Layout, calc_u: bool, calc_vt: bool, a: &mut [Self]) -> Result<SVDOutput<Self>>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum Diag {
NonUnit = b'N',
}

/// Wraps `*trtri` and `*trtrs`
pub trait Triangular_: Sized {
fn inv_triangular(l: Layout, UPLO, Diag, a: &mut [Self]) -> Result<()>;
fn solve_triangular(al: Layout, bl: Layout, UPLO, Diag, a: &[Self], b: &mut [Self]) -> Result<()>;
Expand Down
1 change: 1 addition & 0 deletions src/layout.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Memory layout of matrices

use ndarray::*;
use lapack::c;
Expand Down
66 changes: 38 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
//! This crate implements matrix manipulation for
//! [rust-ndarray](https://github.com/bluss/rust-ndarray) using LAPACK.
//! Linear algebra package for [rust-ndarray](https://github.com/bluss/rust-ndarray) using LAPACK via [stainless-steel/lapack](https://github.com/stainless-steel/lapack)
//!
//! Basic manipulations are implemented as matrix traits,
//! [Matrix](matrix/trait.Matrix.html), [SquareMatrix](square/trait.SquareMatrix.html),
//! and [HermiteMatrix](hermite/trait.HermiteMatrix.html).
//! Linear algebra methods
//! -----------------------
//! - [QR decomposition](qr/trait.QR.html)
//! - [singular value decomposition](svd/trait.SVD.html)
//! - [solve linear problem](solve/index.html)
//! - [solve linear problem for triangular matrix](triangular/trait.SolveTriangular.html)
//! - [inverse matrix](solve/trait.Inverse.html)
//! - [eigenvalue decomposition for Hermite matrix][eigh]
//!
//! Matrix
//! -------
//! - [singular-value decomposition](matrix/trait.Matrix.html#tymethod.svd)
//! - [LU decomposition](matrix/trait.Matrix.html#tymethod.lu)
//! - [QR decomposition](matrix/trait.Matrix.html#tymethod.qr)
//! - [operator norm for L1 norm](matrix/trait.Matrix.html#tymethod.norm_1)
//! - [operator norm for L-inf norm](matrix/trait.Matrix.html#tymethod.norm_i)
//! - [Frobeiuns norm](matrix/trait.Matrix.html#tymethod.norm_f)
//! [eigh]:eigh/trait.Eigh.html
//!
//! SquareMatrix
//! -------------
//! - [inverse of matrix](square/trait.SquareMatrix.html#tymethod.inv)
//! - [trace of matrix](square/trait.SquareMatrix.html#tymethod.trace)
//! - [WIP] eigenvalue
//! Utilities
//! -----------
//! - [assertions for array](index.html#macros)
//! - [generator functions](generate/index.html)
//! - [Scalar trait](types/trait.Field.html)
//!
//! HermiteMatrix
//! --------------
//! - [eigenvalue analysis](hermite/trait.HermiteMatrix.html#tymethod.eigh)
//! - [symmetric square root](hermite/trait.HermiteMatrix.html#tymethod.ssqrt)
//! - [Cholesky factorization](hermite/trait.HermiteMatrix.html#tymethod.cholesky)
//! Usage
//! ------
//! Most functions in this crate is defined as [self-consuming trait technique][sct] like [serde]
//! does.
//!
//! Others
//! -------
//! - [solve triangular](triangular/trait.SolveTriangular.html)
//! - [misc utilities](util/index.html)
//! For example, we can execute [eigh][eigh] using three types of interfaces:
//!
//! ```rust,ignore
//! let a = random((3, 3));
//! let (eval, evec) = a.eigh(UPLO::Upper)?;
//! let (eval, evec) = (&a).eigh(UPLO::Upper)?;
//! let (eval, evec) = (&mut a).eigh(UPLO::Upper)?;
//! ```
//!
//! The first type `a.eigh()` consumes `a`, and the memory of `a` is used for `evec`.
//! The second type `(&a).eigh()` consumes the reference (not `a` itself),
//! and the memory for `evec` is newly allocated.
//! The last one `(&mut a).eigh()` is similar to the first one;
//! It borrows `a` mutably, and rewrite it to contains `evec`.
//! In all cases, the array `eval` is newly allocated.
//!
//! [sct]:https://github.com/serde-rs/serde/releases/tag/v0.9.0
//! [serde]:https://github.com/serde-rs/serde

extern crate blas;
extern crate lapack;
Expand All @@ -47,7 +57,7 @@ extern crate derive_new;
pub mod types;
pub mod error;
pub mod layout;
pub mod impl2;
pub mod lapack_traits;

pub mod cholesky;
pub mod eigh;
Expand Down
2 changes: 1 addition & 1 deletion src/norm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Define trait for vectors
//! Norm of vectors

use std::ops::*;
use ndarray::*;
Expand Down
5 changes: 3 additions & 2 deletions src/opnorm.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! Operator norm

use ndarray::*;

use super::types::*;
use super::error::*;
use super::layout::*;

pub use impl2::NormType;
use impl2::LapackScalar;
pub use lapack_traits::NormType;
use lapack_traits::LapackScalar;

pub trait OperationNorm {
type Output;
Expand Down
3 changes: 2 additions & 1 deletion src/qr.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! QR decomposition

use num_traits::Zero;
use ndarray::*;

use super::error::*;
use super::layout::*;

use impl2::LapackScalar;
use lapack_traits::LapackScalar;

pub trait QR<Q, R> {
fn qr(self) -> Result<(Q, R)>;
Expand Down
5 changes: 3 additions & 2 deletions src/solve.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Solve linear problems

use ndarray::*;
use super::layout::*;
use super::error::*;
use super::impl2::*;
use super::lapack_traits::*;

pub use impl2::{Pivot, Transpose};
pub use lapack_traits::{Pivot, Transpose};

pub struct Factorized<S: Data> {
pub a: ArrayBase<S, Ix2>,
Expand Down
3 changes: 2 additions & 1 deletion src/svd.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//! singular-value decomposition

use ndarray::*;

use super::error::*;
use super::layout::*;
use impl2::LapackScalar;
use lapack_traits::LapackScalar;

pub trait SVD<U, S, VT> {
fn svd(self, calc_u: bool, calc_vt: bool) -> Result<(Option<U>, S, Option<VT>)>;
Expand Down
1 change: 1 addition & 0 deletions src/trace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Trace calculation

use ndarray::*;

Expand Down
Loading