From d0d9186f4ab8a5fd85dc43cb5e513c59480a2a9f Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Wed, 20 Sep 2017 23:13:31 -0400 Subject: [PATCH] Add documentation for solveh module --- src/solveh.rs | 111 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/src/solveh.rs b/src/solveh.rs index 62c3728f..c09afd5e 100644 --- a/src/solveh.rs +++ b/src/solveh.rs @@ -1,4 +1,53 @@ -//! Solve Hermite/Symmetric linear problems +//! Solve Hermitian (or real symmetric) linear problems and invert Hermitian +//! (or real symmetric) matrices +//! +//! **Note that only the upper triangular portion of the matrix is used.** +//! +//! # Examples +//! +//! Solve `A * x = b`, where `A` is a Hermitian (or real symmetric) matrix: +//! +//! ``` +//! #[macro_use] +//! extern crate ndarray; +//! extern crate ndarray_linalg; +//! +//! use ndarray::prelude::*; +//! use ndarray_linalg::SolveH; +//! # fn main() { +//! +//! let a: Array2 = array![ +//! [3., 2., -1.], +//! [2., -2., 4.], +//! [-1., 4., 5.] +//! ]; +//! let b: Array1 = array![11., -12., 1.]; +//! let x = a.solveh_into(b).unwrap(); +//! assert!(x.all_close(&array![1., 3., -2.], 1e-9)); +//! +//! # } +//! ``` +//! +//! If you are solving multiple systems of linear equations with the same +//! Hermitian or real symmetric coefficient matrix `A`, it's faster to compute +//! the factorization once at the beginning than solving directly using `A`: +//! +//! ``` +//! # extern crate ndarray; +//! # extern crate ndarray_linalg; +//! use ndarray::prelude::*; +//! use ndarray_linalg::*; +//! # fn main() { +//! +//! let a: Array2 = random((3, 3)); +//! let f = a.factorizeh_into().unwrap(); // Factorize A (A is consumed) +//! for _ in 0..10 { +//! let b: Array1 = random(3); +//! let x = f.solveh_into(b).unwrap(); // Solve A * x = b using the factorization +//! } +//! +//! # } +//! ``` use ndarray::*; @@ -9,19 +58,37 @@ use super::types::*; pub use lapack_traits::{Pivot, UPLO}; +/// An interface for solving systems of Hermitian (or real symmetric) linear equations. +/// +/// If you plan to solve many equations with the same Hermitian (or real +/// symmetric) coefficient matrix `A` but different `b` vectors, it's faster to +/// factor the `A` matrix once using the `FactorizeH` trait, and then solve +/// using the `FactorizedH` struct. pub trait SolveH { - fn solveh>(&self, a: &ArrayBase) -> Result> { - let mut a = replicate(a); - self.solveh_mut(&mut a)?; - Ok(a) + /// Solves a system of linear equations `A * x = b` with Hermitian (or real + /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and + /// `x` is the successful result. + fn solveh>(&self, b: &ArrayBase) -> Result> { + let mut b = replicate(b); + self.solveh_mut(&mut b)?; + Ok(b) } - fn solveh_into>(&self, mut a: ArrayBase) -> Result> { - self.solveh_mut(&mut a)?; - Ok(a) + /// Solves a system of linear equations `A * x = b` with Hermitian (or real + /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and + /// `x` is the successful result. + fn solveh_into>(&self, mut b: ArrayBase) -> Result> { + self.solveh_mut(&mut b)?; + Ok(b) } + /// Solves a system of linear equations `A * x = b` with Hermitian (or real + /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and + /// `x` is the successful result. The value of `x` is also assigned to the + /// argument. fn solveh_mut<'a, S: DataMut>(&self, &'a mut ArrayBase) -> Result<&'a mut ArrayBase>; } +/// Represents the Bunch–Kaufman factorization of a Hermitian (or real +/// symmetric) matrix as `A = P * U * D * U^T * P^T`. pub struct FactorizedH { pub a: ArrayBase, pub ipiv: Pivot, @@ -69,6 +136,12 @@ where A: Scalar, S: DataMut, { + /// Computes the inverse of the factorized matrix. + /// + /// **Warning: The inverse is stored only in the upper triangular portion + /// of the result matrix!** If you want the lower triangular portion to be + /// correct, you must fill it in according to the results in the upper + /// triangular portion. pub fn into_inverseh(mut self) -> Result> { unsafe { A::invh( @@ -82,11 +155,19 @@ where } } +/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or +/// real symmetric) matrix refs. pub trait FactorizeH { + /// Computes the Bunch–Kaufman factorization of a Hermitian (or real + /// symmetric) matrix. fn factorizeh(&self) -> Result>; } +/// An interface for computing the Bunch–Kaufman factorization of Hermitian (or +/// real symmetric) matrices. pub trait FactorizeHInto { + /// Computes the Bunch–Kaufman factorization of a Hermitian (or real + /// symmetric) matrix. fn factorizeh_into(self) -> Result>; } @@ -116,13 +197,27 @@ where } } +/// An interface for inverting Hermitian (or real symmetric) matrix refs. pub trait InverseH { type Output; + /// Computes the inverse of the Hermitian (or real symmetric) matrix. + /// + /// **Warning: The inverse is stored only in the upper triangular portion + /// of the result matrix!** If you want the lower triangular portion to be + /// correct, you must fill it in according to the results in the upper + /// triangular portion. fn invh(&self) -> Result; } +/// An interface for inverting Hermitian (or real symmetric) matrices. pub trait InverseHInto { type Output; + /// Computes the inverse of the Hermitian (or real symmetric) matrix. + /// + /// **Warning: The inverse is stored only in the upper triangular portion + /// of the result matrix!** If you want the lower triangular portion to be + /// correct, you must fill it in according to the results in the upper + /// triangular portion. fn invh_into(self) -> Result; }