Crates.io | condest |
lib.rs | condest |
version | 0.2.1 |
source | src |
created_at | 2019-01-09 11:09:47.570475 |
updated_at | 2019-01-22 10:55:54.739675 |
description | An implementation of the 1-norm and condition number estimator by Higham and Tisseur, 2000 |
homepage | |
repository | https://github.com/superfluffy/rust-condest |
max_upload_size | |
id | 107590 |
size | 57,173 |
This crate implements the matrix 1-norm estimator by Higham and Tisseur,
Algorithm 2.4 on page 7 (1190) in the linked document. It allows for 1-norm estimation
of a single matrices, A
, matrix powers, A^m
, and matrix products, A1 * A2 * ... * An
,
which can be cheaper than explicitly calculating them.
It uses the excellent rust-ndarray
crate for matrix storage.
The example below generates a random matrix a
and estimates its 1-norm. On
average, this gives pretty good results. Of course, there are some matrices
where this algorithm severely underestimates the actual 1-norm. See Higham and
Tisseur for more.
condest::normest1
creates a Normest1
struct, uses it to estimate the
1-norm, and throws it away. If you want to repeatedly estimate 1-norms of
matrices of the same dimensions, initialize Normest1
and call normest1
,
normest1_pow
or normest1_prod
on it.
Important: You need to explicitly link to a BLAS + LAPACK provider such as
openblas_src
. See the explanations given at the blas-lapack-rs
organization.
extern crate openblas_src; // Need to declare `openblas_src` (or some other BLAS provider) explicitly to link to a BLAS library.
use ndarray::{
prelude::*,
Zip,
};
use ndarray_rand::RandomExt;
use rand::{
SeedableRng,
};
use rand::distributions::StandardNormal;
use rand_xoshiro::Xoshiro256Plus;
fn main() {
let t = 2;
let n = 100;
let itmax = 5;
let mut rng = Xoshiro256Plus::seed_from_u64(1234);
let distribution = StandardNormal;
let mut a = Array::random_using((n, n), distribution, &mut rng);
a.mapv_inplace(|x| 1.0/x);
let estimated = condest::normest1(&a, t, itmax);
let expected = {
let (layout, a_slice) = if let Some(a_slice) = a.as_slice() {
(cblas::Layout::RowMajor, a_slice)
} else if let Some(a_slice) = a.as_slice_memory_order() {
(cblas::Layout::ColumnMajor, a_slice)
} else {
panic!("Matrix not contiguous!")
};
unsafe {
lapacke::dlange(
layout,
b'1',
n as i32,
n as i32,
a_slice,
n as i32,
)}
};
assert_eq!(estimated, expected);
}
Right now, only 1-norm estimates are exposed. The vectors needed to estimate the condition number are implemented, but are not yet accessible through an API. Outstanding points are:
normest1
without extra allocation.