From 7268df85f1f878cb2d9dd6943e5591f0b2b37018 Mon Sep 17 00:00:00 2001 From: L <457124+liborty@users.noreply.github.com> Date: Thu, 2 May 2024 18:09:45 +1000 Subject: [PATCH] 2.1.1 --- README.md | 2 ++ src/triangmat.rs | 23 ++++++++++++++++------- tests/tests.rs | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 97fdd19..ace77d2 100644 --- a/README.md +++ b/README.md @@ -333,6 +333,8 @@ Methods which take an additional generic vector argument, such as a vector of we ## Appendix: Recent Releases +* **Version 2.1.1** - Added function `project` to project a `TriangMat` to a lower dimensional space of selected dimensions. Removed `rows` which was a duplicate of `dim`. + * **Version 2.1.0** - Changed the type of `mid` argument to covariance methods from U -> f64, making the normal expectation for the type of precise geometric medians explicit. Accordingly, moved `covar` and `serial_covar` from trait `VecVecg` to `VecVec`. This might potentially require changing some `use` declarations in your code. * **Version 2.0.12** - added `depth_ratio` diff --git a/src/triangmat.rs b/src/triangmat.rs index 91f44c7..f430222 100644 --- a/src/triangmat.rs +++ b/src/triangmat.rs @@ -40,10 +40,6 @@ impl TriangMat { pub fn is_empty(&self) -> bool { self.data.is_empty() } - /// Square matrix dimension (rows) - pub fn rows(&self) -> usize { - Self::rowcol(self.len()).0 - } /// Squared euclidian vector magnitude (norm) of the data vector pub fn magsq(&self) -> f64 { self.data.vmagsq() @@ -99,8 +95,7 @@ impl TriangMat { let mut fullcov = self.to_full(); fullcov.iter_mut().for_each(|eigenvector| eigenvector.munit()); fullcov - } - + } /// Translates subscripts to a 1d vector, i.e. natural numbers, to a pair of /// (row,column) coordinates within a lower/upper triangular matrix. /// Enables memory efficient representation of triangular matrices as one flat vector. @@ -109,6 +104,20 @@ impl TriangMat { let column = s - row * (row + 1) / 2; // subtracting the last triangular number (of whole rows) (row, column) } + /// Project symmetric/antisymmetric triangmat to a smaller one of the same kind, + /// into a subspace specified by an ascending index of dimensions. + /// Deletes all rows and columns of the missing dimensions. + pub fn project(&self, index: &[usize]) -> Self { + let mut res = Vec::with_capacity(sumn(index.len())); + for &row_idx in index { + let row = self.row(row_idx); + for &column_idx in index { + if column_idx > row.len() { break; }; + res.push(row[column_idx]); + }; + }; + TriangMat { kind:self.kind, data: res } + } /// Extract one row from TriangMat pub fn row(&self, r: usize) -> Vec { @@ -290,7 +299,7 @@ impl TriangMat { { let u = self.to_full(); let mut qm = m.iter().map(|mvec| mvec.tof64()).collect::>>(); - for uvec in u.iter().take(self.rows()) { + for uvec in u.iter().take(self.dim()) { qm.iter_mut() .for_each(|qvec| *qvec = uvec.house_reflect::(qvec)) } diff --git a/tests/tests.rs b/tests/tests.rs index 554006a..c01143f 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -252,6 +252,7 @@ fn triangmat() -> Result<(), RE> { // let transppt = pts.transpose(); let cov = pts.covar(&pts.par_gmedian(EPS))?; println!("Comediance matrix:\n{cov}"); + println!("Projected to subspace given by [0,2,4,6,9]:\n{}",cov.project(&[0,2,4,6,9])); let chol = cov.cholesky()?; println!("Cholesky L matrix:\n{chol}"); println!("Eigenvalues by Cholesky decomposition:\n{}",