dace/
vec.rs

1use crate::*;
2use dacecore::*;
3use auto_ops::*;
4pub use ndarray::linalg::Dot;
5use ndarray::prelude::*;
6use ndarray::Array1;
7use ndarray::*;
8use ndarray_linalg::error::LinalgError;
9use ndarray_linalg::{Inverse, Norm};
10use num_traits::{One, Zero};
11use std::convert::From;
12use std::iter::zip;
13use std::ops;
14use std::{
15    fmt::{Debug, Display},
16    ops::{Deref, DerefMut},
17};
18
19/// Generic vector class to handle vectors
20/// of algebraic types and their algebraic operations.
21pub struct AlgebraicVector<T>(
22    /// 1D ndarray wrapped by the AlgebraicVector
23    pub Array1<T>,
24);
25
26impl<T: PartialEq> PartialEq for AlgebraicVector<T> {
27    fn eq(&self, other: &Self) -> bool {
28        self.0 == other.0
29    }
30}
31
32impl<T: Eq> Eq for AlgebraicVector<T> {}
33
34impl<T> Clone for AlgebraicVector<T>
35where
36    OwnedRepr<T>: RawDataClone,
37{
38    fn clone(&self) -> Self {
39        Self(self.0.clone())
40    }
41}
42
43impl<T> Deref for AlgebraicVector<T> {
44    type Target = Array1<T>;
45
46    fn deref(&self) -> &Self::Target {
47        &self.0
48    }
49}
50
51impl<T> DerefMut for AlgebraicVector<T> {
52    fn deref_mut(&mut self) -> &mut Self::Target {
53        &mut self.0
54    }
55}
56
57impl<T, U> AsRef<T> for AlgebraicVector<U>
58where
59    T: ?Sized,
60    <AlgebraicVector<U> as Deref>::Target: AsRef<T>,
61{
62    fn as_ref(&self) -> &T {
63        self.deref().as_ref()
64    }
65}
66
67impl<T, U> AsMut<T> for AlgebraicVector<U>
68where
69    <AlgebraicVector<U> as Deref>::Target: AsMut<T>,
70{
71    fn as_mut(&mut self) -> &mut T {
72        self.deref_mut().as_mut()
73    }
74}
75
76impl<T> From<Vec<T>> for AlgebraicVector<T> {
77    fn from(v: Vec<T>) -> Self {
78        Self(Array1::from(v))
79    }
80}
81
82impl<T> From<Array1<T>> for AlgebraicVector<T> {
83    fn from(v: Array1<T>) -> Self {
84        Self(v)
85    }
86}
87
88impl<T: Clone> AlgebraicVector<T> {
89    pub fn zeros(shape: impl ShapeBuilder<Dim = Ix1>) -> Self
90    where
91        T: Zero,
92    {
93        Array1::<T>::zeros(shape).into()
94    }
95
96    pub fn ones(shape: impl ShapeBuilder<Dim = Ix1>) -> Self
97    where
98        T: One,
99    {
100        Array1::<T>::ones(shape).into()
101    }
102}
103
104impl<T: Display> Display for AlgebraicVector<T> {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        let last_index = self.len() - 1;
107        writeln!(f, "[")?;
108        for (i, el) in self.indexed_iter() {
109            el.fmt(f)?;
110            if i != last_index {
111                writeln!(f, ",")?;
112            }
113        }
114        writeln!(f, "]")
115    }
116}
117
118impl<T: Debug> Debug for AlgebraicVector<T> {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        self.0.fmt(f)
121    }
122}
123
124impl<T> IntoIterator for AlgebraicVector<T> {
125    type Item = <Array1<T> as IntoIterator>::Item;
126    type IntoIter = <Array1<T> as IntoIterator>::IntoIter;
127    fn into_iter(self) -> Self::IntoIter {
128        self.0.into_iter()
129    }
130}
131
132impl<'a, T> IntoIterator for &'a AlgebraicVector<T> {
133    type Item = <&'a Array1<T> as IntoIterator>::Item;
134    type IntoIter = <&'a Array1<T> as IntoIterator>::IntoIter;
135
136    fn into_iter(self) -> Self::IntoIter {
137        self.iter()
138    }
139}
140
141impl<'a, T> IntoIterator for &'a mut AlgebraicVector<T> {
142    type Item = <&'a mut Array1<T> as IntoIterator>::Item;
143    type IntoIter = <&'a mut Array1<T> as IntoIterator>::IntoIter;
144
145    fn into_iter(self) -> Self::IntoIter {
146        self.iter_mut()
147    }
148}
149
150impl<'a, A: 'a> IntoNdProducer for &'a AlgebraicVector<A> {
151    type Item = <Self::Output as NdProducer>::Item;
152    type Dim = Ix1;
153    type Output = ArrayView1<'a, A>;
154    fn into_producer(self) -> Self::Output {
155        <_>::from(&self.0)
156    }
157}
158
159impl AlgebraicVector<DA> {
160    /// Compute the element-wise constant part of an `AlgebraicVector<DA>`.
161    pub fn cons(&self) -> AlgebraicVector<f64> {
162        Zip::from(self).map_collect(DA::cons).into()
163    }
164
165    /// Compute the element-wise sine of an `AlgebraicVector<DA>`.
166    pub fn sin(&self) -> Self {
167        Zip::from(self).map_collect(DA::sin).into()
168    }
169
170    /// Compute the element-wise cosine of an `AlgebraicVector<DA>`.
171    pub fn cos(&self) -> Self {
172        Zip::from(self).map_collect(DA::cos).into()
173    }
174
175    /// Compute the element-wise tangent of an `AlgebraicVector<DA>`.
176    pub fn tan(&self) -> Self {
177        Zip::from(self).map_collect(DA::tan).into()
178    }
179
180    /// Compute the element-wise arcsine of an `AlgebraicVector<DA>`.
181    pub fn asin(&self) -> Self {
182        Zip::from(self).map_collect(DA::asin).into()
183    }
184
185    /// Compute the element-wise arcsine of an `AlgebraicVector<DA>`.
186    #[inline(always)]
187    pub fn arcsin(&self) -> Self {
188        self.sin()
189    }
190
191    /// Compute the element-wise arccosine of an `AlgebraicVector<DA>`.
192    pub fn acos(&self) -> Self {
193        Zip::from(self).map_collect(DA::acos).into()
194    }
195
196    /// Compute the element-wise arccosine of an `AlgebraicVector<DA>`.
197    #[inline(always)]
198    pub fn arccos(&self) -> Self {
199        self.cos()
200    }
201
202    /// Compute the element-wise arctangent of an `AlgebraicVector<DA>`.
203    pub fn atan(&self) -> Self {
204        Zip::from(self).map_collect(DA::atan).into()
205    }
206
207    /// Compute the element-wise arctangent of an `AlgebraicVector<DA>`.
208    #[inline(always)]
209    pub fn arctan(&self) -> Self {
210        self.tan()
211    }
212
213    /// Compute the element-wise four-quadrant arctangent of Y/X of two `AlgebraicVector<DA>`.
214    pub fn atan2(&self, oth: &Self) -> Self {
215        Zip::from(self).and(oth).map_collect(DA::atan2).into()
216    }
217
218    /// Compute the element-wise four-quadrant arctangent of Y/X of two `AlgebraicVector<DA>`.
219    #[inline(always)]
220    pub fn arctan2(&self, oth: &Self) -> Self {
221        self.atan2(oth)
222    }
223
224    /// Get an `AlgebraicVector<DA>` with all monomials of order
225    /// less than `min` and greater than `max` removed (trimmed).
226    ///
227    /// # Arguments
228    ///
229    /// * `min` - minimum order to be preserved
230    /// * `max` - maximum order to be preserved
231    pub fn trim(&self, imin: u32, imax: impl Into<Option<u32>>) -> Self {
232        let imax = imax.into().unwrap_or_else(DA::max_order);
233        Zip::from(self).map_collect(|el| el.trim(imin, imax)).into()
234    }
235
236    /// Compute the derivative of a `AlgebraicVector<T>` with respect to variable `p`.
237    ///
238    /// # Arguments
239    ///
240    /// * `p` variable with respect to which the derivative is calculated
241    pub fn deriv(&self, i: u32) -> Self {
242        Zip::from(self).map_collect(|el| el.deriv(i)).into()
243    }
244
245    /// Compute the integral of a `AlgebraicVector<T>` with respect to variable `p`.
246    ///
247    /// # Arguments
248    ///
249    /// * `p` variable with respect to which the integral is calculated
250    pub fn integ(&self, i: u32) -> Self {
251        Zip::from(self).map_collect(|el| el.integ(i)).into()
252    }
253
254    /// Partial evaluation of vector of polynomials.
255    ///
256    /// In each element of the vector, variable `var` is replaced by the value `val`.
257    ///
258    /// # Arguments
259    ///
260    /// * `var` - variable number to be replaced
261    /// * `val` - value by which to replace the variable
262    pub fn plug(&self, var: u32, val: f64) -> Self {
263        Zip::from(self).map_collect(|el| el.plug(var, val)).into()
264    }
265
266    /// Get the DA identity of dimension `n`.
267    ///
268    /// # Arguments
269    ///
270    /// * `n` - dimension of the identity
271    pub fn identity(n: impl Into<Option<usize>>) -> Self {
272        let n = n.into().unwrap_or_else(|| DA::max_variables() as usize);
273        let mut out = Self::zeros(n);
274        for i in 0..n {
275            unsafe { daceCreateVariable(&mut out[i], i as u32 + 1, 1.0) };
276            check_exception_panic();
277        }
278        out
279    }
280
281    /// Return the linear part of an `AlgebraicVector<DA>`.
282    pub fn linear(&self) -> AlgebraicMatrix<f64> {
283        let nvar = DA::max_variables() as usize;
284        let mut out = AlgebraicMatrix::zeros([self.len(), nvar]);
285        for (i, el) in self.indexed_iter() {
286            out.index_axis_mut(Axis(0), i).assign(&el.linear());
287        }
288        out
289    }
290
291    /// Compute the norm of an `AlgebraicVector<DA>`.
292    ///
293    /// # Panics
294    ///
295    /// Panics if the constant part of any element is <= 0.0.
296    pub fn vnorm(&self) -> DA {
297        let mut out = DA::new();
298        let mut tmp = DA::new();
299        unsafe {
300            for el in self {
301                daceSquare(el, &mut tmp);
302                daceAdd(&out, &tmp, &mut out);
303            }
304            daceSquareRoot(&out, &mut out);
305        }
306        check_exception_panic();
307        out
308    }
309
310    /// Normalize an `AlgebraicVector<DA>`.
311    pub fn normalize(&self) -> AlgebraicVector<DA> {
312        self / self.vnorm()
313    }
314
315    /// Invert the polynomials map given by the `AlgebraicVector<DA>`.
316    ///
317    /// # Panics
318    ///
319    /// Panics if the length of the vector exceeds the maximum number of DA variables.
320    pub fn invert(&self) -> Result<Self, LinalgError> {
321        let ord = DA::truncation_order();
322        let nvar = self.len();
323        let max_vars = DA::max_variables() as usize;
324        if nvar > max_vars {
325            panic!("Vector<DA>::inverse: length of vector exceeds maximum number of DA variables.")
326        }
327
328        // Create DA identity
329        let dda = Self::identity(nvar);
330
331        // Split map into constant part AC,
332        // non-constant part M, and non-linear part AN
333        let ac = self.cons();
334        let m = self.trim(1, None);
335        let an = m.trim(2, None);
336
337        // Extract the linear coefficients matrix
338        let al = m.linear();
339
340        // Compute the inverse of linear coefficients matrix
341        let ai = al.inv()?;
342
343        // Compute DA representation of the inverse of the linear part
344        // of the map and its composition with non-linear part AN
345        let aioan = ai.dot(&an).compile();
346        let linv = ai.dot(&dda);
347
348        // Iterate to obtain the inverse map
349        let mut mi = linv.clone();
350        for i in 1..ord {
351            DA::set_truncation_order(i + 1);
352            mi = &linv - aioan.eval(&mi);
353        }
354
355        Ok(mi.eval(&(dda - ac)))
356    }
357}
358
359impl Compile for AlgebraicVector<DA> {
360    /// Compile current `AlgebraicVector<DA>` object and create a compiledDA object.
361    fn compile(&self) -> da::CompiledDA {
362        let dim = self.len();
363        let mut ac = vec![0.0; (dim + 2) * unsafe { daceGetMaxMonomials() } as usize];
364        let mut terms = 0;
365        let mut _vars = 0;
366        let mut ord = 0;
367        let collection = self.iter().collect::<Vec<&DA>>();
368
369        unsafe {
370            daceEvalTree(
371                collection.as_ptr(),
372                dim as u32,
373                ac.as_mut_ptr(),
374                &mut terms,
375                &mut _vars,
376                &mut ord,
377            );
378        }
379        check_exception_panic();
380        da::CompiledDA {
381            dim,
382            ac,
383            terms,
384            _vars,
385            ord,
386        }
387    }
388}
389
390/// Cross product of two objects.
391pub trait Cross<'a, Rhs> {
392    /// The resulting type after applying the cross operation.
393    type Output;
394    /// Compute the cross product.
395    fn cross(&'a self, oth: &'a Rhs) -> Self::Output;
396}
397
398impl<'a, T, U> Cross<'a, AlgebraicVector<T>> for AlgebraicVector<U>
399where
400    T: 'a,
401    U: 'a,
402    &'a U: ops::Mul<&'a T>,
403    <&'a U as ops::Mul<&'a T>>::Output: ops::Sub<<&'a U as ops::Mul<&'a T>>::Output>,
404{
405    type Output = AlgebraicVector<<<&'a U as ops::Mul<&'a T>>::Output as ops::Sub<<&'a U as ops::Mul<&'a T>>::Output>>::Output>;
406    /// Computes the cross product with an `AlgebraicVector<T>`.
407    ///
408    /// # Arguments
409    ///
410    /// * `rhs` - operand (`AlgebraicVector<T>`)
411    ///
412    /// # Panics
413    ///
414    /// Panics if the lengths of the vectors are not equal to 3.
415    fn cross(&'a self, other: &'a AlgebraicVector<T>) -> Self::Output {
416        if self.len() != 3 || other.len() != 3 {
417            panic!("DACE::AlgebraicVector<T>::cross(): Inputs must be 3 element AlgebraicVectors.");
418        }
419        darray![
420            &self[1] * &other[2] - &self[2] * &other[1],
421            &self[2] * &other[0] - &self[0] * &other[2],
422            &self[0] * &other[1] - &self[1] * &other[0],
423        ]
424    }
425}
426
427impl AlgebraicVector<f64> {
428    /// Compute the norm of an `AlgebraicVector<f64>`.
429    pub fn vnorm(&self) -> f64 {
430        self.norm_l2()
431    }
432}
433
434impl Dot<AlgebraicVector<DA>> for AlgebraicVector<DA> {
435    type Output = DA;
436    /// Compute the scalar product of this `AlgebraicVector<DA>`
437    /// with an `AlgebraicVector<DA>`.
438    ///
439    /// # Arguments
440    ///
441    /// * `rhs` - operand (`AlgebraicVector<DA>`)
442    ///
443    /// # Panics
444    ///
445    /// Panics if the vectors have different lengths.
446    fn dot(&self, rhs: &AlgebraicVector<DA>) -> Self::Output {
447        if self.len() != rhs.len() {
448            panic!("The elements must have the same length.");
449        }
450        let mut out = DA::new();
451        let mut tmp: DA = DA::new();
452        for (x, y) in zip(self, rhs) {
453            unsafe { daceMultiply(x, y, &mut tmp) };
454            check_exception_panic();
455            out += &tmp;
456        }
457        out
458    }
459}
460
461impl Dot<AlgebraicVector<f64>> for AlgebraicVector<DA> {
462    type Output = DA;
463    /// Compute the scalar product of this `AlgebraicVector<DA>`
464    /// with an `AlgebraicVector<f64>`.
465    ///
466    /// # Arguments
467    ///
468    /// * `rhs` - operand (`AlgebraicVector<f64>`)
469    ///
470    /// # Panics
471    ///
472    /// Panics if the vectors have different lengths.
473    fn dot(&self, rhs: &AlgebraicVector<f64>) -> Self::Output {
474        if self.len() != rhs.len() {
475            panic!("The elements must have the same length.");
476        }
477        let mut out = DA::new();
478        let mut tmp: DA = DA::new();
479        for (x, y) in zip(self, rhs) {
480            unsafe { daceMultiplyDouble(x, *y, &mut tmp) };
481            check_exception_panic();
482            out += &tmp;
483        }
484        out
485    }
486}
487
488impl Dot<AlgebraicVector<DA>> for AlgebraicVector<f64> {
489    type Output = DA;
490    /// Compute the scalar product of this `AlgebraicVector<f64>`
491    /// with an `AlgebraicVector<DA>`.
492    ///
493    /// # Arguments
494    ///
495    /// * `rhs` - operand (`AlgebraicVector<DA>`)
496    ///
497    /// # Panics
498    ///
499    /// Panics if the vectors have different lengths.
500    fn dot(&self, rhs: &AlgebraicVector<DA>) -> Self::Output {
501        if self.len() != rhs.len() {
502            panic!("The elements must have the same length.");
503        }
504        let mut out = DA::new();
505        let mut tmp: DA = DA::new();
506        for (x, y) in zip(self, rhs) {
507            unsafe { daceMultiplyDouble(y, *x, &mut tmp) };
508            check_exception_panic();
509            out += &tmp;
510        }
511        out
512    }
513}
514
515impl Dot<AlgebraicVector<f64>> for AlgebraicVector<f64> {
516    type Output = f64;
517    /// Compute the scalar product of this `AlgebraicVector<f64>`
518    /// with an `AlgebraicVector<f64>`.
519    ///
520    /// # Arguments
521    ///
522    /// * `rhs` - operand (`AlgebraicVector<f64>`)
523    ///
524    /// # Panics
525    ///
526    /// Panics if the vectors have different lengths.
527    fn dot(&self, rhs: &AlgebraicVector<f64>) -> Self::Output {
528        if self.len() != rhs.len() {
529            panic!("The elements must have the same length.");
530        }
531        self.0.dot(&rhs.0)
532    }
533}
534
535impl From<&AlgebraicVector<f64>> for AlgebraicVector<DA> {
536    fn from(d: &AlgebraicVector<f64>) -> Self {
537        d.map(|x| da!(*x)).into()
538    }
539}
540
541impl From<AlgebraicVector<f64>> for AlgebraicVector<DA> {
542    fn from(d: AlgebraicVector<f64>) -> Self {
543        (&d).into()
544    }
545}
546
547impl From<&AlgebraicVector<u32>> for AlgebraicVector<DA> {
548    fn from(d: &AlgebraicVector<u32>) -> Self {
549        d.map(|x| da!(*x)).into()
550    }
551}
552
553impl From<AlgebraicVector<u32>> for AlgebraicVector<DA> {
554    fn from(d: AlgebraicVector<u32>) -> Self {
555        (&d).into()
556    }
557}
558
559impl<'a, T: Clone> From<ArrayView1<'a, T>> for AlgebraicVector<T> {
560    fn from(v: ArrayView1<'a, T>) -> Self {
561        AlgebraicVector(v.to_owned())
562    }
563}
564
565// Add vector
566
567impl_op_ex!(+ |a: &AlgebraicVector<DA>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
568    (&a.0 + &b.0).into()
569});
570
571impl_op_ex!(+= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<DA>| {
572    a.0 += &b.0;
573});
574
575impl_op_ex_commutative!(+ |a: &AlgebraicVector<DA>, b: &AlgebraicVector<f64>| -> AlgebraicVector<DA> {
576    (&a.0 + &b.0).into()
577});
578
579impl_op_ex!(+= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<f64>| {
580    a.0 = &a.0 + &b.0;
581});
582
583impl_op_ex!(+ |a: &AlgebraicVector<f64>, b: &AlgebraicVector<f64>| -> AlgebraicVector<f64> {
584    (&a.0 + &b.0).into()
585});
586
587impl_op_ex!(+= |a: &mut AlgebraicVector<f64>, b: &AlgebraicVector<f64>| {
588    a.0 += &b.0;
589});
590
591// Add scalar
592
593impl_op_ex_commutative!(+ |a: &AlgebraicVector<DA>, b: &DA| -> AlgebraicVector<DA> {
594    (&a.0 + b.to_owned()).into()
595});
596
597impl_op_ex!(+= |a: &mut AlgebraicVector<DA>, b: &DA| {
598    for lhs in &mut a.0 {
599        *lhs += b;
600    }
601});
602
603impl_op_ex_commutative!(+ |a: &AlgebraicVector<DA>, b: &f64| -> AlgebraicVector<DA> {
604    (&a.0 + *b).into()
605});
606
607impl_op_ex!(+= |a: &mut AlgebraicVector<DA>, b: &f64| {
608    for lhs in &mut a.0 {
609        *lhs += b;
610    }
611});
612
613impl_op_ex_commutative!(+ |a: &AlgebraicVector<f64>, b: &DA| -> AlgebraicVector<DA> {
614    AlgebraicVector::<DA>::from(a) + b
615});
616
617impl_op_ex_commutative!(+ |a: &AlgebraicVector<f64>, b: &f64| -> AlgebraicVector<f64> {
618    (&a.0 + *b).into()
619});
620
621impl_op_ex!(+= |a: &mut AlgebraicVector<f64>, b: &f64| {
622    a.0 += *b
623});
624
625// Sub vector
626
627impl_op_ex!(
628    -|a: &AlgebraicVector<DA>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
629        (&a.0 - &b.0).into()
630    }
631);
632
633impl_op_ex!(-= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<DA>| {
634    a.0 -= &b.0;
635});
636
637impl_op_ex!(
638    -|a: &AlgebraicVector<DA>, b: &AlgebraicVector<f64>| -> AlgebraicVector<DA> {
639        (&a.0 - &b.0).into()
640    }
641);
642
643impl_op_ex!(
644    -|a: &AlgebraicVector<f64>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
645        (&a.0 - b.0.to_owned()).into()
646    }
647);
648
649impl_op_ex!(
650    -|a: &AlgebraicVector<f64>, b: &AlgebraicVector<f64>| -> AlgebraicVector<f64> {
651        (&a.0 - &b.0).into()
652    }
653);
654
655impl_op_ex!(-= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<f64>| {
656    for (lhs, rhs) in zip(&mut a.0, &b.0) {
657        *lhs -= *rhs;
658    }
659});
660
661// Sub scalar
662
663impl_op_ex!(-|a: &AlgebraicVector<DA>, b: &DA| -> AlgebraicVector<DA> {
664    (&a.0 - b.to_owned()).into()
665});
666
667impl_op_ex!(-|a: &DA, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
668    (-(&b.0 - a.to_owned())).into()
669});
670
671impl_op_ex!(-= |a: &mut AlgebraicVector<DA>, b: &DA| {
672    for lhs in &mut a.0 {
673        *lhs -= b;
674    }
675});
676
677impl_op_ex!(-|a: &AlgebraicVector<DA>, b: &f64| -> AlgebraicVector<DA> { (&a.0 - *b).into() });
678
679impl_op_ex!(-|a: &f64, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> { (-(&b.0 - *a)).into() });
680
681impl_op_ex!(-= |a: &mut AlgebraicVector<DA>, b: &f64| {
682    for lhs in &mut a.0 {
683        *lhs -= b;
684    }
685});
686
687impl_op_ex!(-|a: &AlgebraicVector<f64>, b: &DA| -> AlgebraicVector<DA> {
688    AlgebraicVector::<DA>::from(a) - b
689});
690
691impl_op_ex!(-|a: &DA, b: &AlgebraicVector<f64>| -> AlgebraicVector<DA> {
692    a - AlgebraicVector::<DA>::from(b)
693});
694
695impl_op_ex!(-|a: &AlgebraicVector<f64>, b: &f64| -> AlgebraicVector<f64> { (&a.0 - *b).into() });
696
697impl_op_ex!(-|a: &f64, b: &AlgebraicVector<f64>| -> AlgebraicVector<f64> { (-(&b.0 - *a)).into() });
698
699impl_op_ex!(-= |a: &mut AlgebraicVector<f64>, b: &f64| {
700    a.0 -= *b;
701});
702
703// Mul vector
704
705impl_op_ex!(
706    *|a: &AlgebraicVector<DA>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
707        (&a.0 * &b.0).into()
708    }
709);
710
711impl_op_ex!(*= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<DA>| {
712    a.0 *= &b.0;
713});
714
715impl_op_ex_commutative!(*|a: &AlgebraicVector<DA>,
716                          b: &AlgebraicVector<f64>|
717 -> AlgebraicVector<DA> { (&a.0 * &b.0).into() });
718
719impl_op_ex!(*= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<f64>| {
720    for (lhs, rhs) in zip(&mut a.0, &b.0) {
721        *lhs *= *rhs;
722    }
723});
724
725// Mul scalar
726
727impl_op_ex_commutative!(*|a: &AlgebraicVector<DA>, b: &DA| -> AlgebraicVector<DA> {
728    (&a.0 * b.to_owned()).into()
729});
730
731impl_op_ex!(*= |a: &mut AlgebraicVector<DA>, b: &DA| {
732    for lhs in &mut a.0 {
733        *lhs *= b;
734    }
735});
736
737impl_op_ex_commutative!(*|a: &AlgebraicVector<DA>, b: &f64| -> AlgebraicVector<DA> {
738    (&a.0 * *b).into()
739});
740
741impl_op_ex!(*= |a: &mut AlgebraicVector<DA>, b: &f64| {
742    for lhs in &mut a.0 {
743        *lhs *= *b;
744    }
745});
746
747impl_op_ex_commutative!(*|a: &AlgebraicVector<f64>, b: &DA| -> AlgebraicVector<DA> {
748    AlgebraicVector::<DA>::from(a) * b
749});
750
751impl_op_ex_commutative!(
752    *|a: &AlgebraicVector<f64>, b: &f64| -> AlgebraicVector<f64> { (&a.0 * *b).into() }
753);
754
755impl_op_ex!(*= |a: &mut AlgebraicVector<f64>, b: &f64| {
756    a.0 *= *b;
757});
758
759// Div vector
760
761impl_op_ex!(
762    /|a: &AlgebraicVector<DA>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
763        (&a.0 / &b.0).into()
764    }
765);
766
767impl_op_ex!(/= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<DA>| {
768    a.0 /= &b.0;
769});
770
771impl_op_ex!(
772    /|a: &AlgebraicVector<DA>, b: &AlgebraicVector<f64>| -> AlgebraicVector<DA> {
773        (&a.0 / &b.0).into()
774    }
775);
776
777impl_op_ex!(
778    /|a: &AlgebraicVector<f64>, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
779        (&a.0 / b.0.to_owned()).into()
780    }
781);
782
783impl_op_ex!(/= |a: &mut AlgebraicVector<DA>, b: &AlgebraicVector<f64>| {
784    for (lhs, rhs) in zip(&mut a.0, &b.0) {
785        *lhs /= *rhs;
786    }
787});
788
789// Div scalar
790
791impl_op_ex!(/|a: &AlgebraicVector<DA>, b: &DA| -> AlgebraicVector<DA> {
792    (&a.0 / b.to_owned()).into()
793});
794
795impl_op_ex!(/|a: &DA, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
796    (Array1::<DA>::ones(b.len()) * a.to_owned() / &b.0).into()
797});
798
799impl_op_ex!(/= |a: &mut AlgebraicVector<DA>, b: &DA| {
800    for lhs in &mut a.0 {
801        *lhs /= b;
802    }
803});
804
805impl_op_ex!(/|a: &AlgebraicVector<DA>, b: &f64| -> AlgebraicVector<DA> { (&a.0 / *b).into() });
806
807impl_op_ex!(/|a: &f64, b: &AlgebraicVector<DA>| -> AlgebraicVector<DA> {
808    (Array1::<DA>::ones(b.len()) * *a / &b.0).into()
809});
810
811impl_op_ex!(/= |a: &mut AlgebraicVector<DA>, b: &f64| {
812    for lhs in &mut a.0 {
813        *lhs /= *b;
814    }
815});
816
817impl_op_ex!(/|a: &AlgebraicVector<f64>, b: &DA| -> AlgebraicVector<DA> {
818    AlgebraicVector::<DA>::from(a) / b
819});
820
821impl_op_ex!(/|a: &DA, b: &AlgebraicVector<f64>| -> AlgebraicVector<DA> {
822    a / AlgebraicVector::<DA>::from(b)
823});
824
825impl_op_ex!(/|a: &AlgebraicVector<f64>, b: &f64| -> AlgebraicVector<f64> { (&a.0 / *b).into() });
826
827impl_op_ex!(/|a: &f64, b: &AlgebraicVector<f64>| -> AlgebraicVector<f64> {
828    (*a / &b.0).into()
829});
830
831impl_op_ex!(/= |a: &mut AlgebraicVector<f64>, b: &f64| {
832    a.0 /= *b;
833});
834
835// Neg
836
837impl<T> ops::Neg for AlgebraicVector<T>
838where
839    AlgebraicVector<T>: ops::MulAssign<f64>,
840{
841    type Output = AlgebraicVector<T>;
842    fn neg(mut self) -> Self::Output {
843        self *= -1.0;
844        self
845    }
846}
847
848impl<T> ops::Neg for &AlgebraicVector<T>
849where
850    T: Clone + ops::Mul<f64, Output = T>,
851{
852    type Output = AlgebraicVector<T>;
853    fn neg(self) -> Self::Output {
854        (&self.0 * -1.0).into()
855    }
856}