pub const SQRT_2: f64 =
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157f64;
pub const SQRT_3: f64 = 1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154f64;
pub const SQRT_6: f64 =
2.44948974278317809819728407470589139196594748065667012843269256725096037745731502653985943310464023f64;
pub const SQRT_2_BY_3: f64 =
0.816496580927726032732428024901963797321982493552223376144230855750320125819105008846619811034880078272864f64;
pub const SQRT_3_BY_2: f64 =
1.22474487139158904909864203735294569598297374032833506421634628362548018872865751326992971655232011f64;
pub const ONE_BY_3: f64 =
0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333f64;
pub const TWO_BY_3: f64 =
0.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666f64;
pub const TOL_J2: f64 = 1e-9;
const ONE: f64 = 1.0;
pub const IDENTITY2: [f64; 9] = [ONE, ONE, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
pub const IDENTITY4: [[f64; 9]; 9] = [
[ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE],
];
pub const TRANSPOSITION: [[f64; 9]; 9] = [
[ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -ONE, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -ONE, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -ONE],
];
pub const TRACE_PROJECTION: [[f64; 9]; 9] = [
[ONE, ONE, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[ONE, ONE, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[ONE, ONE, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
];
pub const P_ISO: [[f64; 9]; 9] = [
[ONE_BY_3, ONE_BY_3, ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[ONE_BY_3, ONE_BY_3, ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[ONE_BY_3, ONE_BY_3, ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
];
pub const P_SYM: [[f64; 9]; 9] = [
[ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
];
pub const P_SKEW: [[f64; 9]; 9] = [
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE],
];
pub const P_DEV: [[f64; 9]; 9] = [
[TWO_BY_3, -ONE_BY_3, -ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[-ONE_BY_3, TWO_BY_3, -ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[-ONE_BY_3, -ONE_BY_3, TWO_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ONE],
];
pub const P_SYMDEV: [[f64; 9]; 9] = [
[TWO_BY_3, -ONE_BY_3, -ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[-ONE_BY_3, TWO_BY_3, -ONE_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[-ONE_BY_3, -ONE_BY_3, TWO_BY_3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, ONE, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
];
#[rustfmt::skip]
pub const M_TO_IJ: [(usize, usize); 9] = [
(0,0), (1,1), (2,2), (0,1), (1,2), (0,2), (1,0), (2,1), (2,0), ];
#[rustfmt::skip]
pub const IJ_TO_M: [[usize; 3]; 3] = [
[0, 3, 5],
[6, 1, 4],
[8, 7, 2],
];
#[rustfmt::skip]
pub const IJ_TO_M_SYM: [[usize; 3]; 3] = [
[0, 3, 5],
[3, 1, 4],
[5, 4, 2],
];
#[rustfmt::skip]
pub const MN_TO_IJKL: [[(usize,usize,usize,usize); 9]; 9] = [
[(0,0,0,0), (0,0,1,1), (0,0,2,2), (0,0,0,1), (0,0,1,2), (0,0,0,2), (0,0,1,0), (0,0,2,1), (0,0,2,0)], [(1,1,0,0), (1,1,1,1), (1,1,2,2), (1,1,0,1), (1,1,1,2), (1,1,0,2), (1,1,1,0), (1,1,2,1), (1,1,2,0)], [(2,2,0,0), (2,2,1,1), (2,2,2,2), (2,2,0,1), (2,2,1,2), (2,2,0,2), (2,2,1,0), (2,2,2,1), (2,2,2,0)], [(0,1,0,0), (0,1,1,1), (0,1,2,2), (0,1,0,1), (0,1,1,2), (0,1,0,2), (0,1,1,0), (0,1,2,1), (0,1,2,0)], [(1,2,0,0), (1,2,1,1), (1,2,2,2), (1,2,0,1), (1,2,1,2), (1,2,0,2), (1,2,1,0), (1,2,2,1), (1,2,2,0)], [(0,2,0,0), (0,2,1,1), (0,2,2,2), (0,2,0,1), (0,2,1,2), (0,2,0,2), (0,2,1,0), (0,2,2,1), (0,2,2,0)], [(1,0,0,0), (1,0,1,1), (1,0,2,2), (1,0,0,1), (1,0,1,2), (1,0,0,2), (1,0,1,0), (1,0,2,1), (1,0,2,0)], [(2,1,0,0), (2,1,1,1), (2,1,2,2), (2,1,0,1), (2,1,1,2), (2,1,0,2), (2,1,1,0), (2,1,2,1), (2,1,2,0)], [(2,0,0,0), (2,0,1,1), (2,0,2,2), (2,0,0,1), (2,0,1,2), (2,0,0,2), (2,0,1,0), (2,0,2,1), (2,0,2,0)], ];
#[rustfmt::skip]
pub const IJKL_TO_MN: [[[[(usize, usize); 3]; 3]; 3]; 3] = [
[
[[(0,0), (0,3), (0,5)], [(0,6), (0,1), (0,4)], [(0,8), (0,7), (0,2)]], [[(3,0), (3,3), (3,5)], [(3,6), (3,1), (3,4)], [(3,8), (3,7), (3,2)]], [[(5,0), (5,3), (5,5)], [(5,6), (5,1), (5,4)], [(5,8), (5,7), (5,2)]], ],
[
[[(6,0), (6,3), (6,5)], [(6,6), (6,1), (6,4)], [(6,8), (6,7), (6,2)]], [[(1,0), (1,3), (1,5)], [(1,6), (1,1), (1,4)], [(1,8), (1,7), (1,2)]], [[(4,0), (4,3), (4,5)], [(4,6), (4,1), (4,4)], [(4,8), (4,7), (4,2)]], ],
[
[[(8,0), (8,3), (8,5)], [(8,6), (8,1), (8,4)], [(8,8), (8,7), (8,2)]], [[(7,0), (7,3), (7,5)], [(7,6), (7,1), (7,4)], [(7,8), (7,7), (7,2)]], [[(2,0), (2,3), (2,5)], [(2,6), (2,1), (2,4)], [(2,8), (2,7), (2,2)]], ],
];
#[rustfmt::skip]
pub const IJKL_TO_MN_SYM: [[[[(usize, usize); 3]; 3]; 3]; 3] = [
[
[[(0,0), (0,3), (0,5)], [(0,3), (0,1), (0,4)], [(0,5), (0,4), (0,2)]], [[(3,0), (3,3), (3,5)], [(3,3), (3,1), (3,4)], [(3,5), (3,4), (3,2)]], [[(5,0), (5,3), (5,5)], [(5,3), (5,1), (5,4)], [(5,5), (5,4), (5,2)]], ],
[
[[(3,0), (3,3), (3,5)], [(3,3), (3,1), (3,4)], [(3,5), (3,4), (3,2)]], [[(1,0), (1,3), (1,5)], [(1,3), (1,1), (1,4)], [(1,5), (1,4), (1,2)]], [[(4,0), (4,3), (4,5)], [(4,3), (4,1), (4,4)], [(4,5), (4,4), (4,2)]], ],
[
[[(5,0), (5,3), (5,5)], [(5,3), (5,1), (5,4)], [(5,5), (5,4), (5,2)]], [[(4,0), (4,3), (4,5)], [(4,3), (4,1), (4,4)], [(4,5), (4,4), (4,2)]], [[(2,0), (2,3), (2,5)], [(2,3), (2,1), (2,4)], [(2,5), (2,4), (2,2)]], ],
];
#[cfg(test)]
mod tests {
use super::{
IJKL_TO_MN, IJKL_TO_MN_SYM, IJ_TO_M, IJ_TO_M_SYM, MN_TO_IJKL, M_TO_IJ, ONE_BY_3, SQRT_2, SQRT_2_BY_3, SQRT_3,
SQRT_3_BY_2, SQRT_6, TWO_BY_3,
};
#[test]
fn constants_are_correct() {
assert_eq!(SQRT_2, 2_f64.sqrt());
assert_eq!(SQRT_3, 3_f64.sqrt());
assert_eq!(SQRT_6, 6_f64.sqrt());
assert_eq!(SQRT_2_BY_3, (2_f64 / 3_f64).sqrt());
assert_eq!(SQRT_3_BY_2, (3_f64 / 2_f64).sqrt());
assert_eq!(ONE_BY_3, 1_f64 / 3_f64);
assert_eq!(TWO_BY_3, 2_f64 / 3_f64);
}
#[test]
fn maps_are_correct() {
for m in 0..9 {
let (i, j) = M_TO_IJ[m];
assert_eq!(IJ_TO_M[i][j], m);
let m_sym = match m {
6 => 3,
7 => 4,
8 => 5,
_ => m,
};
assert_eq!(IJ_TO_M_SYM[i][j], m_sym);
}
for m in 0..9 {
let m_sym = match m {
6 => 3,
7 => 4,
8 => 5,
_ => m,
};
for n in 0..9 {
let (i, j, k, l) = MN_TO_IJKL[m][n];
assert_eq!(IJKL_TO_MN[i][j][k][l], (m, n));
let n_sym = match n {
6 => 3,
7 => 4,
8 => 5,
_ => n,
};
assert_eq!(IJKL_TO_MN_SYM[i][j][k][l], (m_sym, n_sym))
}
}
}
}