1#[macro_export]
2macro_rules! define_units_relationship {
3 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 1 * __ 1 } => {
4 measures::expand_1_1_same! { $exact $with_approx $with_correlation, $unit2 $unit1 }
5 };
6 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 1 * $unit3:ident 1 } => {
7 measures::expand_1_1! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
8 };
9 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 2 == $unit2:ident 1 * $unit3:ident 2 } => {
10 measures::expand_1_2! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
11 };
12 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 2 == $unit2:ident 2 * $unit3:ident 1 } => {
13 measures::expand_1_2! { $exact $with_approx $with_correlation, $unit3 $unit2 $unit1 }
14 };
15 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 3 == $unit2:ident 1 * $unit3:ident 3 } => {
16 measures::expand_1_3! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
17 };
18 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 3 == $unit2:ident 3 * $unit3:ident 1 } => {
19 measures::expand_1_3! { $exact $with_approx $with_correlation, $unit3 $unit2 $unit1 }
20 };
21 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 2 * __ 2 } => {
22 measures::expand_2_2_same! { $exact $with_approx $with_correlation, $unit2 $unit1 }
23 };
24 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 2 * $unit3:ident 2 } => {
25 measures::expand_2_2! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
26 };
27 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 3 * __ 3 } => {
28 measures::expand_3_3_same! { $exact $with_approx $with_correlation, $unit2 $unit1 }
29 };
30 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 3 * $unit3:ident 3 } => {
31 measures::expand_3_3! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
32 };
33 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 2 X __ 2 } => {
34 measures::expand_cross_2_same! { $exact $with_approx $with_correlation, $unit2 $unit1 }
35 };
36 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 1 == $unit2:ident 2 X $unit3:ident 2 } => {
37 measures::expand_cross_2! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
38 };
39 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 3 == $unit2:ident 3 X __ 3 } => {
40 measures::expand_cross_3_same! { $exact $with_approx $with_correlation, $unit2 $unit1 }
41 };
42 { $exact:tt $with_approx:tt $with_correlation:tt, $unit1:ident 3 == $unit2:ident 3 X $unit3:ident 3 } => {
43 measures::expand_cross_3! { $exact $with_approx $with_correlation, $unit2 $unit3 $unit1 }
44 };
45}
46
47#[macro_export]
49macro_rules! expand_1_1 {
50 {
51 $exact:ident $with_approx:ident $with_correlation:ident,
52 $unit1:ident $unit2:ident $unit3:ident
53 } => {
54 measures::if_all_true! { { $exact }
56 impl<Number: ArithmeticOps> Mul<Measure<$unit2, Number>> for Measure<$unit1, Number> {
58 type Output = Measure<$unit3, Number>;
59 fn mul(self, other: Measure<$unit2, Number>) -> Self::Output {
60 Self::Output::new(self.value * other.value)
61 }
62 }
63
64 impl<Number: ArithmeticOps> Mul<Measure<$unit1, Number>> for Measure<$unit2, Number> {
66 type Output = Measure<$unit3, Number>;
67 fn mul(self, other: Measure<$unit1, Number>) -> Self::Output {
68 Self::Output::new(self.value * other.value)
69 }
70 }
71
72 impl<Number: ArithmeticOps> Div<Measure<$unit1, Number>> for Measure<$unit3, Number> {
74 type Output = Measure<$unit2, Number>;
75 fn div(self, other: Measure<$unit1, Number>) -> Self::Output {
76 Self::Output::new(self.value / other.value)
77 }
78 }
79
80 impl<Number: ArithmeticOps> Div<Measure<$unit2, Number>> for Measure<$unit3, Number> {
82 type Output = Measure<$unit1, Number>;
83 fn div(self, other: Measure<$unit2, Number>) -> Self::Output {
84 Self::Output::new(self.value / other.value)
85 }
86 }
87 }
88
89 measures::if_all_true! { { $with_approx }
91 impl<Number: ArithmeticOps> Mul<ApproxMeasure<$unit2, Number>> for ApproxMeasure<$unit1, Number> {
93 type Output = ApproxMeasure<$unit3, Number>;
94 fn mul(self, other: ApproxMeasure<$unit2, Number>) -> Self::Output {
95 Self::Output::with_variance(
96 self.value * other.value,
97 other.value * other.value * self.variance + self.value * self.value * other.variance
98 )
99 }
100 }
101
102 impl<Number: ArithmeticOps> Mul<ApproxMeasure<$unit1, Number>> for ApproxMeasure<$unit2, Number> {
104 type Output = ApproxMeasure<$unit3, Number>;
105 fn mul(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
106 let value_product = self.value * other.value;
107 Self::Output::with_variance(
108 value_product,
109 value_product *
110 (other.value * self.variance / self.value +
111 self.value * other.variance / other.value),
112 )
113 }
114 }
115
116 impl<Number: ArithmeticOps> Div<ApproxMeasure<$unit1, Number>> for ApproxMeasure<$unit3, Number> {
118 type Output = ApproxMeasure<$unit2, Number>;
119 fn div(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
120 let self_ratio = self.variance / (self.value * self.value);
121 let other_ratio = other.variance / (other.value * other.value);
122 let value_ratio = self.value / other.value;
123 Self::Output::with_variance(
124 value_ratio,
125 value_ratio * value_ratio * (self_ratio + other_ratio),
126 )
127 }
128 }
129
130 impl<Number: ArithmeticOps> Div<ApproxMeasure<$unit2, Number>> for ApproxMeasure<$unit3, Number> {
132 type Output = ApproxMeasure<$unit1, Number>;
133 fn div(self, other: ApproxMeasure<$unit2, Number>) -> Self::Output {
134 let self_ratio = self.variance / (self.value * self.value);
135 let other_ratio = other.variance / (other.value * other.value);
136 let value_ratio = self.value / other.value;
137 Self::Output::with_variance(
138 value_ratio,
139 value_ratio * value_ratio * (self_ratio + other_ratio),
140 )
141 }
142 }
143 }
144
145 measures::if_all_true! { { $with_correlation }
147 impl<Number: ArithmeticOps> ApproxMeasure<$unit1, Number> {
149 fn multiply_with_correlation(self, other: ApproxMeasure<$unit2, Number>, correlation: Number) -> ApproxMeasure<$unit3, Number> {
150 ApproxMeasure::<$unit3, Number>::with_variance(
151 self.value * other.value,
152 other.value * other.value * self.variance + self.value * self.value * other.variance + (Number::ONE + Number::ONE) * self.value * other.value * correlation * self.variance.sqrt() * other.variance.sqrt(),
153 )
154 }
155 }
156
157 impl<Number: ArithmeticOps> ApproxMeasure<$unit1, Number> {
159 fn multiply_with_correlation(self, other: ApproxMeasure<$unit2, Number>, correlation: Number) -> ApproxMeasure<$unit3, Number> {
160 other.multiply_with_correlation(self, correlation)
161 }
162 }
163
164 impl<Number: ArithmeticOps> ApproxMeasure<$unit1, Number> {
166 fn divide_with_correlation(self, other: ApproxMeasure<$unit2, Number>, correlation: Number) -> ApproxMeasure<$unit3, Number> {
167 let value_product = self.value * other.value;
169 ApproxMeasure::<$unit3, Number>::with_variance(
170 value_product,
171 other.value * other.value * self.variance + self.value * self.value * other.variance + (Number::ONE + Number::ONE) * self.value * other.value * correlation * self.variance.sqrt() * other.variance.sqrt(),
172 )
173 }
174 }
175
176 impl<Number: ArithmeticOps> ApproxMeasure<$unit1, Number> {
178 fn divide_with_correlation(self, other: ApproxMeasure<$unit2, Number>, correlation: Number) -> ApproxMeasure<$unit3, Number> {
179 let value_product = self.value * other.value;
181 ApproxMeasure::<$unit3, Number>::with_variance(
182 value_product,
183 other.value * other.value * self.variance + self.value * self.value * other.variance + (Number::ONE + Number::ONE) * self.value * other.value * correlation * self.variance.sqrt() * other.variance.sqrt(),
184 )
185 }
186 }
187 }
188 };
189}
190
191#[macro_export]
193macro_rules! expand_1_1_same {
194 {
195 $exact:ident $with_approx:ident $with_correlation:ident,
196 $unit1:ident $unit3:ident
197 } => {
198 measures::if_all_true! { { $exact }
199 impl<Number: ArithmeticOps> Mul<Measure<$unit1, Number>> for Measure<$unit1, Number> {
201 type Output = Measure<$unit3, Number>;
202 fn mul(self, other: Measure<$unit1, Number>) -> Self::Output {
203 Self::Output::new(self.value * other.value)
204 }
205 }
206
207 impl<Number: ArithmeticOps> Div<Measure<$unit1, Number>> for Measure<$unit3, Number> {
209 type Output = Measure<$unit1, Number>;
210 fn div(self, other: Measure<$unit1, Number>) -> Self::Output {
211 Self::Output::new(self.value / other.value)
212 }
213 }
214
215 impl<Number: ArithmeticOps> Measure<$unit1, Number> {
217 pub fn squared(self) -> Measure<$unit3, Number> {
218 Measure::<$unit3, Number>::new(self.value * self.value)
219 }
220 }
221
222 impl Sqrt for Measure<$unit3, f64> {
227 type Output = Measure<$unit1, f64>;
228 fn sqrt(self) -> Self::Output {
229 Self::Output::new(self.value.sqrt())
230 }
231 }
232 impl Sqrt for Measure<$unit3, f32> {
233 type Output = Measure<$unit1, f32>;
234 fn sqrt(self) -> Self::Output {
235 Self::Output::new(self.value.sqrt())
236 }
237 }
238 }
239
240 measures::if_all_true! { { $with_approx }
241 impl<Number: ArithmeticOps> Mul<ApproxMeasure<$unit1, Number>> for ApproxMeasure<$unit1, Number> {
243 type Output = ApproxMeasure<$unit3, Number>;
244 fn mul(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
245 let value_product = self.value * other.value;
246 Self::Output::with_variance(
247 value_product,
248 value_product *
249 (other.value * self.variance / self.value +
250 self.value * other.variance / other.value),
251 )
252 }
253 }
254
255 impl<Number: ArithmeticOps> Div<ApproxMeasure<$unit1, Number>> for ApproxMeasure<$unit3, Number> {
257 type Output = ApproxMeasure<$unit1, Number>;
258 fn div(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
259 let self_ratio = self.variance / (self.value * self.value);
260 let other_ratio = other.variance / (other.value * other.value);
261 let value_ratio = self.value / other.value;
262 Self::Output::with_variance(
263 value_ratio,
264 value_ratio * value_ratio * (self_ratio + other_ratio),
265 )
266 }
267 }
268
269 impl<Number: ArithmeticOps> ApproxMeasure<$unit1, Number> {
271 fn squared(self) -> ApproxMeasure<$unit3, Number> {
272 let value_product = self.value * self.value;
273 ApproxMeasure::<$unit3, Number>::with_variance(
274 value_product,
275 value_product * ((self.variance + self.variance) + (self.variance + self.variance)),
276 )
277 }
278 }
279
280 impl<Number: ArithmeticOps> Sqrt for ApproxMeasure<$unit3, Number> {
282 type Output = ApproxMeasure<$unit1, Number>;
283 fn sqrt(self) -> Self::Output {
284 Self::Output::with_variance(
285 self.value.sqrt(),
286 self.variance / self.value / ((Number::ONE + Number::ONE) + (Number::ONE + Number::ONE)),
287 )
288 }
289 }
290 }
291 };
292}
293
294#[macro_export]
296macro_rules! expand_1_2 {
297 {
298 $exact:ident $with_approx:ident $with_correlation:ident,
299 $unit1:ident $unit2:ident $unit3:ident
300 } => {
301 impl<Number: ArithmeticOps> Mul<Measure2d<$unit2, Number>> for Measure<$unit1, Number> {
303 type Output = Measure2d<$unit3, Number>;
304 fn mul(self, other: Measure2d<$unit2, Number>) -> Self::Output {
305 Self::Output::new([self.value * other.values[0], self.value * other.values[1]])
306 }
307 }
308
309 impl<Number: ArithmeticOps> Mul<Measure<$unit1, Number>> for Measure2d<$unit2, Number> {
311 type Output = Measure2d<$unit3, Number>;
312 fn mul(self, other: Measure<$unit1, Number>) -> Self::Output {
313 Self::Output::new([self.values[0] * other.value, self.values[1] * other.value])
314 }
315 }
316
317 impl<Number: ArithmeticOps> Div<Measure<$unit1, Number>> for Measure2d<$unit3, Number> {
319 type Output = Measure2d<$unit2, Number>;
320 fn div(self, other: Measure<$unit1, Number>) -> Self::Output {
321 Self::Output::new([self.values[0] / other.value, self.values[1] / other.value])
322 }
323 }
324 };
325}
326
327#[macro_export]
329macro_rules! expand_1_3 {
330 {
331 $exact:ident $with_approx:ident $with_correlation:ident,
332 $unit1:ident $unit2:ident $unit3:ident
333 } => {
334 impl<Number: ArithmeticOps> Mul<Measure3d<$unit2, Number>> for Measure<$unit1, Number> {
336 type Output = Measure3d<$unit3, Number>;
337 fn mul(self, other: Measure3d<$unit2, Number>) -> Self::Output {
338 Self::Output::new([
339 self.value * other.values[0],
340 self.value * other.values[1],
341 self.value * other.values[2],
342 ])
343 }
344 }
345
346 impl<Number: ArithmeticOps> Mul<Measure<$unit1, Number>> for Measure3d<$unit2, Number> {
348 type Output = Measure3d<$unit3, Number>;
349 fn mul(self, other: Measure<$unit1, Number>) -> Self::Output {
350 other * self
351 }
352 }
353
354 impl<Number: ArithmeticOps> Div<Measure<$unit1, Number>> for Measure3d<$unit3, Number> {
356 type Output = Measure3d<$unit2, Number>;
357 fn div(self, other: Measure<$unit1, Number>) -> Self::Output {
358 Self::Output::new([
359 self.values[0] / other.value,
360 self.values[1] / other.value,
361 self.values[2] / other.value,
362 ])
363 }
364 }
365
366 measures::if_all_true! { { $with_approx }
367 impl<Number: ArithmeticOps> Mul<ApproxMeasure3d<$unit2, Number>> for ApproxMeasure<$unit1, Number> {
369 type Output = ApproxMeasure3d<$unit3, Number>;
370 fn mul(self, other: ApproxMeasure3d<$unit2, Number>) -> Self::Output {
371 let value_product_x = self.value * other.values[0];
372 let value_product_y = self.value * other.values[1];
373 let value_product_z = self.value * other.values[2];
374 Self::Output::with_covariances(
375 [
376 value_product_x,
377 value_product_y,
378 value_product_z,
379 ],
380 other.covariances,
381 )
382 }
383 }
384
385 impl<Number: ArithmeticOps> Mul<ApproxMeasure<$unit1, Number>> for ApproxMeasure3d<$unit2, Number> {
387 type Output = ApproxMeasure3d<$unit3, Number>;
388 fn mul(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
389 other * self
390 }
391 }
392
393 impl<Number: ArithmeticOps> Div<ApproxMeasure<$unit1, Number>> for ApproxMeasure3d<$unit3, Number> {
395 type Output = ApproxMeasure3d<$unit2, Number>;
396 fn div(self, other: ApproxMeasure<$unit1, Number>) -> Self::Output {
397 let value_ratio_x = self.values[0] / other.value;
398 let value_ratio_y = self.values[1] / other.value;
399 let value_ratio_z = self.values[2] / other.value;
400 Self::Output::with_covariances(
401 [
402 value_ratio_x,
403 value_ratio_y,
404 value_ratio_z,
405 ],
406 self.covariances,
407 )
408 }
409 }
410 }
411 };
412}
413
414#[macro_export]
416macro_rules! expand_2_2 {
417 {
418 $exact:ident $with_approx:ident $with_correlation:ident,
419 $unit1:ident $unit2:ident $unit3:ident
420 } => {
421 impl<Number: ArithmeticOps> Mul<Measure2d<$unit2, Number>> for Measure2d<$unit1, Number> {
423 type Output = Measure<$unit3, Number>;
424 fn mul(self, other: Measure2d<$unit2, Number>) -> Self::Output {
425 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1])
426 }
427 }
428
429 impl<Number: ArithmeticOps> Mul<Measure2d<$unit1, Number>> for Measure2d<$unit2, Number> {
431 type Output = Measure<$unit3, Number>;
432 fn mul(self, other: Measure2d<$unit1, Number>) -> Self::Output {
433 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1])
434 }
435 }
436
437 measures::if_all_true! { { $with_approx }
438 }
439 };
440}
441
442#[macro_export]
444macro_rules! expand_2_2_same {
445 {
446 $exact:ident $with_approx:ident $with_correlation:ident,
447 $unit1:ident $unit2:ident
448 } => {
449 impl<Number: ArithmeticOps> Mul<Measure2d<$unit1, Number>> for Measure2d<$unit1, Number> {
451 type Output = Measure<$unit2, Number>;
452 fn mul(self, other: Measure2d<$unit1, Number>) -> Self::Output {
453 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1])
454 }
455 }
456
457 impl<Number: ArithmeticOps> Measure2d<$unit1, Number> {
459 pub fn squared(self) -> Measure<$unit2, Number> {
460 Measure::<$unit2, Number>::new(self.values[0] * self.values[0] + self.values[1] * self.values[1])
461 }
462 }
463
464 measures::if_all_true! { { $with_approx }
465 }
466 };
467}
468
469#[macro_export]
471macro_rules! expand_3_3_same {
472 {
473 $exact:ident $with_approx:ident $with_correlation:ident,
474 $unit1:ident $unit2:ident
475 } => {
476 impl<Number: ArithmeticOps> Mul<Measure3d<$unit1, Number>> for Measure3d<$unit1, Number> {
478 type Output = Measure<$unit2, Number>;
479 fn mul(self, other: Measure3d<$unit1, Number>) -> Self::Output {
480 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1] + self.values[2] * other.values[2])
481 }
482 }
483
484 impl<Number: ArithmeticOps> Measure3d<$unit1, Number> {
486 pub fn squared(self) -> Measure<$unit2, Number> {
487 Measure::<$unit2, Number>::new(self.values[0] * self.values[0] + self.values[1] * self.values[1] + self.values[2] * self.values[2])
488 }
489 }
490
491 measures::if_all_true! { { $with_approx }
492 impl<Number: ArithmeticOps> Mul<ApproxMeasure3d<$unit1, Number>> for ApproxMeasure3d<$unit1, Number> {
494 type Output = ApproxMeasure<$unit2, Number>;
495 fn mul(self, other: ApproxMeasure3d<$unit1, Number>) -> Self::Output {
496 let value_product_x = self.values[0] * other.values[0];
497 let value_product_y = self.values[1] * other.values[1];
498 let value_product_z = self.values[2] * other.values[2];
499 Self::Output::with_variance(
500 value_product_x +
501 value_product_y +
502 value_product_z,
503 self.covariances[0][0],
504 )
505 }
506 }
507
508 impl<Number: ArithmeticOps> ApproxMeasure3d<$unit1, Number> {
510 fn squared(self) -> ApproxMeasure<$unit2, Number> {
511 let value = self.values[0] * self.values[0] + self.values[1] * self.values[1] + self.values[2] * self.values[2];
512 ApproxMeasure::<$unit2, Number>::with_variance(
513 value,
514 value * (self.covariances[0][0] + self.covariances[0][0]),
515 )
516 }
517 }
518 }
519 };
520}
521
522#[macro_export]
524macro_rules! expand_3_3 {
525 {
526 $exact:ident $with_approx:ident $with_correlation:ident,
527 $unit1:ident $unit2:ident $unit3:ident
528 } => {
529 impl<Number: ArithmeticOps> Mul<Measure3d<$unit2, Number>> for Measure3d<$unit1, Number> {
531 type Output = Measure<$unit3, Number>;
532 fn mul(self, other: Measure3d<$unit2, Number>) -> Self::Output {
533 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1] + self.values[2] * other.values[2])
534 }
535 }
536
537 impl<Number: ArithmeticOps> Mul<Measure3d<$unit1, Number>> for Measure3d<$unit2, Number> {
539 type Output = Measure<$unit3, Number>;
540 fn mul(self, other: Measure3d<$unit1, Number>) -> Self::Output {
541 Self::Output::new(self.values[0] * other.values[0] + self.values[1] * other.values[1] + self.values[2] * other.values[2])
542 }
543 }
544
545 measures::if_all_true! { { $with_approx }
546 impl<Number: ArithmeticOps> Mul<ApproxMeasure3d<$unit2, Number>> for ApproxMeasure3d<$unit1, Number> {
548 type Output = ApproxMeasure<$unit3, Number>;
549 fn mul(self, other: ApproxMeasure3d<$unit2, Number>) -> Self::Output {
550 let value_product_x = self.values[0] * other.values[0];
551 let value_product_y = self.values[1] * other.values[1];
552 let value_product_z = self.values[2] * other.values[2];
553 Self::Output::with_variance(
554 value_product_x + value_product_y + value_product_z,
555 self.covariances[0][0],
556 )
557 }
558 }
559
560 impl<Number: ArithmeticOps> Mul<ApproxMeasure3d<$unit1, Number>> for ApproxMeasure3d<$unit2, Number> {
562 type Output = ApproxMeasure<$unit3, Number>;
563 fn mul(self, other: ApproxMeasure3d<$unit1, Number>) -> Self::Output {
564 let value_product_x = self.values[0] * other.values[0];
565 let value_product_y = self.values[1] * other.values[1];
566 let value_product_z = self.values[2] * other.values[2];
567 Self::Output::with_variance(
568 value_product_x + value_product_y + value_product_z,
569 self.covariances[0][0],
570 )
571 }
572 }
573 }
574 };
575}
576
577#[macro_export]
579macro_rules! expand_cross_2_same {
580 {
581 $exact:ident $with_approx:ident $with_correlation:ident,
582 $unit1:ident $unit2:ident
583 } => {
584 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure2d<$unit1, Number>> for Measure2d<$unit1, Number> {
586 type Output = Measure<$unit2, Number>;
587 fn cross_product(self, other: Measure2d<$unit1, Number>) -> Self::Output {
588 Self::Output::new(self.values[0] * other.values[1] - self.values[1] * other.values[0])
589 }
590 }
591
592 measures::if_all_true! { { $with_approx }
593 }
594 };
595}
596
597#[macro_export]
599macro_rules! expand_cross_2 {
600 {
601 $exact:ident $with_approx:ident $with_correlation:ident,
602 $unit1:ident $unit2:ident $unit3:ident
603 } => {
604 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure2d<$unit2, Number>> for Measure2d<$unit1, Number> {
606 type Output = Measure<$unit3, Number>;
607 fn cross_product(self, other: Measure2d<$unit2, Number>) -> Self::Output {
608 Self::Output::new(self.values[0] * other.values[1] - self.values[1] * other.values[0])
609 }
610 }
611
612 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure2d<$unit1, Number>> for Measure2d<$unit2, Number> {
614 type Output = Measure<$unit3, Number>;
615 fn cross_product(self, other: Measure2d<$unit1, Number>) -> Self::Output {
616 Self::Output::new(self.values[0] * other.values[1] - self.values[1] * other.values[0])
617 }
618 }
619
620 measures::if_all_true! { { $with_approx }
621 }
622 };
623}
624
625#[macro_export]
627macro_rules! expand_cross_3_same {
628 {
629 $exact:ident $with_approx:ident $with_correlation:ident,
630 $unit1:ident $unit2:ident
631 } => {
632 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure3d<$unit1, Number>> for Measure3d<$unit1, Number> {
634 type Output = Measure3d<$unit2, Number>;
635 fn cross_product(self, other: Measure3d<$unit1, Number>) -> Self::Output {
636 Self::Output::new(
637 [
638 self.values[1] * other.values[2] - self.values[2] * other.values[1],
639 self.values[2] * other.values[0] - self.values[0] * other.values[2],
640 self.values[0] * other.values[1] - self.values[1] * other.values[0],
641 ]
642 )
643 }
644 }
645
646 measures::if_all_true! { { $with_approx }
647 }
648 };
649}
650
651#[macro_export]
653macro_rules! expand_cross_3 {
654 {
655 $exact:ident $with_approx:ident $with_correlation:ident,
656 $unit1:ident $unit2:ident $unit3:ident
657 } => {
658 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure3d<$unit2, Number>> for Measure3d<$unit1, Number> {
660 type Output = Measure3d<$unit3, Number>;
661 fn cross_product(self, other: Measure3d<$unit2, Number>) -> Self::Output {
662 Self::Output::new([
663 self.values[1] * other.values[2] - self.values[2] * other.values[1],
664 self.values[2] * other.values[0] - self.values[0] * other.values[2],
665 self.values[0] * other.values[1] - self.values[1] * other.values[0],
666 ])
667 }
668 }
669
670 impl<Number: ArithmeticOps> measures::traits::CrossProduct<Measure3d<$unit1, Number>> for Measure3d<$unit2, Number> {
672 type Output = Measure3d<$unit3, Number>;
673 fn cross_product(self, other: Measure3d<$unit1, Number>) -> Self::Output {
674 Self::Output::new([
675 self.values[1] * other.values[2] - self.values[2] * other.values[1],
676 self.values[2] * other.values[0] - self.values[0] * other.values[2],
677 self.values[0] * other.values[1] - self.values[1] * other.values[0],
678 ])
679 }
680 }
681
682 measures::if_all_true! { { $with_approx }
683 }
684 };
685}