1use std::ops::{Mul, MulAssign};
2
3use crate::{Tape, Variable, operation_record::OperationRecord};
4
5impl<'a, F: Mul<F, Output = F> + Copy> Mul<Self> for &Variable<'a, F> {
6 type Output = Variable<'a, F>;
7
8 #[inline]
9 fn mul(self, rhs: Self) -> Self::Output {
10 #[inline]
11 fn create_index<F: Mul<F, Output = F> + Copy>(
12 value: F,
13 rhs: F,
14 idx: [usize; 2],
15 tape: &Tape<F>,
16 ) -> usize {
17 let operations = &mut tape.operations.borrow_mut();
18 let count = (*operations).len();
19 (*operations).push(OperationRecord([(idx[0], rhs), (idx[1], value)]));
20 count
21 }
22
23 let value = self.value * rhs.value;
24
25 match (self.index, rhs.index) {
26 (Some((i, tape)), Some((j, _))) => Variable {
27 index: Some((create_index(self.value, rhs.value, [i, j], tape), tape)),
28 value,
29 },
30 (None, None) => Variable { index: None, value },
31 (None, Some((j, tape))) => Variable {
32 index: Some((
33 create_index(self.value, rhs.value, [usize::MAX, j], tape),
34 tape,
35 )),
36 value,
37 },
38 (Some((i, tape)), None) => Variable {
39 index: Some((
40 create_index(self.value, rhs.value, [i, usize::MAX], tape),
41 tape,
42 )),
43 value,
44 },
45 }
46 }
47}
48
49impl<'a, F> Mul<Variable<'a, F>> for &Variable<'a, F>
50where
51 for<'b> &'b Variable<'a, F>: Mul<&'b Variable<'a, F>, Output = Variable<'a, F>>,
52{
53 type Output = Variable<'a, F>;
54 #[inline]
55 fn mul(self, rhs: Variable<'a, F>) -> Self::Output {
56 self.mul(&rhs)
57 }
58}
59
60impl<'a, F> Mul<Self> for Variable<'a, F>
61where
62 for<'b> &'b Variable<'a, F>: Mul<&'b Variable<'a, F>, Output = Variable<'a, F>>,
63{
64 type Output = Variable<'a, F>;
65 #[inline]
66 fn mul(self, rhs: Self) -> Self::Output {
67 (&self).mul(&rhs)
68 }
69}
70
71impl<'a, F> Mul<&Self> for Variable<'a, F>
72where
73 for<'b> &'b Variable<'a, F>: Mul<&'b Variable<'a, F>, Output = Variable<'a, F>>,
74{
75 type Output = Variable<'a, F>;
76
77 #[inline]
78 fn mul(self, rhs: &Variable<'a, F>) -> Self::Output {
79 (&self).mul(rhs)
80 }
81}
82
83impl<'a, F> MulAssign<Self> for Variable<'a, F>
84where
85 for<'b> &'b Variable<'a, F>: Mul<&'b Variable<'a, F>, Output = Variable<'a, F>>,
86{
87 #[inline]
88 fn mul_assign(&mut self, rhs: Self) {
89 *self = &*self * &rhs;
90 }
91}
92
93impl<'a, F> MulAssign<&Self> for Variable<'a, F>
94where
95 for<'b> &'b Variable<'a, F>: Mul<&'b Variable<'a, F>, Output = Variable<'a, F>>,
96{
97 #[inline]
98 fn mul_assign(&mut self, rhs: &Self) {
99 *self = &*self * rhs;
100 }
101}