vox_geometry_rust/
matrix_expression.rs

1/*
2 * // Copyright (c) 2021 Feng Yang
3 * //
4 * // I am making my contributions/submissions to this project solely in my
5 * // personal capacity and am not conveying any rights to any intellectual
6 * // property of any third parties.
7 */
8
9use crate::usize2::USize2;
10use crate::operators::*;
11use crate::vector_expression::*;
12use std::ops::{Sub, Neg, Add, Mul, Div};
13
14
15///
16/// # Base class for matrix expression.
17///
18/// Matrix expression is a meta type that enables template expression pattern.
19///
20/// - tparam T  Real number type.
21/// - tparam E  Subclass type.
22///
23pub trait MatrixExpression {
24    /// Size of the matrix.
25    fn size(&self) -> USize2;
26
27    /// Number of rows.
28    fn rows(&self) -> usize;
29
30    /// Number of columns.
31    fn cols(&self) -> usize;
32
33    /// Returns matrix element at (i, j).
34    fn eval(&self, x: usize, y: usize) -> f64;
35}
36
37//--------------------------------------------------------------------------------------------------
38///
39/// # Constant matrix expression.
40///
41/// This matrix expression represents a constant matrix.
42///
43/// - tparam T  Real number type.
44///
45pub struct MatrixConstant {
46    _m: usize,
47    _n: usize,
48    _c: f64,
49}
50
51impl MatrixConstant {
52    /// Constructs m x n constant matrix expression.
53    pub fn new(m: usize, n: usize, c: f64) -> MatrixConstant {
54        return MatrixConstant {
55            _m: m,
56            _n: n,
57            _c: c,
58        };
59    }
60}
61
62impl MatrixExpression for MatrixConstant {
63    /// Size of the matrix.
64    fn size(&self) -> USize2 {
65        return USize2::new(self.rows(), self.cols());
66    }
67
68    /// Number of rows.
69    fn rows(&self) -> usize {
70        return self._m;
71    }
72
73    /// Number of columns.
74    fn cols(&self) -> usize {
75        return self._n;
76    }
77
78    /// Returns matrix element at (i, j).
79    fn eval(&self, _i: usize, _j: usize) -> f64 {
80        return self._c;
81    }
82}
83
84//--------------------------------------------------------------------------------------------------
85///
86/// # Identity matrix expression.
87///
88/// This matrix expression represents an identity matrix.
89///
90/// - tparam T  Real number type.
91///
92pub struct MatrixIdentity {
93    _m: usize,
94}
95
96impl MatrixIdentity {
97    /// Constructs m x m identity matrix expression.
98    pub fn new(m: usize) -> MatrixIdentity {
99        return MatrixIdentity {
100            _m: m
101        };
102    }
103}
104
105impl MatrixExpression for MatrixIdentity {
106    /// Size of the matrix.
107    fn size(&self) -> USize2 {
108        return USize2::new(self._m, self._m);
109    }
110
111    /// Number of rows.
112    fn rows(&self) -> usize {
113        return self._m;
114    }
115
116    /// Number of columns.
117    fn cols(&self) -> usize {
118        return self._m;
119    }
120
121    /// Returns matrix element at (i, j).
122    fn eval(&self, i: usize, j: usize) -> f64 {
123        return match i == j {
124            true => 1.0,
125            false => 0.0
126        };
127    }
128}
129
130//--------------------------------------------------------------------------------------------------
131/// # MatrixUnaryOp
132
133///
134/// # Matrix expression for unary operation.
135///
136/// This matrix expression represents an unary matrix operation that takes
137/// single input matrix expression.
138///
139/// - tparam T   Real number type.
140/// - tparam E   Input expression type.
141/// - tparam Op  Unary operation.
142///
143pub struct MatrixUnaryOp<E: MatrixExpression, Op: UnaryOp> {
144    _u: E,
145    _op: Op,
146}
147
148impl<E: MatrixExpression, Op: UnaryOp> MatrixUnaryOp<E, Op> {
149    /// Constructs unary operation expression for given input expression.
150    pub fn new(u: E) -> MatrixUnaryOp<E, Op> {
151        return MatrixUnaryOp {
152            _u: u,
153            _op: Op::new(),
154        };
155    }
156}
157
158impl<E: MatrixExpression, Op: UnaryOp> MatrixExpression for MatrixUnaryOp<E, Op> {
159    /// Size of the matrix.
160    fn size(&self) -> USize2 {
161        return self._u.size();
162    }
163
164    /// Number of rows.
165    fn rows(&self) -> usize {
166        return self._u.rows();
167    }
168
169    /// Number of columns.
170    fn cols(&self) -> usize {
171        return self._u.cols();
172    }
173
174    /// Returns matrix element at (i, j).
175    fn eval(&self, i: usize, j: usize) -> f64 {
176        return self._op.eval(self._u.eval(i, j));
177    }
178}
179
180//--------------------------------------------------------------------------------------------------
181///
182/// # Diagonal matrix expression.
183///
184/// This matrix expression represents a diagonal matrix for given input matrix
185/// expression.
186///
187/// - tparam T  Real number type.
188/// - tparam E  Input expression type.
189///
190pub struct MatrixDiagonal<E: MatrixExpression> {
191    _u: E,
192    _is_diag: bool,
193}
194
195impl<E: MatrixExpression> MatrixDiagonal<E> {
196    /// Constructs diagonal matrix expression for given input expression.
197    /// - parameter: is_diag - True for diagonal matrix, false for off-diagonal.
198    pub fn new(u: E, is_diag: bool) -> MatrixDiagonal<E> {
199        return MatrixDiagonal {
200            _u: u,
201            _is_diag: is_diag,
202        };
203    }
204}
205
206impl<E: MatrixExpression> MatrixExpression for MatrixDiagonal<E> {
207    /// Size of the matrix.
208    fn size(&self) -> USize2 {
209        return self._u.size();
210    }
211
212    /// Number of rows.
213    fn rows(&self) -> usize {
214        return self._u.rows();
215    }
216
217    /// Number of columns.
218    fn cols(&self) -> usize {
219        return self._u.cols();
220    }
221
222    /// Returns matrix element at (i, j).
223    fn eval(&self, i: usize, j: usize) -> f64 {
224        return if self._is_diag {
225            match i == j {
226                true => self._u.eval(i, j),
227                false => 0.0
228            }
229        } else {
230            match i != j {
231                true => self._u.eval(i, j),
232                false => 0.0
233            }
234        };
235    }
236}
237
238//--------------------------------------------------------------------------------------------------
239///
240/// # Triangular matrix expression.
241///
242/// This matrix expression represents a triangular matrix for given input matrix
243/// expression.
244///
245/// - tparam T  Real number type.
246/// - tparam E  Input expression type.
247///
248pub struct MatrixTriangular<E: MatrixExpression> {
249    _u: E,
250    _is_upper: bool,
251    _is_strict: bool,
252}
253
254impl<E: MatrixExpression> MatrixTriangular<E> {
255    /// Constructs triangular matrix expression for given input expression.
256    /// - parameter: is_upper - True for upper tri matrix, false for lower tri matrix.
257    /// - parameter: is_strict - True for strictly upper/lower triangular matrix.
258    pub fn new(u: E, is_upper: bool, is_strict: bool) -> MatrixTriangular<E> {
259        return MatrixTriangular {
260            _u: u,
261            _is_upper: is_upper,
262            _is_strict: is_strict,
263        };
264    }
265}
266
267impl<E: MatrixExpression> MatrixExpression for MatrixTriangular<E> {
268    /// Size of the matrix.
269    fn size(&self) -> USize2 {
270        return self._u.size();
271    }
272
273    /// Number of rows.
274    fn rows(&self) -> usize {
275        return self._u.rows();
276    }
277
278    /// Number of columns.
279    fn cols(&self) -> usize {
280        return self._u.cols();
281    }
282
283    /// Returns matrix element at (i, j).
284    fn eval(&self, i: usize, j: usize) -> f64 {
285        return if i < j {
286            match self._is_upper {
287                true => self._u.eval(i, j),
288                false => 0.0
289            }
290        } else if i > j {
291            match !self._is_upper {
292                true => self._u.eval(i, j),
293                false => 0.0
294            }
295        } else {
296            match !self._is_strict {
297                true => self._u.eval(i, j),
298                false => 0.0
299            }
300        };
301    }
302}
303
304//--------------------------------------------------------------------------------------------------
305/// # MatrixBinaryOp
306
307///
308/// # Matrix expression for binary operation.
309///
310/// This matrix expression represents a binary matrix operation that takes
311/// two input matrix expressions.
312///
313/// - tparam T   Real number type.
314/// - tparam E1  First input expression type.
315/// - tparam E2  Second input expression type.
316/// - tparam Op  Binary operation.
317///
318pub struct MatrixBinaryOp<E1: MatrixExpression, E2: MatrixExpression, Op: BinaryOp> {
319    _u: E1,
320    _v: E2,
321    _op: Op,
322}
323
324impl<E1: MatrixExpression, E2: MatrixExpression, Op: BinaryOp> MatrixBinaryOp<E1, E2, Op> {
325    /// Constructs binary operation expression for given input matrix
326    /// expressions.
327    pub fn new(u: E1, v: E2) -> MatrixBinaryOp<E1, E2, Op> {
328        return MatrixBinaryOp {
329            _u: u,
330            _v: v,
331            _op: Op::new(),
332        };
333    }
334}
335
336impl<E1: MatrixExpression, E2: MatrixExpression, Op: BinaryOp> MatrixExpression for MatrixBinaryOp<E1, E2, Op> {
337    /// Size of the matrix.
338    fn size(&self) -> USize2 {
339        return self._v.size();
340    }
341
342    /// Number of rows.
343    fn rows(&self) -> usize {
344        return self._v.rows();
345    }
346
347    /// Number of columns.
348    fn cols(&self) -> usize {
349        return self._v.cols();
350    }
351
352    /// Returns matrix element at (i, j).
353    fn eval(&self, i: usize, j: usize) -> f64 {
354        return self._op.eval(self._u.eval(i, j), self._v.eval(i, j));
355    }
356}
357
358//--------------------------------------------------------------------------------------------------
359///
360/// # Matrix expression for matrix-scalar binary operation.
361///
362/// This matrix expression represents a binary matrix operation that takes
363/// one input matrix expression and one scalar.
364///
365/// - tparam T   Real number type.
366/// - tparam E   Input expression type.
367/// - tparam Op  Binary operation.
368///
369pub struct MatrixScalarBinaryOp<E: MatrixExpression, Op: BinaryOp> {
370    _u: E,
371    _v: f64,
372    _op: Op,
373}
374
375impl<E: MatrixExpression, Op: BinaryOp> MatrixScalarBinaryOp<E, Op> {
376    /// Constructs a binary expression for given matrix and scalar.
377    pub fn new(u: E, v: f64) -> MatrixScalarBinaryOp<E, Op> {
378        return MatrixScalarBinaryOp {
379            _u: u,
380            _v: v,
381            _op: Op::new(),
382        };
383    }
384}
385
386impl<E: MatrixExpression, Op: BinaryOp> MatrixExpression for MatrixScalarBinaryOp<E, Op> {
387    fn size(&self) -> USize2 {
388        return self._u.size();
389    }
390
391    fn rows(&self) -> usize {
392        return self._u.rows();
393    }
394
395    fn cols(&self) -> usize {
396        return self._u.cols();
397    }
398
399    /// Returns matrix element at (i, j).
400    fn eval(&self, i: usize, j: usize) -> f64 {
401        return self._op.eval(self._u.eval(i, j), self._v);
402    }
403}
404
405//--------------------------------------------------------------------------------------------------
406///
407/// # Vector expression for matrix-vector multiplication.
408///
409/// This vector expression represents a matrix-vector operation that takes
410/// one input matrix expression and one vector expression.
411///
412/// - tparam T   Element value type.
413/// - tparam ME  Matrix expression.
414/// - tparam VE  Vector expression.
415///
416pub struct MatrixVectorMul<ME: MatrixExpression, VE: VectorExpression> {
417    _m: ME,
418    _v: VE,
419}
420
421impl<ME: MatrixExpression, VE: VectorExpression> MatrixVectorMul<ME, VE> {
422    pub fn new(m: ME, v: VE) -> MatrixVectorMul<ME, VE> {
423        return MatrixVectorMul {
424            _m: m,
425            _v: v,
426        };
427    }
428
429    /// Returns vector element at i.
430    pub fn eval(&self, i: usize) -> f64 {
431        let mut sum: f64 = 0.0;
432        let n = self._m.cols();
433        for j in 0..n {
434            sum += self._m.eval(i, j) * self._v.eval(j);
435        }
436        return sum;
437    }
438
439    /// Size of the vector.
440    pub fn size(&self) -> usize {
441        return self._v.size();
442    }
443}
444
445impl<ME: MatrixExpression, VE: VectorExpression> MatrixExpression for MatrixVectorMul<ME, VE> {
446    fn size(&self) -> USize2 {
447        unimplemented!();
448    }
449
450    fn rows(&self) -> usize {
451        unimplemented!();
452    }
453
454    fn cols(&self) -> usize {
455        unimplemented!();
456    }
457
458    fn eval(&self, _x: usize, _y: usize) -> f64 {
459        unimplemented!();
460    }
461}
462
463//--------------------------------------------------------------------------------------------------
464///
465/// # Matrix expression for matrix-matrix multiplication.
466///
467/// This matrix expression represents a matrix-matrix operation that takes
468/// two input matrices.
469///
470/// - tparam T   Element value type.
471/// - tparam ME  Matrix expression.
472/// - tparam VE  Vector expression.
473///
474pub struct MatrixMul<E1: MatrixExpression, E2: MatrixExpression> {
475    _u: E1,
476    _v: E2,
477}
478
479impl<E1: MatrixExpression, E2: MatrixExpression> MatrixMul<E1, E2> {
480    /// Constructs matrix-matrix multiplication expression for given two input
481    /// matrices.
482    pub fn new(u: E1, v: E2) -> MatrixMul<E1, E2> {
483        return MatrixMul {
484            _u: u,
485            _v: v,
486        };
487    }
488}
489
490impl<E1: MatrixExpression, E2: MatrixExpression> MatrixExpression for MatrixMul<E1, E2> {
491    /// Size of the matrix.
492    fn size(&self) -> USize2 {
493        return USize2::new(self._u.rows(), self._v.cols());
494    }
495
496    /// Number of rows.
497    fn rows(&self) -> usize {
498        return self._u.rows();
499    }
500
501    /// Number of columns.
502    fn cols(&self) -> usize {
503        return self._v.cols();
504    }
505
506    /// Returns matrix element at (i, j).
507    fn eval(&self, i: usize, j: usize) -> f64 {
508        // todo: Unoptimized mat-mat-mul
509        let mut sum: f64 = 0.0;
510        let n = self._u.cols();
511        for k in 0..n {
512            sum += self._u.eval(i, k) * self._v.eval(k, j);
513        }
514        return sum;
515    }
516}
517
518//--------------------------------------------------------------------------------------------------
519/// # MatrixBinaryOp Aliases
520
521/// Matrix-matrix addition expression.
522pub type MatrixAdd<E1, E2> = MatrixBinaryOp<E1, E2, Plus>;
523/// Matrix-matrix addition expression.
524pub type MatrixScalarAdd<E> = MatrixScalarBinaryOp<E, Plus>;
525
526
527/// Matrix-matrix subtraction expression.
528pub type MatrixSub<E1, E2> = MatrixBinaryOp<E1, E2, Minus>;
529
530/// Matrix-scalar subtraction expression.
531pub type MatrixScalarSub<E> = MatrixScalarBinaryOp<E, Minus>;
532
533
534/// Matrix-matrix subtraction expression with inverse order.
535pub type MatrixScalarRSub<E> = MatrixScalarBinaryOp<E, RMinus>;
536
537
538/// Matrix-scalar multiplication expression.
539pub type MatrixScalarMul<E> = MatrixScalarBinaryOp<E, Multiplies>;
540
541/// Matrix-scalar division expression.
542pub type MatrixScalarDiv<E> = MatrixScalarBinaryOp<E, Divides>;
543
544
545/// Matrix-scalar division expression with inverse order.
546pub type MatrixScalarRDiv<E> = MatrixScalarBinaryOp<E, RDivides>;
547//--------------------------------------------------------------------------------------------------------------------------
548//--------------------------------------------------------------------------------------------------------------------------
549/// Returns a matrix with opposite sign.
550macro_rules! impl_neg_mat0 {
551    ($Matrix:ty) => {
552        impl Neg for $Matrix {
553            type Output = MatrixScalarMul<$Matrix>;
554
555            fn neg(self) -> Self::Output {
556                return MatrixScalarMul::new(self, -1.0);
557            }
558        }
559    }
560}
561impl_neg_mat0!(MatrixConstant);
562impl_neg_mat0!(MatrixIdentity);
563
564macro_rules! impl_neg_mat1 {
565    ($Matrix:ty) => {
566        impl<E: MatrixExpression> Neg for $Matrix {
567            type Output = MatrixScalarMul<$Matrix>;
568
569            fn neg(self) -> Self::Output {
570                return MatrixScalarMul::new(self, -1.0);
571            }
572        }
573    }
574}
575impl_neg_mat1!(MatrixDiagonal<E>);
576impl_neg_mat1!(MatrixTriangular<E>);
577impl_neg_mat1!(MatrixScalarAdd<E>);
578impl_neg_mat1!(MatrixScalarSub<E>);
579impl_neg_mat1!(MatrixScalarRSub<E>);
580impl_neg_mat1!(MatrixScalarMul<E>);
581impl_neg_mat1!(MatrixScalarDiv<E>);
582impl_neg_mat1!(MatrixScalarRDiv<E>);
583
584macro_rules! impl_neg_mat1_vec1 {
585    ($Matrix:ty) => {
586        impl<E: MatrixExpression, E1: VectorExpression> Neg for $Matrix {
587            type Output = MatrixScalarMul<$Matrix>;
588
589            fn neg(self) -> Self::Output {
590                return MatrixScalarMul::new(self, -1.0);
591            }
592        }
593    }
594}
595impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
596impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
597impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
598impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
599impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
600impl_neg_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
601
602macro_rules! impl_neg_mat1_vec2 {
603    ($Matrix:ty) => {
604        impl<E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Neg for $Matrix {
605            type Output = MatrixScalarMul<$Matrix>;
606
607            fn neg(self) -> Self::Output {
608                return MatrixScalarMul::new(self, -1.0);
609            }
610        }
611    }
612}
613impl_neg_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
614impl_neg_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
615impl_neg_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
616impl_neg_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
617
618macro_rules! impl_neg_mat2 {
619    ($Matrix:ty) => {
620        impl<E1: MatrixExpression, E2: MatrixExpression> Neg for $Matrix {
621            type Output = MatrixScalarMul<$Matrix>;
622
623            fn neg(self) -> Self::Output {
624                return MatrixScalarMul::new(self, -1.0);
625            }
626        }
627    }
628}
629impl_neg_mat2!(MatrixMul<E1, E2>);
630impl_neg_mat2!(MatrixAdd<E1, E2>);
631impl_neg_mat2!(MatrixSub<E1, E2>);
632
633//--------------------------------------------------------------------------------------------------
634/// Returns a + b (element-size).
635macro_rules! impl_add_mat0 {
636    ($Matrix:ty) => {
637        impl<Return: MatrixExpression> Add<Return> for $Matrix {
638            type Output = MatrixAdd<$Matrix, Return>;
639
640            fn add(self, rhs: Return) -> Self::Output {
641                return MatrixAdd::new(self, rhs);
642            }
643        }
644    }
645}
646impl_add_mat0!(MatrixConstant);
647impl_add_mat0!(MatrixIdentity);
648
649macro_rules! impl_add_mat1 {
650    ($Matrix:ty) => {
651        impl<Return: MatrixExpression, E: MatrixExpression> Add<Return> for $Matrix {
652            type Output = MatrixAdd<$Matrix, Return>;
653
654            fn add(self, rhs: Return) -> Self::Output {
655                return MatrixAdd::new(self, rhs);
656            }
657        }
658    }
659}
660impl_add_mat1!(MatrixDiagonal<E>);
661impl_add_mat1!(MatrixTriangular<E>);
662impl_add_mat1!(MatrixScalarAdd<E>);
663impl_add_mat1!(MatrixScalarSub<E>);
664impl_add_mat1!(MatrixScalarRSub<E>);
665impl_add_mat1!(MatrixScalarMul<E>);
666impl_add_mat1!(MatrixScalarDiv<E>);
667impl_add_mat1!(MatrixScalarRDiv<E>);
668
669macro_rules! impl_add_mat1_vec1 {
670    ($Matrix:ty) => {
671        impl<Return: MatrixExpression, E: MatrixExpression, E1: VectorExpression> Add<Return> for $Matrix {
672            type Output = MatrixAdd<$Matrix, Return>;
673
674            fn add(self, rhs: Return) -> Self::Output {
675                return MatrixAdd::new(self, rhs);
676            }
677        }
678    }
679}
680impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
681impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
682impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
683impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
684impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
685impl_add_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
686
687macro_rules! impl_add_mat1_vec2 {
688    ($Matrix:ty) => {
689        impl<Return: MatrixExpression, E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Add<Return> for $Matrix {
690            type Output = MatrixAdd<$Matrix, Return>;
691
692            fn add(self, rhs: Return) -> Self::Output {
693                return MatrixAdd::new(self, rhs);
694            }
695        }
696    }
697}
698impl_add_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
699impl_add_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
700impl_add_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
701impl_add_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
702
703macro_rules! impl_add_mat1_vec2 {
704    ($Matrix:ty) => {
705        impl<Return: MatrixExpression, E1: MatrixExpression, E2: MatrixExpression> Add<Return> for $Matrix {
706            type Output = MatrixAdd<$Matrix, Return>;
707
708            fn add(self, rhs: Return) -> Self::Output {
709                return MatrixAdd::new(self, rhs);
710            }
711        }
712    }
713}
714impl_add_mat1_vec2!(MatrixMul<E1, E2>);
715impl_add_mat1_vec2!(MatrixAdd<E1, E2>);
716impl_add_mat1_vec2!(MatrixSub<E1, E2>);
717
718//--------------------------------------------------------------------------------------------------
719/// Returns a + b', where every element of matrix b' is b.
720macro_rules! impl_add_scalar_mat0 {
721    ($Matrix:ty) => {
722        impl Add<f64> for $Matrix {
723            type Output = MatrixScalarAdd<$Matrix>;
724
725            fn add(self, rhs: f64) -> Self::Output {
726                return MatrixScalarAdd::new(self, rhs);
727            }
728        }
729    }
730}
731impl_add_scalar_mat0!(MatrixConstant);
732impl_add_scalar_mat0!(MatrixIdentity);
733
734macro_rules! impl_add_scalar_mat1 {
735    ($Matrix:ty) => {
736        impl<E: MatrixExpression> Add<f64> for $Matrix {
737            type Output = MatrixScalarAdd<$Matrix>;
738
739            fn add(self, rhs: f64) -> Self::Output {
740                return MatrixScalarAdd::new(self, rhs);
741            }
742        }
743    }
744}
745impl_add_scalar_mat1!(MatrixDiagonal<E>);
746impl_add_scalar_mat1!(MatrixTriangular<E>);
747impl_add_scalar_mat1!(MatrixScalarAdd<E>);
748impl_add_scalar_mat1!(MatrixScalarSub<E>);
749impl_add_scalar_mat1!(MatrixScalarRSub<E>);
750impl_add_scalar_mat1!(MatrixScalarMul<E>);
751impl_add_scalar_mat1!(MatrixScalarDiv<E>);
752impl_add_scalar_mat1!(MatrixScalarRDiv<E>);
753
754macro_rules! impl_add_scalar_mat1_vec1 {
755    ($Matrix:ty) => {
756        impl<E: MatrixExpression, E1: VectorExpression> Add<f64> for $Matrix {
757            type Output = MatrixScalarAdd<$Matrix>;
758
759            fn add(self, rhs: f64) -> Self::Output {
760                return MatrixScalarAdd::new(self, rhs);
761            }
762        }
763    }
764}
765impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
766impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
767impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
768impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
769impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
770impl_add_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
771
772macro_rules! impl_add_scalar_mat1_vec2 {
773    ($Matrix:ty) => {
774        impl<E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Add<f64> for $Matrix {
775            type Output = MatrixScalarAdd<$Matrix>;
776
777            fn add(self, rhs: f64) -> Self::Output {
778                return MatrixScalarAdd::new(self, rhs);
779            }
780        }
781    }
782}
783impl_add_scalar_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
784impl_add_scalar_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
785impl_add_scalar_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
786impl_add_scalar_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
787
788macro_rules! impl_add_scalar_mat2 {
789    ($Matrix:ty) => {
790        impl<E1: MatrixExpression, E2: MatrixExpression> Add<f64> for $Matrix {
791            type Output = MatrixScalarAdd<$Matrix>;
792
793            fn add(self, rhs: f64) -> Self::Output {
794                return MatrixScalarAdd::new(self, rhs);
795            }
796        }
797    }
798}
799impl_add_scalar_mat2!(MatrixMul<E1, E2>);
800impl_add_scalar_mat2!(MatrixAdd<E1, E2>);
801impl_add_scalar_mat2!(MatrixSub<E1, E2>);
802
803//--------------------------------------------------------------------------------------------------
804/// Returns a - b (element-size).
805macro_rules! impl_sub_mat0 {
806    ($Matrix:ty) => {
807        impl<Return: MatrixExpression> Sub<Return> for $Matrix {
808            type Output = MatrixSub<$Matrix, Return>;
809
810            fn sub(self, rhs: Return) -> Self::Output {
811                return MatrixSub::new(self, rhs);
812            }
813        }
814    }
815}
816impl_sub_mat0!(MatrixConstant);
817impl_sub_mat0!(MatrixIdentity);
818
819macro_rules! impl_sub_mat1 {
820    ($Matrix:ty) => {
821        impl<Return: MatrixExpression, E: MatrixExpression> Sub<Return> for $Matrix {
822            type Output = MatrixSub<$Matrix, Return>;
823
824            fn sub(self, rhs: Return) -> Self::Output {
825                return MatrixSub::new(self, rhs);
826            }
827        }
828    }
829}
830impl_sub_mat1!(MatrixDiagonal<E>);
831impl_sub_mat1!(MatrixTriangular<E>);
832impl_sub_mat1!(MatrixScalarAdd<E>);
833impl_sub_mat1!(MatrixScalarSub<E>);
834impl_sub_mat1!(MatrixScalarRSub<E>);
835impl_sub_mat1!(MatrixScalarMul<E>);
836impl_sub_mat1!(MatrixScalarDiv<E>);
837impl_sub_mat1!(MatrixScalarRDiv<E>);
838
839macro_rules! impl_sub_mat1_vec1 {
840    ($Matrix:ty) => {
841        impl<Return: MatrixExpression, E: MatrixExpression, E1: VectorExpression> Sub<Return> for $Matrix {
842            type Output = MatrixSub<$Matrix, Return>;
843
844            fn sub(self, rhs: Return) -> Self::Output {
845                return MatrixSub::new(self, rhs);
846            }
847        }
848    }
849}
850impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
851impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
852impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
853impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
854impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
855impl_sub_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
856
857macro_rules! impl_sub_mat1_vec2 {
858    ($Matrix:ty) => {
859        impl<Return: MatrixExpression, E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Sub<Return> for $Matrix {
860            type Output = MatrixSub<$Matrix, Return>;
861
862            fn sub(self, rhs: Return) -> Self::Output {
863                return MatrixSub::new(self, rhs);
864            }
865        }
866    }
867}
868impl_sub_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
869impl_sub_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
870impl_sub_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
871impl_sub_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
872
873macro_rules! impl_sub_mat2 {
874    ($Matrix:ty) => {
875        impl<Return: MatrixExpression, E1: MatrixExpression, E2: MatrixExpression> Sub<Return> for $Matrix {
876            type Output = MatrixSub<$Matrix, Return>;
877
878            fn sub(self, rhs: Return) -> Self::Output {
879                return MatrixSub::new(self, rhs);
880            }
881        }
882    }
883}
884impl_sub_mat2!(MatrixMul<E1, E2>);
885impl_sub_mat2!(MatrixAdd<E1, E2>);
886impl_sub_mat2!(MatrixSub<E1, E2>);
887
888//--------------------------------------------------------------------------------------------------
889/// Returns a - b', where every element of matrix b' is b.
890macro_rules! impl_sub_scalar_mat0 {
891    ($Matrix:ty) => {
892        impl Sub<f64> for $Matrix {
893            type Output = MatrixScalarSub<$Matrix>;
894
895            fn sub(self, rhs: f64) -> Self::Output {
896                return MatrixScalarSub::new(self, rhs);
897            }
898        }
899    }
900}
901impl_sub_scalar_mat0!(MatrixConstant);
902impl_sub_scalar_mat0!(MatrixIdentity);
903
904macro_rules! impl_sub_scalar_mat1 {
905    ($Matrix:ty) => {
906        impl<E: MatrixExpression> Sub<f64> for $Matrix {
907            type Output = MatrixScalarSub<$Matrix>;
908
909            fn sub(self, rhs: f64) -> Self::Output {
910                return MatrixScalarSub::new(self, rhs);
911            }
912        }
913    }
914}
915impl_sub_scalar_mat1!(MatrixDiagonal<E>);
916impl_sub_scalar_mat1!(MatrixTriangular<E>);
917impl_sub_scalar_mat1!(MatrixScalarAdd<E>);
918impl_sub_scalar_mat1!(MatrixScalarSub<E>);
919impl_sub_scalar_mat1!(MatrixScalarRSub<E>);
920impl_sub_scalar_mat1!(MatrixScalarMul<E>);
921impl_sub_scalar_mat1!(MatrixScalarDiv<E>);
922impl_sub_scalar_mat1!(MatrixScalarRDiv<E>);
923
924macro_rules! impl_sub_scalar_mat1_vec1 {
925    ($Matrix:ty) => {
926        impl<E: MatrixExpression, E1: VectorExpression> Sub<f64> for $Matrix {
927            type Output = MatrixScalarSub<$Matrix>;
928
929            fn sub(self, rhs: f64) -> Self::Output {
930                return MatrixScalarSub::new(self, rhs);
931            }
932        }
933    }
934}
935impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
936impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
937impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
938impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
939impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
940impl_sub_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
941
942macro_rules! impl_sub_scalar_mat1_vec2 {
943    ($Matrix:ty) => {
944        impl<E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Sub<f64> for $Matrix {
945            type Output = MatrixScalarSub<$Matrix>;
946
947            fn sub(self, rhs: f64) -> Self::Output {
948                return MatrixScalarSub::new(self, rhs);
949            }
950        }
951    }
952}
953impl_sub_scalar_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
954impl_sub_scalar_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
955impl_sub_scalar_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
956impl_sub_scalar_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
957
958macro_rules! impl_sub_scalar_mat2 {
959    ($Matrix:ty) => {
960        impl<E1: MatrixExpression, E2: MatrixExpression> Sub<f64> for $Matrix {
961            type Output = MatrixScalarSub<$Matrix>;
962
963            fn sub(self, rhs: f64) -> Self::Output {
964                return MatrixScalarSub::new(self, rhs);
965            }
966        }
967    }
968}
969impl_sub_scalar_mat2!(MatrixMul<E1, E2>);
970impl_sub_scalar_mat2!(MatrixAdd<E1, E2>);
971impl_sub_scalar_mat2!(MatrixSub<E1, E2>);
972
973//--------------------------------------------------------------------------------------------------
974/// Returns a * b', where every element of matrix b' is b.
975macro_rules! impl_mul_scalar_mat0 {
976    ($Matrix:ty) => {
977        impl Mul<f64> for $Matrix {
978            type Output = MatrixScalarMul<$Matrix>;
979
980            fn mul(self, rhs: f64) -> Self::Output {
981                return MatrixScalarMul::new(self, rhs);
982            }
983        }
984    }
985}
986impl_mul_scalar_mat0!(MatrixConstant);
987impl_mul_scalar_mat0!(MatrixIdentity);
988
989macro_rules! impl_mul_scalar_mat1 {
990    ($Matrix:ty) => {
991        impl<E: MatrixExpression> Mul<f64> for $Matrix {
992            type Output = MatrixScalarMul<$Matrix>;
993
994            fn mul(self, rhs: f64) -> Self::Output {
995                return MatrixScalarMul::new(self, rhs);
996            }
997        }
998    }
999}
1000impl_mul_scalar_mat1!(MatrixDiagonal<E>);
1001impl_mul_scalar_mat1!(MatrixTriangular<E>);
1002impl_mul_scalar_mat1!(MatrixScalarAdd<E>);
1003impl_mul_scalar_mat1!(MatrixScalarSub<E>);
1004impl_mul_scalar_mat1!(MatrixScalarRSub<E>);
1005impl_mul_scalar_mat1!(MatrixScalarMul<E>);
1006impl_mul_scalar_mat1!(MatrixScalarDiv<E>);
1007impl_mul_scalar_mat1!(MatrixScalarRDiv<E>);
1008
1009macro_rules! impl_mul_scalar_mat1_vec1 {
1010    ($Matrix:ty) => {
1011        impl<E: MatrixExpression, E1: VectorExpression> Mul<f64> for $Matrix {
1012            type Output = MatrixScalarMul<$Matrix>;
1013
1014            fn mul(self, rhs: f64) -> Self::Output {
1015                return MatrixScalarMul::new(self, rhs);
1016            }
1017        }
1018    }
1019}
1020impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
1021impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
1022impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
1023impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
1024impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
1025impl_mul_scalar_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
1026
1027macro_rules! impl_mul_scalar_mat1_vec2 {
1028    ($Matrix:ty) => {
1029        impl<E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Mul<f64> for $Matrix {
1030            type Output = MatrixScalarMul<$Matrix>;
1031
1032            fn mul(self, rhs: f64) -> Self::Output {
1033                return MatrixScalarMul::new(self, rhs);
1034            }
1035        }
1036    }
1037}
1038impl_mul_scalar_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
1039impl_mul_scalar_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
1040impl_mul_scalar_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
1041impl_mul_scalar_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
1042
1043macro_rules! impl_mul_scalar_mat2 {
1044    ($Matrix:ty) => {
1045        impl<E1: MatrixExpression, E2: MatrixExpression> Mul<f64> for $Matrix {
1046            type Output = MatrixScalarMul<$Matrix>;
1047
1048            fn mul(self, rhs: f64) -> Self::Output {
1049                return MatrixScalarMul::new(self, rhs);
1050            }
1051        }
1052    }
1053}
1054impl_mul_scalar_mat2!(MatrixMul<E1, E2>);
1055impl_mul_scalar_mat2!(MatrixAdd<E1, E2>);
1056impl_mul_scalar_mat2!(MatrixSub<E1, E2>);
1057
1058//--------------------------------------------------------------------------------------------------
1059/// Returns a * b.
1060macro_rules! impl_mul_vec_mat0 {
1061    ($Matrix:ty) => {
1062        macro_rules! impl_mul_vec1_mat0 {
1063            ($Vector:ty) => {
1064                impl<E1:VectorExpression> Mul<$Vector> for $Matrix {
1065                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1066
1067                    fn mul(self, rhs: $Vector) -> Self::Output {
1068                        return MatrixVectorMul::new(self, rhs);
1069                    }
1070                }
1071            };
1072        }
1073        impl_mul_vec1_mat0!(VectorScalarAdd<E1>);
1074        impl_mul_vec1_mat0!(VectorScalarSub<E1>);
1075        impl_mul_vec1_mat0!(VectorScalarRSub<E1>);
1076        impl_mul_vec1_mat0!(VectorScalarMul<E1>);
1077        impl_mul_vec1_mat0!(VectorScalarDiv<E1>);
1078        impl_mul_vec1_mat0!(VectorScalarRDiv<E1>);
1079
1080        macro_rules! impl_mul_vec2_mat0 {
1081            ($Vector:ty) => {
1082                impl<E1:VectorExpression, E2:VectorExpression> Mul<$Vector> for $Matrix {
1083                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1084
1085                    fn mul(self, rhs: $Vector) -> Self::Output {
1086                        return MatrixVectorMul::new(self, rhs);
1087                    }
1088                }
1089            };
1090        }
1091        impl_mul_vec2_mat0!(VectorAdd<E1, E2>);
1092        impl_mul_vec2_mat0!(VectorSub<E1, E2>);
1093        impl_mul_vec2_mat0!(VectorMul<E1, E2>);
1094        impl_mul_vec2_mat0!(VectorDiv<E1, E2>);
1095    }
1096}
1097impl_mul_vec_mat0!(MatrixConstant);
1098impl_mul_vec_mat0!(MatrixIdentity);
1099
1100macro_rules! impl_mul_vec_mat1 {
1101    ($Matrix:ty) => {
1102        macro_rules! impl_mul_vec1_mat0 {
1103            ($Vector:ty) => {
1104                impl<E1:VectorExpression, E: MatrixExpression> Mul<$Vector> for $Matrix {
1105                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1106
1107                    fn mul(self, rhs: $Vector) -> Self::Output {
1108                        return MatrixVectorMul::new(self, rhs);
1109                    }
1110                }
1111            };
1112        }
1113        impl_mul_vec1_mat0!(VectorScalarAdd<E1>);
1114        impl_mul_vec1_mat0!(VectorScalarSub<E1>);
1115        impl_mul_vec1_mat0!(VectorScalarRSub<E1>);
1116        impl_mul_vec1_mat0!(VectorScalarMul<E1>);
1117        impl_mul_vec1_mat0!(VectorScalarDiv<E1>);
1118        impl_mul_vec1_mat0!(VectorScalarRDiv<E1>);
1119
1120        macro_rules! impl_mul_vec2_mat0 {
1121            ($Vector:ty) => {
1122                impl<E1:VectorExpression, E2:VectorExpression, E: MatrixExpression> Mul<$Vector> for $Matrix {
1123                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1124
1125                    fn mul(self, rhs: $Vector) -> Self::Output {
1126                        return MatrixVectorMul::new(self, rhs);
1127                    }
1128                }
1129            };
1130        }
1131        impl_mul_vec2_mat0!(VectorAdd<E1, E2>);
1132        impl_mul_vec2_mat0!(VectorSub<E1, E2>);
1133        impl_mul_vec2_mat0!(VectorMul<E1, E2>);
1134        impl_mul_vec2_mat0!(VectorDiv<E1, E2>);
1135    }
1136}
1137impl_mul_vec_mat1!(MatrixDiagonal<E>);
1138impl_mul_vec_mat1!(MatrixTriangular<E>);
1139impl_mul_vec_mat1!(MatrixScalarAdd<E>);
1140impl_mul_vec_mat1!(MatrixScalarSub<E>);
1141impl_mul_vec_mat1!(MatrixScalarRSub<E>);
1142impl_mul_vec_mat1!(MatrixScalarMul<E>);
1143impl_mul_vec_mat1!(MatrixScalarDiv<E>);
1144impl_mul_vec_mat1!(MatrixScalarRDiv<E>);
1145
1146macro_rules! impl_mul_vec_mat1_vec1 {
1147    ($Matrix:ty) => {
1148        macro_rules! impl_mul_vec1_mat0 {
1149            ($Vector:ty) => {
1150                impl<E1:VectorExpression, E: MatrixExpression, V1: VectorExpression> Mul<$Vector> for $Matrix {
1151                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1152
1153                    fn mul(self, rhs: $Vector) -> Self::Output {
1154                        return MatrixVectorMul::new(self, rhs);
1155                    }
1156                }
1157            };
1158        }
1159        impl_mul_vec1_mat0!(VectorScalarAdd<E1>);
1160        impl_mul_vec1_mat0!(VectorScalarSub<E1>);
1161        impl_mul_vec1_mat0!(VectorScalarRSub<E1>);
1162        impl_mul_vec1_mat0!(VectorScalarMul<E1>);
1163        impl_mul_vec1_mat0!(VectorScalarDiv<E1>);
1164        impl_mul_vec1_mat0!(VectorScalarRDiv<E1>);
1165
1166        macro_rules! impl_mul_vec2_mat0 {
1167            ($Vector:ty) => {
1168                impl<E1:VectorExpression, E2:VectorExpression, E: MatrixExpression, V1: VectorExpression> Mul<$Vector> for $Matrix {
1169                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1170
1171                    fn mul(self, rhs: $Vector) -> Self::Output {
1172                        return MatrixVectorMul::new(self, rhs);
1173                    }
1174                }
1175            };
1176        }
1177        impl_mul_vec2_mat0!(VectorAdd<E1, E2>);
1178        impl_mul_vec2_mat0!(VectorSub<E1, E2>);
1179        impl_mul_vec2_mat0!(VectorMul<E1, E2>);
1180        impl_mul_vec2_mat0!(VectorDiv<E1, E2>);
1181    }
1182}
1183impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<V1>>);
1184impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<V1>>);
1185impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<V1>>);
1186impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<V1>>);
1187impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<V1>>);
1188impl_mul_vec_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<V1>>);
1189
1190macro_rules! impl_mul_vec_mat1_vec2 {
1191    ($Matrix:ty) => {
1192        macro_rules! impl_mul_vec1_mat0 {
1193            ($Vector:ty) => {
1194                impl<E1:VectorExpression, E: MatrixExpression, V1: VectorExpression, V2: VectorExpression> Mul<$Vector> for $Matrix {
1195                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1196
1197                    fn mul(self, rhs: $Vector) -> Self::Output {
1198                        return MatrixVectorMul::new(self, rhs);
1199                    }
1200                }
1201            };
1202        }
1203        impl_mul_vec1_mat0!(VectorScalarAdd<E1>);
1204        impl_mul_vec1_mat0!(VectorScalarSub<E1>);
1205        impl_mul_vec1_mat0!(VectorScalarRSub<E1>);
1206        impl_mul_vec1_mat0!(VectorScalarMul<E1>);
1207        impl_mul_vec1_mat0!(VectorScalarDiv<E1>);
1208        impl_mul_vec1_mat0!(VectorScalarRDiv<E1>);
1209
1210        macro_rules! impl_mul_vec2_mat0 {
1211            ($Vector:ty) => {
1212                impl<E1:VectorExpression, E2:VectorExpression, E: MatrixExpression, V1: VectorExpression, V2: VectorExpression> Mul<$Vector> for $Matrix {
1213                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1214
1215                    fn mul(self, rhs: $Vector) -> Self::Output {
1216                        return MatrixVectorMul::new(self, rhs);
1217                    }
1218                }
1219            };
1220        }
1221        impl_mul_vec2_mat0!(VectorAdd<E1, E2>);
1222        impl_mul_vec2_mat0!(VectorSub<E1, E2>);
1223        impl_mul_vec2_mat0!(VectorMul<E1, E2>);
1224        impl_mul_vec2_mat0!(VectorDiv<E1, E2>);
1225    }
1226}
1227impl_mul_vec_mat1_vec2!(MatrixVectorMul<E, VectorAdd<V1, V2>>);
1228impl_mul_vec_mat1_vec2!(MatrixVectorMul<E, VectorSub<V1, V2>>);
1229impl_mul_vec_mat1_vec2!(MatrixVectorMul<E, VectorMul<V1, V2>>);
1230impl_mul_vec_mat1_vec2!(MatrixVectorMul<E, VectorDiv<V1, V2>>);
1231
1232macro_rules! impl_mul_vec_mat2 {
1233    ($Matrix:ty) => {
1234        macro_rules! impl_mul_vec1_mat0 {
1235            ($Vector:ty) => {
1236                impl<E1:VectorExpression, V1: MatrixExpression, V2: MatrixExpression> Mul<$Vector> for $Matrix {
1237                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1238
1239                    fn mul(self, rhs: $Vector) -> Self::Output {
1240                        return MatrixVectorMul::new(self, rhs);
1241                    }
1242                }
1243            };
1244        }
1245        impl_mul_vec1_mat0!(VectorScalarAdd<E1>);
1246        impl_mul_vec1_mat0!(VectorScalarSub<E1>);
1247        impl_mul_vec1_mat0!(VectorScalarRSub<E1>);
1248        impl_mul_vec1_mat0!(VectorScalarMul<E1>);
1249        impl_mul_vec1_mat0!(VectorScalarDiv<E1>);
1250        impl_mul_vec1_mat0!(VectorScalarRDiv<E1>);
1251
1252        macro_rules! impl_mul_vec2_mat0 {
1253            ($Vector:ty) => {
1254                impl<E1:VectorExpression, E2:VectorExpression, V1: MatrixExpression, V2: MatrixExpression> Mul<$Vector> for $Matrix {
1255                    type Output = MatrixVectorMul<$Matrix, $Vector>;
1256
1257                    fn mul(self, rhs: $Vector) -> Self::Output {
1258                        return MatrixVectorMul::new(self, rhs);
1259                    }
1260                }
1261            };
1262        }
1263        impl_mul_vec2_mat0!(VectorAdd<E1, E2>);
1264        impl_mul_vec2_mat0!(VectorSub<E1, E2>);
1265        impl_mul_vec2_mat0!(VectorMul<E1, E2>);
1266        impl_mul_vec2_mat0!(VectorDiv<E1, E2>);
1267    }
1268}
1269impl_mul_vec_mat2!(MatrixMul<V1, V2>);
1270impl_mul_vec_mat2!(MatrixAdd<V1, V2>);
1271impl_mul_vec_mat2!(MatrixSub<V1, V2>);
1272
1273//--------------------------------------------------------------------------------------------------
1274/// Returns a * b.
1275macro_rules! impl_mul_mat0 {
1276    ($Matrix:ty) => {
1277        impl<Matrix: MatrixExpression> Mul<Matrix> for $Matrix {
1278            type Output = MatrixMul<$Matrix, Matrix>;
1279
1280            fn mul(self, rhs: Matrix) -> Self::Output {
1281                return MatrixMul::new(self, rhs);
1282            }
1283        }
1284    }
1285}
1286impl_mul_mat0!(MatrixConstant);
1287impl_mul_mat0!(MatrixIdentity);
1288
1289macro_rules! impl_mul_mat1 {
1290    ($Matrix:ty) => {
1291        impl<Matrix: MatrixExpression, E: MatrixExpression> Mul<Matrix> for $Matrix {
1292            type Output = MatrixMul<$Matrix, Matrix>;
1293
1294            fn mul(self, rhs: Matrix) -> Self::Output {
1295                return MatrixMul::new(self, rhs);
1296            }
1297        }
1298    }
1299}
1300impl_mul_mat1!(MatrixDiagonal<E>);
1301impl_mul_mat1!(MatrixTriangular<E>);
1302impl_mul_mat1!(MatrixScalarAdd<E>);
1303impl_mul_mat1!(MatrixScalarSub<E>);
1304impl_mul_mat1!(MatrixScalarRSub<E>);
1305impl_mul_mat1!(MatrixScalarMul<E>);
1306impl_mul_mat1!(MatrixScalarDiv<E>);
1307impl_mul_mat1!(MatrixScalarRDiv<E>);
1308
1309macro_rules! impl_mul_mat1_vec1 {
1310    ($Matrix:ty) => {
1311        impl<Matrix: MatrixExpression, E: MatrixExpression, E1: VectorExpression> Mul<Matrix> for $Matrix {
1312            type Output = MatrixMul<$Matrix, Matrix>;
1313
1314            fn mul(self, rhs: Matrix) -> Self::Output {
1315                return MatrixMul::new(self, rhs);
1316            }
1317        }
1318    }
1319}
1320impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
1321impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
1322impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
1323impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
1324impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
1325impl_mul_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
1326
1327macro_rules! impl_mul_mat1_vec2 {
1328    ($Matrix:ty) => {
1329        impl<Matrix: MatrixExpression, E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Mul<Matrix> for $Matrix {
1330            type Output = MatrixMul<$Matrix, Matrix>;
1331
1332            fn mul(self, rhs: Matrix) -> Self::Output {
1333                return MatrixMul::new(self, rhs);
1334            }
1335        }
1336    }
1337}
1338impl_mul_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
1339impl_mul_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
1340impl_mul_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
1341impl_mul_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
1342
1343macro_rules! impl_mul_mat2 {
1344    ($Matrix:ty) => {
1345        impl<Matrix: MatrixExpression, E1: MatrixExpression, E2: MatrixExpression> Mul<Matrix> for $Matrix {
1346            type Output = MatrixMul<$Matrix, Matrix>;
1347
1348            fn mul(self, rhs: Matrix) -> Self::Output {
1349                return MatrixMul::new(self, rhs);
1350            }
1351        }
1352    }
1353}
1354impl_mul_mat2!(MatrixMul<E1, E2>);
1355impl_mul_mat2!(MatrixAdd<E1, E2>);
1356impl_mul_mat2!(MatrixSub<E1, E2>);
1357
1358//--------------------------------------------------------------------------------------------------
1359/// Returns a' / b, where every element of matrix a' is a.
1360macro_rules! impl_div_mat0 {
1361    ($Matrix:ty) => {
1362        impl Div<f64> for $Matrix {
1363            type Output = MatrixScalarDiv<$Matrix>;
1364
1365            fn div(self, rhs: f64) -> Self::Output {
1366                return MatrixScalarDiv::new(self, rhs);
1367            }
1368        }
1369    }
1370}
1371
1372impl_div_mat0!(MatrixConstant);
1373impl_div_mat0!(MatrixIdentity);
1374
1375macro_rules! impl_div_mat1 {
1376    ($Matrix:ty) => {
1377        impl<E: MatrixExpression> Div<f64> for $Matrix {
1378            type Output = MatrixScalarDiv<$Matrix>;
1379
1380            fn div(self, rhs: f64) -> Self::Output {
1381                return MatrixScalarDiv::new(self, rhs);
1382            }
1383        }
1384    }
1385}
1386impl_div_mat1!(MatrixDiagonal<E>);
1387impl_div_mat1!(MatrixTriangular<E>);
1388impl_div_mat1!(MatrixScalarAdd<E>);
1389impl_div_mat1!(MatrixScalarSub<E>);
1390impl_div_mat1!(MatrixScalarRSub<E>);
1391impl_div_mat1!(MatrixScalarMul<E>);
1392impl_div_mat1!(MatrixScalarDiv<E>);
1393impl_div_mat1!(MatrixScalarRDiv<E>);
1394
1395macro_rules! impl_div_mat1_vec1 {
1396    ($Matrix:ty) => {
1397        impl<E: MatrixExpression, E1: VectorExpression> Div<f64> for $Matrix {
1398            type Output = MatrixScalarDiv<$Matrix>;
1399
1400            fn div(self, rhs: f64) -> Self::Output {
1401                return MatrixScalarDiv::new(self, rhs);
1402            }
1403        }
1404    }
1405}
1406impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarAdd<E1>>);
1407impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarSub<E1>>);
1408impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarRSub<E1>>);
1409impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarMul<E1>>);
1410impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarDiv<E1>>);
1411impl_div_mat1_vec1!(MatrixVectorMul<E, VectorScalarRDiv<E1>>);
1412
1413macro_rules! impl_div_mat1_vec2 {
1414    ($Matrix:ty) => {
1415        impl<E: MatrixExpression, E1: VectorExpression, E2: VectorExpression> Div<f64> for $Matrix {
1416            type Output = MatrixScalarDiv<$Matrix>;
1417
1418            fn div(self, rhs: f64) -> Self::Output {
1419                return MatrixScalarDiv::new(self, rhs);
1420            }
1421        }
1422    }
1423}
1424impl_div_mat1_vec2!(MatrixVectorMul<E, VectorAdd<E1, E2>>);
1425impl_div_mat1_vec2!(MatrixVectorMul<E, VectorSub<E1, E2>>);
1426impl_div_mat1_vec2!(MatrixVectorMul<E, VectorMul<E1, E2>>);
1427impl_div_mat1_vec2!(MatrixVectorMul<E, VectorDiv<E1, E2>>);
1428
1429macro_rules! impl_div_mat2 {
1430    ($Matrix:ty) => {
1431        impl<E1: MatrixExpression, E2: MatrixExpression> Div<f64> for $Matrix {
1432            type Output = MatrixScalarDiv<$Matrix>;
1433
1434            fn div(self, rhs: f64) -> Self::Output {
1435                return MatrixScalarDiv::new(self, rhs);
1436            }
1437        }
1438    }
1439}
1440impl_div_mat2!(MatrixMul<E1, E2>);
1441impl_div_mat2!(MatrixAdd<E1, E2>);
1442impl_div_mat2!(MatrixSub<E1, E2>);