1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
// use super::*;
// // Holy Decree:
// // Tragically, Rust will have a cycle of dependencies with the product rule
// // unless we evaluate the coefficients before multiplying:
// // L's Grad implementation requires it to be multiplicable by R's, & vice versa
// // So, unfortunately, evaluate we must
// //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// // Never mind, this happens all the time, even if we evaluate.
// // I think this is why we need Expr<...> around everything.
// // // Holy Fucking Christ
// //
// // impl<
// // L: ~const Eval<
// // Evaluated: ~const core::ops::Mul<R::Evaluated>
// // + ~const core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<R::Differentiated>,
// // R: ~const Eval<
// // Evaluated: ~const core::ops::Mul<L::Evaluated>
// // + ~const core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<L::Differentiated>,
// // > const grad::Typed for Mul<L, R>
// // where
// // <L::Evaluated as core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>>::Output:
// // ~const core::ops::Add<
// // <R::Evaluated as core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>>::Output,
// // >,
// // <L as core::ops::Mul<R::Differentiated>>::Output:
// // ~const core::ops::Add<<R as core::ops::Mul<L::Differentiated>>::Output>,
// // <<L as core::ops::Mul<R::Differentiated>>::Output as core::ops::Add<
// // <R as core::ops::Mul<L::Differentiated>>::Output,
// // >>::Output: ~const eval::Eval,
// // {
// // // my sincerest apologies
// // type Differentiated = <<L as core::ops::Mul<R::Differentiated>>::Output as core::ops::Add<
// // <R as core::ops::Mul<L::Differentiated>>::Output,
// // >>::Output;
// // }
// // impl<
// // L: ~const Eval<
// // Evaluated: ~const core::ops::Mul<R::Evaluated>
// // + ~const core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<R::Differentiated>,
// // R: ~const Eval<
// // Evaluated: ~const core::ops::Mul<L::Evaluated>
// // + ~const core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<L::Differentiated>,
// // > const grad::Own for Mul<L, R>
// // where
// // <L::Evaluated as core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>>::Output:
// // ~const core::ops::Add<
// // <R::Evaluated as core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>>::Output,
// // >,
// // <L as core::ops::Mul<R::Differentiated>>::Output:
// // ~const core::ops::Add<<R as core::ops::Mul<L::Differentiated>>::Output>,
// // <<L as core::ops::Mul<R::Differentiated>>::Output as core::ops::Add<
// // <R as core::ops::Mul<L::Differentiated>>::Output,
// // >>::Output: ~const eval::Eval,
// // {
// // fn grad<U>(self, x: &U) -> Self::Differentiated {
// // let g0 = (&self.0).grad(x);
// // let g1 = (&self.1).grad(x);
// // (self.0 * g1) + (self.1 * g0)
// // }
// // }
// // impl<
// // L: ~const Eval<
// // Evaluated: ~const core::ops::Mul<R::Evaluated>
// // + ~const core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<R::Differentiated>,
// // R: ~const Eval<
// // Evaluated: ~const core::ops::Mul<L::Evaluated>
// // + ~const core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>,
// // > + ~const Grad
// // + ~const core::ops::Mul<L::Differentiated>,
// // > const grad::Ref for Mul<L, R>
// // where
// // <L::Evaluated as core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>>::Output:
// // ~const core::ops::Add<
// // <R::Evaluated as core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>>::Output,
// // >,
// // <L as core::ops::Mul<R::Differentiated>>::Output:
// // ~const core::ops::Add<<R as core::ops::Mul<L::Differentiated>>::Output>,
// // <<L as core::ops::Mul<R::Differentiated>>::Output as core::ops::Add<
// // <R as core::ops::Mul<L::Differentiated>>::Output,
// // >>::Output: ~const eval::Eval,
// // for<'a> &'a L: ~const core::ops::Mul<R::Differentiated>,
// // for<'a> &'a R: ~const core::ops::Mul<L::Differentiated>,
// // for<'a> <&'a L as core::ops::Mul<R::Differentiated>>::Output:
// // ~const core::ops::Add<<&'a R as core::ops::Mul<L::Differentiated>>::Output>,
// // {
// // fn grad<U>(&self, x: &U) -> Self::Differentiated {
// // let g0 = (&self.0).grad(x);
// // let g1 = (&self.1).grad(x);
// // ((&self.0) * g1) + ((&self.1) * g0)
// // }
// // }
// impl<
// L: ~const Grad<
// Evaluated: ~const Eval<
// Evaluated: ~const core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>,
// > + ~const core::ops::Mul<R::Evaluated>,
// >,
// R: ~const Grad<Evaluated: ~const Eval>,
// > const grad::Typed for Mul<L, R>
// {
// type Differentiated = ();
// }
// impl<
// L: ~const Grad<
// Evaluated: ~const Eval<
// Evaluated: ~const core::ops::Mul<<R::Differentiated as eval::Typed>::Evaluated>,
// > + ~const core::ops::Mul<R::Evaluated>,
// >,
// R: ~const Grad<
// Evaluated: ~const Eval<
// Evaluated: ~const core::ops::Mul<<L::Differentiated as eval::Typed>::Evaluated>,
// >,
// >,
// > const grad::Own for Mul<L, R>
// {
// fn grad<U>(self, x: &U) -> <Self as grad::Typed>::Differentiated {
// let g0 = (&self.0).grad(x);
// let g1 = (&self.1).grad(x);
// Add(Mul(self.0.eval(), g1), Mul(self.1.eval(), g0))
// }
// }