Tue, 31 Dec 2024 09:12:43 -0500
Try to have Field as member type in Mappings etc.
| 5 | 1 | |
| 2 | use std::iter::Chain; | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
3 | use std::sync::Arc; |
| 0 | 4 | |
| 5 | use crate::types::*; | |
|
29
7fd0984743b5
Rename Differentiate → Differentiable
Tuomo Valkonen <tuomov@iki.fi>
parents:
27
diff
changeset
|
6 | use crate::mapping::{Apply, Differentiable}; |
|
27
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
7 | use crate::iter::{Mappable, MapF, MapZ}; |
| 5 | 8 | use crate::sets::Cube; |
| 9 | use crate::loc::Loc; | |
| 10 | ||
| 0 | 11 | use super::support::*; |
| 12 | use super::aggregator::*; | |
| 13 | ||
| 5 | 14 | /// A structure for storing two [`SupportGenerator`]s summed/chain together. |
| 15 | /// | |
| 16 | /// This is needed to work with sums of different types of [`Support`]s. | |
| 0 | 17 | #[derive(Debug,Clone)] |
| 18 | pub struct BothGenerators<A, B>( | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
19 | pub(super) Arc<A>, |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
20 | pub(super) Arc<B>, |
| 0 | 21 | ); |
| 22 | ||
| 5 | 23 | /// A structure for a [`Support`] that can be either `A` or `B`. |
| 24 | /// | |
| 25 | /// This is needed to work with sums of different types of [`Support`]s. | |
| 0 | 26 | #[derive(Debug,Clone)] |
| 27 | pub enum EitherSupport<A, B> { | |
| 28 | Left(A), | |
| 29 | Right(B), | |
| 30 | } | |
| 31 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
32 | impl<A, B, F : Num> HasScalarField for EitherSupport<A, B> |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
33 | where A : HasScalarField<Field = F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
34 | B : HasScalarField<Field = F> { |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
35 | type Field = F; |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
36 | } |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
37 | |
| 0 | 38 | // We need type alias bounds to access associate types. |
| 39 | #[allow(type_alias_bounds)] | |
| 40 | type BothAllDataIter< | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
41 | 'a, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
42 | G1 : SupportGenerator<N>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
43 | G2 : SupportGenerator<N, RealField = G1::RealField>, |
| 0 | 44 | const N : usize |
| 45 | > = Chain< | |
| 46 | MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, | |
| 47 | MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, | |
| 48 | >; | |
| 49 | ||
| 50 | impl<G1, G2> BothGenerators<G1, G2> { | |
| 5 | 51 | /// Helper for [`all_left_data`]. |
| 0 | 52 | #[inline] |
| 53 | fn map_left<F : Float, const N : usize>((d, support) : (G1::Id, G1::SupportType)) | |
| 54 | -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
55 | where G1 : SupportGenerator<N, Id=usize, RealField =F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
56 | G2 : SupportGenerator<N, Id=usize, RealField = F> { |
| 0 | 57 | |
| 58 | let id : usize = d.into(); | |
| 59 | (id.into(), EitherSupport::Left(support)) | |
| 60 | } | |
| 61 | ||
| 5 | 62 | /// Helper for [`all_right_data`]. |
| 0 | 63 | #[inline] |
| 64 | fn map_right<F : Float, const N : usize>(n0 : &usize, (d, support) : (G2::Id, G2::SupportType)) | |
| 65 | -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
66 | where G1 : SupportGenerator<N, Id=usize, RealField = F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
67 | G2 : SupportGenerator<N, Id=usize, RealField = F> { |
| 0 | 68 | |
| 69 | let id : usize = d.into(); | |
| 70 | ((n0+id).into(), EitherSupport::Right(support)) | |
| 71 | } | |
| 72 | ||
| 5 | 73 | /// Calls [`SupportGenerator::all_data`] on the “left” support generator. |
| 74 | /// | |
| 75 | /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. | |
| 0 | 76 | #[inline] |
| 77 | pub(super) fn all_left_data<F : Float, const N : usize>(&self) | |
| 78 | -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
79 | where G1 : SupportGenerator<N, Id=usize, RealField = F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
80 | G2 : SupportGenerator<N, Id=usize, RealField = F> { |
| 0 | 81 | self.0.all_data().mapF(Self::map_left) |
| 82 | } | |
| 83 | ||
| 5 | 84 | /// Calls [`SupportGenerator::all_data`] on the “right” support generator. |
| 85 | /// | |
| 86 | /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. | |
| 0 | 87 | #[inline] |
| 88 | pub(super) fn all_right_data<F : Float, const N : usize>(&self) | |
| 89 | -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
90 | where G1 : SupportGenerator<N, Id=usize, RealField=F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
91 | G2 : SupportGenerator<N, Id=usize, RealField=F> { |
| 0 | 92 | let n0 = self.0.support_count(); |
| 93 | self.1.all_data().mapZ(n0, Self::map_right) | |
| 94 | } | |
| 95 | } | |
| 96 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
97 | impl<F : Float, G1, G2> HasScalarField for BothGenerators<G1, G2> |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
98 | where G1 : HasScalarField<Field=F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
99 | G2 : HasScalarField<Field=F> { |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
100 | type Field = F; |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
101 | } |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
102 | |
| 0 | 103 | impl<F : Float, G1, G2, const N : usize> |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
104 | SupportGenerator<N> |
| 0 | 105 | for BothGenerators<G1, G2> |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
106 | where G1 : SupportGenerator<N, Id=usize> + HasRealField<RealField=F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
107 | G2 : SupportGenerator<N, Id=usize> + HasRealField<RealField=F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
108 | Self : HasRealField<RealField = F> { |
| 0 | 109 | |
| 110 | type Id = usize; | |
| 111 | type SupportType = EitherSupport<G1::SupportType, G2::SupportType>; | |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
112 | type AllDataIter<'a> = BothAllDataIter<'a, G1, G2, N> where G1 : 'a, G2 : 'a; |
| 0 | 113 | |
| 114 | #[inline] | |
| 115 | fn support_for(&self, id : Self::Id) | |
| 116 | -> Self::SupportType { | |
| 117 | let n0 = self.0.support_count(); | |
| 118 | if id < n0 { | |
| 119 | EitherSupport::Left(self.0.support_for(id.into())) | |
| 120 | } else { | |
| 121 | EitherSupport::Right(self.1.support_for((id-n0).into())) | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 125 | #[inline] | |
| 126 | fn support_count(&self) -> usize { | |
| 127 | self.0.support_count() + self.1.support_count() | |
| 128 | } | |
| 129 | ||
| 130 | #[inline] | |
| 131 | fn all_data(&self) -> Self::AllDataIter<'_> { | |
| 132 | self.all_left_data().chain(self.all_right_data()) | |
| 133 | } | |
| 134 | } | |
| 135 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
136 | impl<F: Float, S1, S2, const N : usize> Support<N> for EitherSupport<S1, S2> |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
137 | where S1 : Support<N, RealField = F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
138 | S2 : Support<N, RealField = F> { |
| 0 | 139 | |
| 140 | #[inline] | |
| 141 | fn support_hint(&self) -> Cube<F,N> { | |
| 142 | match self { | |
| 143 | EitherSupport::Left(ref a) => a.support_hint(), | |
| 144 | EitherSupport::Right(ref b) => b.support_hint(), | |
| 145 | } | |
| 146 | } | |
| 147 | ||
| 148 | #[inline] | |
| 149 | fn in_support(&self, x : &Loc<F,N>) -> bool { | |
| 150 | match self { | |
| 151 | EitherSupport::Left(ref a) => a.in_support(x), | |
| 152 | EitherSupport::Right(ref b) => b.in_support(x), | |
| 153 | } | |
| 154 | } | |
| 155 | ||
| 156 | #[inline] | |
| 157 | fn bisection_hint(&self, cube : &Cube<F, N>) -> [Option<F>; N] { | |
| 158 | match self { | |
| 159 | EitherSupport::Left(ref a) => a.bisection_hint(cube), | |
| 160 | EitherSupport::Right(ref b) => b.bisection_hint(cube), | |
| 161 | } | |
| 162 | } | |
| 163 | } | |
| 164 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
165 | impl<F : Float, A, S1, S2, const N : usize> LocalAnalysis<A, Cube<F, N>> |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
166 | for EitherSupport<S1, S2> |
| 0 | 167 | where A : Aggregator, |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
168 | S1 : LocalAnalysis<A, Cube<F, N>>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
169 | S2 : LocalAnalysis<A, Cube<F, N>> { |
| 0 | 170 | |
| 171 | #[inline] | |
| 172 | fn local_analysis(&self, cube : &Cube<F, N>) -> A { | |
| 173 | match self { | |
| 174 | EitherSupport::Left(ref a) => a.local_analysis(cube), | |
| 175 | EitherSupport::Right(ref b) => b.local_analysis(cube), | |
| 176 | } | |
| 177 | } | |
| 178 | } | |
| 179 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
180 | impl<A, S1, S2> GlobalAnalysis<A> for EitherSupport<S1, S2> |
| 0 | 181 | where A : Aggregator, |
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
182 | S1 : GlobalAnalysis<A>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
183 | S2 : GlobalAnalysis<A>, { |
| 0 | 184 | |
| 185 | #[inline] | |
| 186 | fn global_analysis(&self) -> A { | |
| 187 | match self { | |
| 188 | EitherSupport::Left(ref a) => a.global_analysis(), | |
| 189 | EitherSupport::Right(ref b) => b.global_analysis(), | |
| 190 | } | |
| 191 | } | |
| 192 | } | |
| 193 | ||
|
13
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
194 | impl<F, S1, S2, X> Apply<X> for EitherSupport<S1, S2> |
|
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
195 | where S1 : Apply<X, Output=F>, |
|
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
196 | S2 : Apply<X, Output=F> { |
|
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
197 | type Output = F; |
| 0 | 198 | #[inline] |
|
13
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
199 | fn apply(&self, x : X) -> F { |
| 0 | 200 | match self { |
|
13
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
201 | EitherSupport::Left(ref a) => a.apply(x), |
|
465fa2121ccb
Better Linear and Mapping structure that can provide consuming and reference `apply`.
Tuomo Valkonen <tuomov@iki.fi>
parents:
8
diff
changeset
|
202 | EitherSupport::Right(ref b) => b.apply(x), |
| 0 | 203 | } |
| 204 | } | |
| 205 | } | |
| 206 | ||
|
81
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
207 | impl<F : Float, S1, S2, X> Differentiable<X> for EitherSupport<S1, S2> |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
208 | where S1 : Differentiable<X, Derivative=F, RealField=F>, |
|
d2acaaddd9af
Try to have Field as member type in Mappings etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
47
diff
changeset
|
209 | S2 : Differentiable<X, Derivative=F, RealField=F> { |
|
47
a0db98c16ab5
Some Differentiable simplifications and clarifications
Tuomo Valkonen <tuomov@iki.fi>
parents:
29
diff
changeset
|
210 | type Derivative = F; |
|
27
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
211 | #[inline] |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
212 | fn differential(&self, x : X) -> F { |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
213 | match self { |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
214 | EitherSupport::Left(ref a) => a.differential(x), |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
215 | EitherSupport::Right(ref b) => b.differential(x), |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
216 | } |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
217 | } |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
218 | } |
|
00029c20c0ee
Implement Differentiate for BTFN
Tuomo Valkonen <tuomov@iki.fi>
parents:
13
diff
changeset
|
219 | |
| 0 | 220 | macro_rules! make_either_scalarop_rhs { |
| 221 | ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { | |
| 222 | impl<F : Float, G1, G2> | |
| 223 | std::ops::$trait_assign<F> | |
| 224 | for BothGenerators<G1, G2> | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
225 | where G1 : std::ops::$trait_assign<F> + Clone, |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
226 | G2 : std::ops::$trait_assign<F> + Clone, { |
| 0 | 227 | #[inline] |
| 228 | fn $fn_assign(&mut self, t : F) { | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
229 | Arc::make_mut(&mut self.0).$fn_assign(t); |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
230 | Arc::make_mut(&mut self.1).$fn_assign(t); |
| 0 | 231 | } |
| 232 | } | |
| 233 | ||
| 234 | impl<'a, F : Float, G1, G2> | |
| 235 | std::ops::$trait<F> | |
| 236 | for &'a BothGenerators<G1, G2> | |
| 237 | where &'a G1 : std::ops::$trait<F,Output=G1>, | |
| 238 | &'a G2 : std::ops::$trait<F,Output=G2> { | |
| 239 | type Output = BothGenerators<G1, G2>; | |
| 240 | #[inline] | |
| 241 | fn $fn(self, t : F) -> BothGenerators<G1, G2> { | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
242 | BothGenerators(Arc::new(self.0.$fn(t)), |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
243 | Arc::new(self.1.$fn(t))) |
| 0 | 244 | } |
| 245 | } | |
| 246 | } | |
| 247 | } | |
| 248 | ||
| 249 | make_either_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); | |
| 250 | make_either_scalarop_rhs!(Div, div, DivAssign, div_assign); | |
| 251 | ||
| 252 | impl<G1, G2> std::ops::Neg for BothGenerators<G1, G2> | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
253 | where G1 : std::ops::Neg + Clone, |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
254 | G2 : std::ops::Neg + Clone, { |
| 0 | 255 | type Output = BothGenerators<G1::Output, G2::Output>; |
| 256 | #[inline] | |
| 257 | fn neg(self) -> Self::Output { | |
|
8
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
258 | BothGenerators(Arc::new(Arc::unwrap_or_clone(self.0).neg()), |
|
4e09b7829b51
Multithreaded bisection tree operations
Tuomo Valkonen <tuomov@iki.fi>
parents:
5
diff
changeset
|
259 | Arc::new(Arc::unwrap_or_clone(self.1).neg())) |
| 0 | 260 | } |
| 261 | } | |
| 262 | /* | |
| 263 | impl<'a, G1, G2> std::ops::Neg for &'a BothGenerators<G1, G2> | |
| 264 | where &'a G1 : std::ops::Neg, &'a G2 : std::ops::Neg, { | |
| 265 | type Output = BothGenerators<<&'a G1 as std::ops::Neg>::Output, | |
| 266 | <&'a G2 as std::ops::Neg>::Output>; | |
| 267 | fn neg(self) -> Self::Output { | |
| 268 | BothGenerators(self.0.neg(), self.1.neg()) | |
| 269 | } | |
| 270 | } | |
| 271 | */ |