Skip to content

Commit

Permalink
v 2.0.10
Browse files Browse the repository at this point in the history
  • Loading branch information
liborty committed Apr 23, 2024
1 parent 0b4a2e9 commit c4e439f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "rstats"
version = "2.0.9"
version = "2.0.10"
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.."
description = "Statistics, Information Measures, Data Analysis, Linear Algebra, Clifford Algebra, Machine Learning, Geometric Median, Matrix Decompositions, PCA, Mahalanobis Distance, Hulls, Multithreading.."
readme = "README.md"
homepage = "https://github.com/liborty/rstats"
repository = "https://github.com/liborty/rstats"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ Methods which take an additional generic vector argument, such as a vector of we

## Appendix: Recent Releases

* **Version 2.0.10** - Added to struct TriangMat `eigenvectors` (enabling PCA) and `variances` which compute variances of the data cloud along the original axes, by projecting on them and summing the eigenvalue weighted principal components.

* **Version 2.0.9** - Pruned some rarely used methods, simplified `gmparts` and `gmerror`, updated dependencies.

* **Version 2.0.8**' - Changed initial guess in iterative weighted gm methods to weighted mean. This, being more accurate than plain mean, leads to fewer iterations. Updated some dependencies.
Expand Down
25 changes: 22 additions & 3 deletions src/triangmat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{re_error, sumn, RError, Stats, TriangMat, Vecg, RE}; // MStats, MinMax, MutVecg, Stats, VecVec };
use crate::{re_error, sumn, RError, Stats, TriangMat, Vecg, MutVecg, RE}; // MStats, MinMax, MutVecg, Stats, VecVec };
pub use indxvec::{printing::*, Printing, Vecops};

/// Meanings of 'kind' field. Note that 'Upper Symmetric' would represent the same full matrix as
Expand Down Expand Up @@ -83,14 +83,33 @@ impl TriangMat {
}
TriangMat { kind: 2, data }
}
/// Eigenvalues (obtainable from Cholesky L matrix)
/// Eigenvalues from Cholesky L matrix
pub fn eigenvalues(&self) -> Vec<f64> {
self.diagonal().iter().map(|&x| x * x).collect::<Vec<f64>>()
}
/// Determinant (obtainable from Cholesky L matrix)
/// Determinant from Cholesky L matrix
pub fn determinant(&self) -> f64 {
self.diagonal().iter().map(|&x| x * x).product()
}
/// Normalized full eigenvectors from triangular covariance matrix.
/// Can be used together with eigenvalues for Principal Components Analysis.
/// Covariance matrix is symmetric, so
/// we use its rows as eigenvectors (no need to transpose it)
pub fn eigenvectors(&self) -> Vec<Vec<f64>> {
let mut fullcov = self.to_full();
fullcov.iter_mut().for_each(|eigenvector| eigenvector.munit());
fullcov
}
/// Independent variances along the original axes (dimensions),
/// from triangular covariance matrix.
pub fn variances(&self) -> Result< Vec<f64>, RE > {
let eigenvalues = self.cholesky()?.eigenvalues();
let eigenvectors = self.eigenvectors();
let mut result = vec![0_f64;eigenvalues.len()];
eigenvectors.iter().zip(eigenvalues).for_each(
|(eigenvector, eigenvalue)| result.mutvadd(&eigenvector.smult(eigenvalue)));
Ok(result)
}

/// Translates subscripts to a 1d vector, i.e. natural numbers, to a pair of
/// (row,column) coordinates within a lower/upper triangular matrix.
Expand Down
10 changes: 5 additions & 5 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,18 +242,18 @@ fn triangmat() -> Result<(), RE> {
println!("Diagonal: {}",TriangMat::unit(7).diagonal().gr());
let d = 10_usize;
let n = 90_usize;
println!("Testing on a random set of {n} points in {d} dimensional space");
// set_seeds(1133);
println!("Testing on a random set of {n} points in {d} dimensional space");
let pts = ranvv_f64_range(n,d, 0.0..=4.0)?;
// println!("\nTest data:\n{}",pts.gr());
// let transppt = pts.transpose();
let cov = pts.covar(&pts.par_gmedian(EPS))?;
println!("Comediance matrix:\n{cov}");
let chol = cov.cholesky()?;
println!("Cholesky L matrix:\n{chol}");
println!("Sorted eigenvalues of the comediance matrix from Cholesky decomposition:\n{}",
chol.eigenvalues().sortm(false).gr());
println!("Determinant of the comediance matrix (their product): {}",chol.determinant().gr());
println!("Eigenvalues by Cholesky decomposition:\n{}",
chol.eigenvalues().gr());
println!("Determinant (their product): {}",chol.determinant().gr());
println!("Variances of the original data by summing principal components:\n{}",cov.variances()?.gr());
let d = ranv_f64(d)?;
let dmag = d.vmag();
let mahamag = chol.mahalanobis(&d)?;
Expand Down

0 comments on commit c4e439f

Please sign in to comment.