opensrdk_symbolic_computation/expression/operators/
neg.rs1use crate::{BracketsLevel, Expression, ExpressionArray};
2use std::{collections::HashMap, ops::Neg};
3
4impl Neg for Expression {
5 type Output = Self;
6
7 fn neg(self) -> Self::Output {
8 if let Expression::PartialVariable(v) = &self {
9 return Expression::PartialVariable(ExpressionArray::from_factory(
10 v.sizes().to_vec(),
11 |indices| Expression::Neg(v[indices].clone().into()),
12 ));
13 }
14
15 if let Expression::Constant(mut v) = self {
16 v.elems_mut().into_iter().for_each(|v| *v = -*v);
17 return v.into();
18 }
19 if let Expression::Neg(v) = self {
20 return *v;
21 }
22
23 Expression::Neg(self.into())
24 }
25}
26
27impl Expression {
28 pub(crate) fn diff_neg(v: &Box<Expression>, variable_ids: &[&str]) -> Vec<Expression> {
29 v.differential(variable_ids)
30 .into_iter()
31 .map(|e| -e)
32 .collect()
33 }
34
35 pub(crate) fn tex_code_neg(v: &Box<Expression>, symbols: &HashMap<&str, &str>) -> String {
36 format!("{{-{}}}", v._tex_code(symbols, BracketsLevel::ForOperation))
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use std::{
43 collections::HashMap,
44 ops::{Add, Neg},
45 };
46
47 use opensrdk_linear_algebra::sparse::SparseTensor;
48
49 use crate::Expression;
50
51 #[test]
52 fn it_works() {
53 let a1 = 5.0f64;
54 let b1 = vec![a1; 8];
55 let mut hash1 = HashMap::new();
56 hash1.insert(vec![3, 2, 1], 2.0);
57 hash1.insert(vec![1usize; 3], 3.0);
58 hash1.insert(vec![4usize; 3], 4.0);
59 hash1.insert(vec![5usize; 3], 2.0);
60 let c1 = SparseTensor::from(vec![6usize; 3], hash1).unwrap();
61
62 let ea1 = Expression::from(a1);
63 let eb1 = Expression::from(b1.clone());
64 let ec1 = Expression::from(c1.clone());
65
66 let ea = ea1.neg();
67 let eb = eb1.neg();
68 let ec = ec1.neg();
69
70 let a = Expression::from(-a1);
71 let b = Expression::from(b1.iter().map(|j| -j).collect::<Vec<f64>>());
72 let c = Expression::from(-c1);
73
74 assert_eq!(ea, a);
75 assert_eq!(eb, b);
76 assert_eq!(ec, c);
77 }
78}