Skip to content

Commit

Permalink
2.1.11
Browse files Browse the repository at this point in the history
  • Loading branch information
liborty committed Jul 17, 2024
1 parent 6800309 commit 97a1adf
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rstats"
version = "2.1.10"
version = "2.1.11"
authors = ["Libor Spacek"]
edition = "2021"
description = "Statistics, Information Measures, Data Analysis, Linear Algebra, Clifford Algebra, Machine Learning, Geometric Median, Matrix Decompositions, Mahalanobis Distance, Hulls, Multithreading.."
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ Methods which take an additional generic vector argument, such as a vector of we

## Appendix: Recent Releases

* **Version 2.1.11** - Some minor tidying up of code.

* **Version 2.1.10** - Added `project` of a `TriangMat` to a subspace given by a subspace index.

* **Version 2.1.9** - Added multiplications and more tests for `TriangMat`.
Expand Down
36 changes: 16 additions & 20 deletions src/triangmat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,22 +310,21 @@ impl TriangMat {
}
/// Efficient Cholesky-Banachiewicz matrix decomposition into `LL'`,
/// where L is the returned lower triangular matrix and L' its upper triangular transpose.
/// Expects as input a positive definite matrix
/// in TriangMat compact form, such as a covariance matrix produced by `covar`.
/// The computations are all done on the compact form,
/// Takes a positive definite TriangMat matrix,
/// such as a covariance matrix produced by `covar`.
/// The computations are all done in the compact form,
/// making this implementation memory efficient for large (symmetric) matrices.
/// Reports errors if the above conditions are not satisfied.
/// Reports errors if the input expectations are not satisfied.
pub fn cholesky(&self) -> Result<Self, RE> {
let sl = self.data.len();
// input not long enough to compute anything
if sl < 3 {
return nodata_error("cholesky needs at least 3x3 TriangMat");
};
// n is the dimension of the implied square matrix.
// Not needed as an extra argument. We compute it
// by solving a quadratic equation in seqtosubs()
// It is obtained by solving a quadratic equation in rowcol()
let (n, c) = rowcol(sl);
// input is not a triangular number, is of wrong size
// if the input is not a triangular number, then it is of the wrong size
if c != 0 {
return data_error("cholesky needs a triangular matrix");
};
Expand Down Expand Up @@ -386,27 +385,24 @@ impl TriangMat {
if self.kind != 0 { return data_error("forward-substitute expects plain lower kind"); };
let data = &self.data;
if data.len() < 3 {
return Err(RError::NoDataError(
"forward-substitute needs at least three items".to_owned(),
));
return nodata_error("forward-substitute needs at least three items");
};
// 2d matrix dimension
let n = self.dim();
// dimensions/lengths mismatch
if n != b.len() {
return Err(RError::DataError(
"forward_substitute mismatch of self and b dimension".to_owned(),
));
return data_error("forward_substitute mismatch of self and b dimension");
};
let mut res: Vec<f64> = Vec::with_capacity(n); // result of the same size and shape as b
res.push(f64::from(b[0]) / self.data[0]);
let mut res: Vec<f64> = Vec::with_capacity(n); // result of the same size as b
if self.data[0].is_normal() { res.push( f64::from(b[0])/self.data[0] ) }
else { return arith_error("forward-substitute given underconstrained system"); };
for (row, &b_component) in b.iter().enumerate().take(n).skip(1) {
let rowoffset = sumn(row);
let mut sumtodiag = 0_f64;
for (column, res_component) in res.iter().enumerate() {
sumtodiag += self.data[rowoffset + column] * res_component;
}
res.push((f64::from(b_component) - sumtodiag) / self.data[rowoffset + row]);
let sumtodiag = res.iter().enumerate().map(|(column, res_component)|
self.data[rowoffset + column] * res_component).sum::<f64>();
if self.data[rowoffset + row].is_normal() {
res.push((f64::from(b_component) - sumtodiag) / self.data[rowoffset + row]); }
else { return arith_error("forward-substitute given underconstrained system"); };
}
// println!("Forward substitution: {}",res.gr());
Ok(res)
Expand Down
17 changes: 9 additions & 8 deletions src/vecvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,19 +434,20 @@ where
.map(|(vi, gi)| (vi.clone().into() - gi).powi(2))
.sum();
if mag > eps {
let rec = 1.0_f64 / (mag.sqrt()); // reciprocal of distance (scalar)
// vsum increment by components
// reciprocal of distance (scalar)
let rec = 1.0_f64 / (mag.sqrt());
// vsum increment by components
for (vi, gi) in p.iter().zip(&mut nextg) {
*gi += vi.clone().into() * rec
}
nextrecsum += rec // add separately the reciprocals for final scaling
} // else simply ignore this point v, should its distance from g be <= eps
// add the scaling reciprocal
nextrecsum += rec
} // ignore point p when |p-g| <= eps
}
nextg.iter_mut().for_each(|gi| *gi /= nextrecsum);
// eprintln!("recsum {}, nextrecsum {} diff {}",recsum,nextrecsum,nextrecsum-recsum);
nextg.iter_mut().for_each(|gi| *gi /= nextrecsum);
if nextrecsum - recsum < eps {
return nextg;
}; // termination test
}; // termination
g = nextg;
recsum = nextrecsum;
}
Expand Down Expand Up @@ -605,7 +606,7 @@ where
Ok(TriangMat{ kind:2,data:covsums }) // kind 2 = symmetric, non transposed
}

/// Projects self onto a given basis, e.g. PCA dimensional reduction
/// Projects self onto a given basis, e.g. dimensional reduction
/// The returned vectors will have lengths equal to the number of supplied basis vectors.
fn projection(self, basis: &[Vec<f64>]) -> Result<Vec<Vec<f64>>, RE>
{
Expand Down

0 comments on commit 97a1adf

Please sign in to comment.