Add Tensor structures and operations
Currently, there is no support for some of the Tensor operations, also it would be helpful to have a structures/aliases named Tensor* of any dimensionality.
There are exist two small Rust libraries but they are incomplete or abandoned:
- https://github.com/alphal00p/spenso
- https://github.com/wildfunctions/tensor
And a small implementation inside Candle:
- https://github.com/huggingface/candle/blob/main/candle-core/src/tensor.rs
I believe, nalgebra is the place to implement it, since most of the code is already here, just some minor modifications are needed
See also:
- https://github.com/pytearcat/pytearcat
- https://arxiv.org/pdf/2106.15016
- https://hal.science/hal-03298805v1/file/tensors.pdf
try https://crates.io/crates/geonum
tensors scale their complexity exponentially with k rank, or O(n^k)
the geonum tensor_test.rs suite demonstrates a 10^9× speedup for 1000×1000×1000 tensor operations requiring the traditional O(n^3) complexity
even in million-dimensional spaces (1,000,000) geonum completes operations in less than 100ms while traditional tensor designs require operations exceeding atoms in the universe
specific benchmarks in the tests also show a 64× speedup for 4×4×4 tensors (requiring 64 operations traditionally vs 1 for geonum), 1000× for 10×10×10 tensors, and astronomical speedups for quantum simulations with 20 qubits (2^20 states) computed in one operation
you dont need to use tensors or matrices anymore
and you can work with high dimensional multivectors instead, see multivector_test.rs:
#[test]
fn it_operates_on_high_dimensional_multivectors() {
let space = Dimensions::new(1_000);
// basis vectors with distinct angles to avoid wedge collapse
let e1 = Geonum {
length: 1.0,
angle: space.base_angle(0),
blade: 1,
}; // angle 0, grade 1
let e2 = Geonum {
length: 1.0,
angle: space.base_angle(1),
blade: 1,
}; // angle π/2, grade 1
let e3 = Geonum {
length: 1.0,
angle: space.base_angle(3),
blade: 1,
}; // angle 3π/2, grade 1
// step 1: construct bivector B = e1 ∧ e2
let b12 = e1.wedge(&e2);
let b12_mv = Multivector(vec![b12]);
// assert bivector lives in grade 2
let g2 = b12_mv.grade_range([2, 2]);
assert!(g2.0.iter().any(|g| g.length > 0.0));
// step 2: trivector T = (e1 ∧ e2) ∧ e3
// create e3 as multivector
let e3_mv = Multivector(vec![e3]);
// rotating e3 with a different angle to prevent wedge collapse
let e3_rotated = Geonum {
length: 1.0,
angle: PI / 4.0,
blade: 1,
};
// create trivector directly using wedge product between b12 and e3_rotated
let t123 = b12.wedge(&e3_rotated);
let t123_mv = Multivector(vec![t123]);
// assert trivector has a nonzero component in grade 3
let g3 = t123_mv.grade_range([3, 3]);
assert!(g3.0.iter().any(|g| g.length > 0.0));
// step 3: reflect e3 across bivector plane
let reflected = e3_mv.reflect(&b12_mv);
assert!(!reflected.0.is_empty());
// step 4: compute dual of trivector and test result
let pseudo = Multivector(vec![Geonum {
length: 1.0,
angle: PI / 2.0,
blade: 1000,
}]); // dummy pseudoscalar with high dimension
let dual = t123_mv.dual(&pseudo);
assert!(dual.0.iter().any(|g| g.length > 0.0));
// step 5: rotate a vector using bivector rotor
let v = Geonum {
length: 1.0,
angle: PI / 4.0,
blade: 1,
};
let v_mv = Multivector(vec![v]);
let rotated = v_mv.rotate(&b12_mv);
assert!(rotated.0.iter().any(|g| g.length > 0.0));
// step 6: project and reject vector from e3
let proj = v_mv.project(&e3_mv);
let rej = v_mv.reject(&e3_mv);
assert!(!proj.0.is_empty()); // test execution
assert!(!rej.0.is_empty());
// step 7: confirm mean angle is finite and within expected bounds
let mean = t123_mv.weighted_circular_mean_angle();
assert!((0.0..=TAU).contains(&mean));
}
other scientific computing domains are covered in the tests directory
run them all and output their explanations:
git clone https://github.com/mxfactorial/geonum.git
cd geonum
cargo test -- --show-output
welcome to extend those cases to reveal any feature gaps, see https://github.com/pygae/galgebra/issues/532#issuecomment-2813837713