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
19pub struct AlgebraicVector<T>(
22 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 pub fn cons(&self) -> AlgebraicVector<f64> {
162 Zip::from(self).map_collect(DA::cons).into()
163 }
164
165 pub fn sin(&self) -> Self {
167 Zip::from(self).map_collect(DA::sin).into()
168 }
169
170 pub fn cos(&self) -> Self {
172 Zip::from(self).map_collect(DA::cos).into()
173 }
174
175 pub fn tan(&self) -> Self {
177 Zip::from(self).map_collect(DA::tan).into()
178 }
179
180 pub fn asin(&self) -> Self {
182 Zip::from(self).map_collect(DA::asin).into()
183 }
184
185 #[inline(always)]
187 pub fn arcsin(&self) -> Self {
188 self.sin()
189 }
190
191 pub fn acos(&self) -> Self {
193 Zip::from(self).map_collect(DA::acos).into()
194 }
195
196 #[inline(always)]
198 pub fn arccos(&self) -> Self {
199 self.cos()
200 }
201
202 pub fn atan(&self) -> Self {
204 Zip::from(self).map_collect(DA::atan).into()
205 }
206
207 #[inline(always)]
209 pub fn arctan(&self) -> Self {
210 self.tan()
211 }
212
213 pub fn atan2(&self, oth: &Self) -> Self {
215 Zip::from(self).and(oth).map_collect(DA::atan2).into()
216 }
217
218 #[inline(always)]
220 pub fn arctan2(&self, oth: &Self) -> Self {
221 self.atan2(oth)
222 }
223
224 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 pub fn deriv(&self, i: u32) -> Self {
242 Zip::from(self).map_collect(|el| el.deriv(i)).into()
243 }
244
245 pub fn integ(&self, i: u32) -> Self {
251 Zip::from(self).map_collect(|el| el.integ(i)).into()
252 }
253
254 pub fn plug(&self, var: u32, val: f64) -> Self {
263 Zip::from(self).map_collect(|el| el.plug(var, val)).into()
264 }
265
266 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 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 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 pub fn normalize(&self) -> AlgebraicVector<DA> {
312 self / self.vnorm()
313 }
314
315 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 let dda = Self::identity(nvar);
330
331 let ac = self.cons();
334 let m = self.trim(1, None);
335 let an = m.trim(2, None);
336
337 let al = m.linear();
339
340 let ai = al.inv()?;
342
343 let aioan = ai.dot(&an).compile();
346 let linv = ai.dot(&dda);
347
348 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 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
390pub trait Cross<'a, Rhs> {
392 type Output;
394 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 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 pub fn vnorm(&self) -> f64 {
430 self.norm_l2()
431 }
432}
433
434impl Dot<AlgebraicVector<DA>> for AlgebraicVector<DA> {
435 type Output = DA;
436 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 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 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 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
565impl_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
591impl_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
625impl_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
661impl_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
703impl_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
725impl_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
759impl_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
789impl_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
835impl<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}