qualia_core_db/solvers/linear_algebra/
vector.rs1use crate::solvers::SolversError;
7
8pub fn add_into(a: &[f64], b: &[f64], c: &mut [f64]) -> Result<(), SolversError> {
10 if a.len() != b.len() || a.len() != c.len() {
11 return Err(SolversError::InvalidDimension);
12 }
13 for i in 0..a.len() {
14 c[i] = a[i] + b[i];
15 }
16 Ok(())
17}
18
19pub fn add_assign(a: &mut [f64], b: &[f64]) -> Result<(), SolversError> {
21 if a.len() != b.len() {
22 return Err(SolversError::InvalidDimension);
23 }
24 for i in 0..a.len() {
25 a[i] += b[i];
26 }
27 Ok(())
28}
29
30pub fn hadamard_into(a: &[f64], b: &[f64], c: &mut [f64]) -> Result<(), SolversError> {
32 if a.len() != b.len() || a.len() != c.len() {
33 return Err(SolversError::InvalidDimension);
34 }
35 for i in 0..a.len() {
36 c[i] = a[i] * b[i];
37 }
38 Ok(())
39}
40
41pub fn hadamard_assign(a: &mut [f64], b: &[f64]) -> Result<(), SolversError> {
43 if a.len() != b.len() {
44 return Err(SolversError::InvalidDimension);
45 }
46 for i in 0..a.len() {
47 a[i] *= b[i];
48 }
49 Ok(())
50}
51
52pub fn scale(a: &mut [f64], s: f64) {
54 for v in a.iter_mut() {
55 *v *= s;
56 }
57}
58
59pub fn axpy(alpha: f64, x: &[f64], y: &mut [f64]) -> Result<(), SolversError> {
61 if x.len() != y.len() {
62 return Err(SolversError::InvalidDimension);
63 }
64 for i in 0..x.len() {
65 y[i] += alpha * x[i];
66 }
67 Ok(())
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn add_is_vector_addition() {
76 let a = [1.0, 2.0, 3.0];
77 let b = [10.0, 20.0, 30.0];
78 let mut c = [0.0; 3];
79 add_into(&a, &b, &mut c).unwrap();
80 assert_eq!(c, [11.0, 22.0, 33.0]);
81 let mut x = a;
82 add_assign(&mut x, &b).unwrap();
83 assert_eq!(x, [11.0, 22.0, 33.0]);
84 }
85
86 #[test]
87 fn hadamard_is_elementwise_product() {
88 let a = [2.0, 3.0, 4.0];
89 let b = [5.0, 0.0, -1.0];
90 let mut c = [0.0; 3];
91 hadamard_into(&a, &b, &mut c).unwrap();
92 assert_eq!(c, [10.0, 0.0, -4.0]);
93 let mut x = a;
94 hadamard_assign(&mut x, &b).unwrap();
95 assert_eq!(x, [10.0, 0.0, -4.0]);
96 }
97
98 #[test]
99 fn scale_and_axpy() {
100 let mut a = [1.0, 2.0, 3.0];
101 scale(&mut a, 2.0);
102 assert_eq!(a, [2.0, 4.0, 6.0]);
103 let x = [1.0, 1.0, 1.0];
104 let mut y = [10.0, 20.0, 30.0];
105 axpy(0.5, &x, &mut y).unwrap();
106 assert_eq!(y, [10.5, 20.5, 30.5]);
107 }
108
109 #[test]
110 fn rejects_length_mismatch() {
111 let a = [1.0, 2.0];
112 let b = [1.0];
113 let mut c = [0.0; 2];
114 assert!(matches!(
115 add_into(&a, &b, &mut c),
116 Err(SolversError::InvalidDimension)
117 ));
118 }
119}