Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tensor operators #111

Merged
merged 44 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
35aec17
Impl vec_outer_update
cpmech May 10, 2024
ec438d0
Fix doc comment
cpmech May 10, 2024
fe6374d
Impl AsMatrix9x9 trait
cpmech May 10, 2024
d0ff144
Impl t2_dyad_t2_update
cpmech May 10, 2024
4cec57f
Impl operators for plasticity
cpmech May 10, 2024
60b1998
[tensor] Improve doc comments
cpmech May 11, 2024
319962f
[wip] Use assert in tensor operations
cpmech May 11, 2024
1c12fa1
Revert back to returning Result in tensor operations
cpmech May 11, 2024
c13d841
Improve tests
cpmech May 11, 2024
ad3b428
Impl tensor4 update
cpmech May 11, 2024
8507788
Tensor2: hold Mandel. Remove inline
cpmech May 12, 2024
bf928d0
Tensor4: hold Mandel. Rename update to add. Remove inline
cpmech May 12, 2024
8c5a18c
Impl serialize for Mandel
cpmech May 12, 2024
2d15e6a
Rename methods add to update
cpmech May 12, 2024
b4b5437
Rename to_array and to_matrix to as_array and as_matrix in Tensor4
cpmech May 12, 2024
c244382
Improve as_array and as_matrix functions of Tensor4
cpmech May 12, 2024
b2209ad
[wip] Use assert in Tensor2 to compare Mandel. Improve doc comments a…
cpmech May 12, 2024
fad4800
[wip] Improve doc comments
cpmech May 12, 2024
9113eed
[wip] Use assert in Tensor4. Improve doc comments
cpmech May 12, 2024
1bbce46
[wip] Use assert in derivatives_t2 functions. Improve doc comments
cpmech May 12, 2024
954138a
[sparse] Improve grammar in doc comments
cpmech May 12, 2024
2eddc31
[tensor][Important][wip] Make vec, mat, and mandel pub(crate)
cpmech May 12, 2024
8f560af
[tensor][wip] Implement symmetric member function of Mandel
cpmech May 12, 2024
4a70314
[wip] Improve asserts in derivatives_t2
cpmech May 12, 2024
328e361
Impl method sym2d_as_symmetric of Tensor2
cpmech May 12, 2024
39d7f40
[Important][wip] Rewrite error handling in derivatives_t4
cpmech May 12, 2024
1d67cd6
[tensor][wip][Important] Improve operation functions
cpmech May 12, 2024
4724441
[wip] Update spectral2.rs
cpmech May 12, 2024
8565988
[wip] Update lin_elasticity
cpmech May 12, 2024
dd9d629
Impl Tensor2 and Tensor4 vector and matrix member functions
cpmech May 12, 2024
c3b7e93
[tensor] Fix doc tests
cpmech May 12, 2024
a30e3db
[tensor2] Improve tests
cpmech May 12, 2024
fb2c6f1
[tensor] Simplify test
cpmech May 12, 2024
8a1e65f
[tensor] Simplify test
cpmech May 12, 2024
a44b1e0
[tensor] Simplify test
cpmech May 12, 2024
6a7c23b
[Important] Split operations file
cpmech May 12, 2024
873640d
Improve plasticity modulus function
cpmech May 12, 2024
c2e965a
Impl mutable access to vec and mat in Tensor2 and Tensor4
cpmech May 12, 2024
2276be3
Impl dim methods of Tensor2 and Tensor4
cpmech May 13, 2024
f32472b
Impl tensor add for Tensor2 and Tensor4
cpmech May 13, 2024
e6df18c
[wip] Impl compliance modulus in LinElasticity
cpmech May 13, 2024
a5c808f
Fix compliance modulus calculation in LinElasticity
cpmech May 13, 2024
b786c28
Improve set_tensor (mirror) method. Impl set_mandel_vector method of …
cpmech May 14, 2024
9bb864c
Improve set_tensor method of Tensor4
cpmech May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"brusselator",
"bweuler",
"Cephes",
"Cᵢⱼₛₜ",
"cmath",
"condest",
"copysign",
Expand All @@ -30,16 +31,20 @@
"dggev",
"dgssvx",
"Dᵢⱼₖₗ",
"Dᵢⱼₛₜ",
"Dₒₚₖₗ",
"dopri",
"Dormand",
"Dorozhinskii",
"dpotrf",
"dscal",
"Dₛₜₖₗ",
"dsyev",
"dsyrk",
"dtype",
"dydx",
"dznrm2",
"Eᵢⱼₖₗ",
"erfinv",
"FACCON",
"Fehlberg",
Expand Down
2 changes: 2 additions & 0 deletions russell_lab/src/matvec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod mat_vec_mul_update;
mod solve_lin_sys;
mod vec_mat_mul;
mod vec_outer;
mod vec_outer_update;
pub use crate::matvec::complex_mat_vec_mul::*;
pub use crate::matvec::complex_solve_lin_sys::*;
pub use crate::matvec::complex_vec_mat_mul::*;
Expand All @@ -20,3 +21,4 @@ pub use crate::matvec::mat_vec_mul_update::*;
pub use crate::matvec::solve_lin_sys::*;
pub use crate::matvec::vec_mat_mul::*;
pub use crate::matvec::vec_outer::*;
pub use crate::matvec::vec_outer_update::*;
151 changes: 151 additions & 0 deletions russell_lab/src/matvec/vec_outer_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
use crate::matrix::Matrix;
use crate::vector::Vector;
use crate::{to_i32, StrError, CBLAS_COL_MAJOR};

