karpal_algebra/
vector_space.rs1use crate::field::Field;
2use crate::module::Module;
3
4pub trait VectorSpace<F: Field>: Module<F> {}
6
7impl VectorSpace<f32> for f32 {}
8impl VectorSpace<f64> for f64 {}
9
10impl<F: Field + crate::abelian::AbelianGroup> VectorSpace<F> for (F, F) {}
11
12#[cfg(test)]
13mod tests {
14 use super::*;
15 use crate::module::Module;
16 use crate::semiring::Semiring;
17 use karpal_core::Semigroup;
18
19 #[test]
20 fn f64_is_vector_space() {
21 fn use_vs<V: VectorSpace<f64>>(v: V, s: f64) -> V {
22 v.scale(s)
23 }
24 assert!((use_vs(3.0f64, 2.0) - 6.0).abs() < 1e-10);
25 }
26
27 #[test]
28 fn tuple_is_vector_space() {
29 fn add_scaled<V: VectorSpace<f64> + Semigroup>(a: V, b: V, s: f64) -> V {
30 a.combine(b.scale(s))
31 }
32 let result = add_scaled((1.0f64, 0.0), (0.0, 1.0f64), 2.0);
33 assert!((result.0 - 1.0).abs() < 1e-10);
34 assert!((result.1 - 2.0).abs() < 1e-10);
35 }
36
37 #[test]
38 fn tuple_linear_combination() {
39 let e1 = (1.0f64, 0.0);
40 let e2 = (0.0f64, 1.0);
41 let v = e1.scale(3.0).combine(e2.scale(4.0));
42 assert!((v.0 - 3.0).abs() < 1e-10);
43 assert!((v.1 - 4.0).abs() < 1e-10);
44 }
45
46 #[test]
47 fn scalar_field_is_one_dimensional() {
48 let v: f64 = 5.0;
50 let scaled = v.scale(f64::one());
51 assert!((scaled - 5.0).abs() < 1e-10);
52 }
53}