extern "C" {
// Performs the rank 1 operation (tensor product)
// <https://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html>
fn cblas_dger(
layout: i32,
m: i32,
n: i32,
alpha: f64,
x: *const f64,
incx: i32,
y: *const f64,
incy: i32,
a: *mut f64,
lda: i32,
);
}

/// (dger) Performs the outer (tensor) product between two vectors resulting in a matrix (with update)
///
/// ```text
/// a += α ⋅ u outer v
/// (m,n) (m) (n)
/// ```
///
/// See also: <https://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html>
///
/// # Note
///
/// The rows of matrix a must equal the length of vector u and
/// the columns of matrix a must equal the length of vector v
///
/// # Examples
///
/// ```
/// use russell_lab::{vec_outer_update, Matrix, Vector, StrError};
///
/// fn main() -> Result<(), StrError> {
/// let u = Vector::from(&[1.0, 2.0, 3.0]);
/// let v = Vector::from(&[5.0, -2.0, 0.0, 1.0]);
/// let mut a = Matrix::from(&[
/// [1000.0, 0.0, 10.0, 100.0],
/// [2000.0, 0.0, 20.0, 200.0],
/// [3000.0, 0.0, 30.0, 300.0],
/// ]);
/// vec_outer_update(&mut a, 1.0, &u, &v)?;
/// let correct = "┌ ┐\n\
/// │ 1005 -2 10 101 │\n\
/// │ 2010 -4 20 202 │\n\
/// │ 3015 -6 30 303 │\n\
/// └ ┘";
/// assert_eq!(format!("{}", a), correct);
/// Ok(())
/// }
/// ```
pub fn vec_outer_update(a: &mut Matrix, alpha: f64, u: &Vector, v: &Vector) -> Result<(), StrError> {
let m = u.dim();
let n = v.dim();
if a.nrow() != m || a.ncol() != n {
return Err("matrix and vectors are incompatible");
}
let m_i32: i32 = to_i32(m);
let n_i32: i32 = to_i32(n);
let lda = m_i32;
unsafe {
cblas_dger(
CBLAS_COL_MAJOR,
m_i32,
n_i32,
alpha,
u.as_data().as_ptr(),
1,
v.as_data().as_ptr(),
1,
a.as_mut_data().as_mut_ptr(),
lda,
)
}
Ok(())
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod tests {
use super::{vec_outer_update, Matrix, Vector};
use crate::mat_approx_eq;

#[test]
fn mat_vec_mul_fail_on_wrong_dims() {
let u = Vector::new(2);
let v = Vector::new(3);
let mut a_1x3 = Matrix::new(1, 3);
let mut a_2x1 = Matrix::new(2, 1);
assert_eq!(
vec_outer_update(&mut a_1x3, 1.0, &u, &v),
Err("matrix and vectors are incompatible")
);
assert_eq!(
vec_outer_update(&mut a_2x1, 1.0, &u, &v),
Err("matrix and vectors are incompatible")
);
}

#[test]
fn vec_outer_update_works() {
let u = Vector::from(&[1.0, 2.0, 3.0]);
let v = Vector::from(&[5.0, -2.0, 0.0, 1.0]);
let (m, n) = (u.dim(), v.dim());
let mut a = Matrix::new(m, n);
vec_outer_update(&mut a, 3.0, &u, &v).unwrap();
#[rustfmt::skip]
let correct = &[
[15.0, -6.0, 0.0, 3.0],
[30.0, -12.0, 0.0, 6.0],
[45.0, -18.0, 0.0, 9.0],
];
mat_approx_eq(&a, correct, 1e-15);
}

#[test]
fn vec_outer_update_works_1() {
let u = Vector::from(&[1.0, 2.0, 3.0, 4.0]);
let v = Vector::from(&[1.0, 1.0, -2.0]);
let (m, n) = (u.dim(), v.dim());
let mut a = Matrix::new(m, n);
vec_outer_update(&mut a, 2.0, &u, &v).unwrap();
#[rustfmt::skip]
let correct = &[
[2.0, 2.0, -4.0],
[4.0, 4.0, -8.0],
[6.0, 6.0, -12.0],
[8.0, 8.0, -16.0],
];
mat_approx_eq(&a, correct, 1e-15);

// call it again to make sure that summation is happening
#[rustfmt::skip]
let correct2 = &[
[ 4.0, 4.0, -8.0],
[ 8.0, 8.0, -16.0],
[12.0, 12.0, -24.0],
[16.0, 16.0, -32.0],
];
vec_outer_update(&mut a, 2.0, &u, &v).unwrap();
mat_approx_eq(&a, correct2, 1e-15);
}
}
2 changes: 1 addition & 1 deletion russell_sparse/src/complex_solver_klu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl ComplexLinSolTrait for ComplexSolverKLU {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesFull].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesFull].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- NOT AVAILABLE
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/complex_solver_mumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl ComplexLinSolTrait for ComplexSolverMUMPS {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesLower].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesLower].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- shows messages
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/complex_solver_umfpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ impl ComplexLinSolTrait for ComplexSolverUMFPACK {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesFull].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesFull].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- shows messages
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/coo_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ where
///
/// # Input
///
/// * `a` -- where to store the dense matrix; must be (nrow, ncol)
/// * `a` -- where to store the dense matrix; it must be (nrow, ncol)
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/csc_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ where
///
/// # Input
///
/// * `a` -- where to store the dense matrix; must be (nrow, ncol)
/// * `a` -- where to store the dense matrix; it must be (nrow, ncol)
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/csr_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ where
///
/// # Input
///
/// * `a` -- where to store the dense matrix; must be (nrow, ncol)
/// * `a` -- where to store the dense matrix; it must be (nrow, ncol)
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/solver_klu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl LinSolTrait for SolverKLU {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesFull].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesFull].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- NOT AVAILABLE
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/solver_mumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ impl LinSolTrait for SolverMUMPS {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesLower].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesLower].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- shows messages
///
Expand Down
2 changes: 1 addition & 1 deletion russell_sparse/src/solver_umfpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl LinSolTrait for SolverUMFPACK {
///
/// # Input
///
/// * `mat` -- the coefficient matrix A; must be square and, if symmetric, [Sym::YesFull].
/// * `mat` -- the coefficient matrix A; it must be square and, if symmetric, [Sym::YesFull].
/// * `rhs` -- the right-hand side vector with know values an dimension equal to mat.nrow
/// * `verbose` -- shows messages
///
Expand Down
6 changes: 3 additions & 3 deletions russell_tensor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn main() -> Result<(), StrError> {
Mandel::General,
)?;
assert_eq!(
format!("{:.1}", a.vec),
format!("{:.1}", a.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 5.0 │\n\
Expand All @@ -102,7 +102,7 @@ fn main() -> Result<(), StrError> {
Mandel::Symmetric,
)?;
assert_eq!(
format!("{:.1}", b.vec),
format!("{:.1}", b.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 2.0 │\n\
Expand All @@ -119,7 +119,7 @@ fn main() -> Result<(), StrError> {
Mandel::Symmetric2D,
)?;
assert_eq!(
format!("{:.1}", c.vec),
format!("{:.1}", c.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 2.0 │\n\
Expand Down
6 changes: 3 additions & 3 deletions russell_tensor/examples/allocating_second_order_tensors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() -> Result<(), StrError> {
Mandel::General,
)?;
assert_eq!(
format!("{:.1}", a.vec),
format!("{:.1}", a.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 5.0 │\n\
Expand All @@ -35,7 +35,7 @@ fn main() -> Result<(), StrError> {
Mandel::Symmetric,
)?;
assert_eq!(
format!("{:.1}", b.vec),
format!("{:.1}", b.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 2.0 │\n\
Expand All @@ -52,7 +52,7 @@ fn main() -> Result<(), StrError> {
Mandel::Symmetric2D,
)?;
assert_eq!(
format!("{:.1}", c.vec),
format!("{:.1}", c.vector()),
"┌ ┐\n\
│ 1.0 │\n\
│ 2.0 │\n\
Expand Down
5 changes: 2 additions & 3 deletions russell_tensor/src/as_matrix_3x3.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use russell_lab::Matrix;

/// Defines a trait to handle 2D arrays
/// Defines a trait to handle 3x3 matrices
///
/// # Examples
///
Expand Down Expand Up @@ -97,9 +97,8 @@ impl AsMatrix3x3 for Matrix {

#[cfg(test)]
mod tests {
use russell_lab::Matrix;

use super::AsMatrix3x3;
use russell_lab::Matrix;

fn flatten(mat: &dyn AsMatrix3x3) -> Vec<f64> {
let mut res = vec![0.0; 9];
Expand Down
Loading