static_math/
matrix6x6.rs

1//-------------------------------------------------------------------------
2// @file matrix6x6.rs
3//
4// @date 06/02/20 20:59:42
5// @author Martin Noblia
6// @email mnoblia@disroot.org
7//
8// @brief
9//
10// @detail
11//
12// Licence MIT:
13// Copyright <2020> <Martin Noblia>
14//
15// Permission is hereby granted, free of charge, to any person obtaining a copy
16// of this software and associated documentation files (the "Software"), to deal
17// in the Software without restriction, including without limitation the rights
18// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19// copies of the Software, and to permit persons to whom the Software is
20// furnished to do so, subject to the following conditions:
21//
22// The above copyright notice and this permission notice shall be included in
23// all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED
24// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30//-------------------------------------------------------------------------
31use core::fmt;
32use core::ops::{Add, Mul, Div, Sub, AddAssign, SubAssign, Neg};
33use core::ops::{Deref, DerefMut, Index, IndexMut};
34
35use num::{Float, Num, One, Zero, Signed};
36
37use crate::slices_methods::*;
38use crate::matrix5x5::M55;
39use crate::vector6::V6;
40use crate::matrix3x3::M33;
41use crate::traits::LinearAlgebra;
42use crate::utils::nearly_zero;
43//-------------------------------------------------------------------------
44//                        code
45//-------------------------------------------------------------------------
46/// A static Matrix of 6x6 shape
47#[derive(Copy, Clone, Debug, PartialEq)]
48pub struct M66<T>([[T; 6]; 6]);
49
50impl<T> M66<T> {
51    pub fn new(data_input: [[T; 6]; 6]) -> Self {
52        Self(data_input)
53    }
54    pub fn rows(&self) -> usize {
55        self.0.len()
56    }
57    pub fn cols(&self) -> usize {
58        self.rows()
59    }
60}
61
62
63impl<T: Float + core::iter::Sum> LinearAlgebra<T> for M66<T> {
64    #[inline]
65    fn rows(&self) -> usize {
66        self.0.len()
67    }
68
69    #[inline]
70    fn cols(&self) -> usize {
71        self.rows()
72    }
73
74    #[inline]
75    fn transpose(&self) -> Self {
76        let a_00 = self[(0, 0)];
77        let a_01 = self[(0, 1)];
78        let a_02 = self[(0, 2)];
79        let a_03 = self[(0, 3)];
80        let a_04 = self[(0, 4)];
81        let a_05 = self[(0, 5)];
82        let a_10 = self[(1, 0)];
83        let a_11 = self[(1, 1)];
84        let a_12 = self[(1, 2)];
85        let a_13 = self[(1, 3)];
86        let a_14 = self[(1, 4)];
87        let a_15 = self[(1, 5)];
88        let a_20 = self[(2, 0)];
89        let a_21 = self[(2, 1)];
90        let a_22 = self[(2, 2)];
91        let a_23 = self[(2, 3)];
92        let a_24 = self[(2, 4)];
93        let a_25 = self[(2, 5)];
94        let a_30 = self[(3, 0)];
95        let a_31 = self[(3, 1)];
96        let a_32 = self[(3, 2)];
97        let a_33 = self[(3, 3)];
98        let a_34 = self[(3, 4)];
99        let a_35 = self[(3, 5)];
100        let a_40 = self[(4, 0)];
101        let a_41 = self[(4, 1)];
102        let a_42 = self[(4, 2)];
103        let a_43 = self[(4, 3)];
104        let a_44 = self[(4, 4)];
105        let a_45 = self[(4, 5)];
106        let a_50 = self[(5, 0)];
107        let a_51 = self[(5, 1)];
108        let a_52 = self[(5, 2)];
109        let a_53 = self[(5, 3)];
110        let a_54 = self[(5, 4)];
111        let a_55 = self[(5, 5)];
112
113        M66::new([
114            [a_00, a_10, a_20, a_30, a_40, a_50],
115            [a_01, a_11, a_21, a_31, a_41, a_51],
116            [a_02, a_12, a_22, a_32, a_42, a_52],
117            [a_03, a_13, a_23, a_33, a_43, a_53],
118            [a_04, a_14, a_24, a_34, a_44, a_54],
119            [a_05, a_15, a_25, a_35, a_45, a_55],
120        ])
121    }
122
123    #[inline(always)]
124    fn trace(&self) -> T {
125           self[(0, 0)] + self[(1, 1)] + self[(2, 2)] + self[(3, 3)] + self[(4, 4)] + self[(5, 5)]
126    }
127
128    fn norm2(&self) -> T {
129        T::sqrt(
130            self.iter()
131                .flatten()
132                .cloned()
133                .map(|element| element * element)
134                .sum(),
135        )
136    }
137
138    #[inline(always)]
139    fn det(&self) -> T {
140        let a_00 = self[(0, 0)];
141        let a_01 = self[(0, 1)];
142        let a_02 = self[(0, 2)];
143        let a_03 = self[(0, 3)];
144        let a_04 = self[(0, 4)];
145        let a_05 = self[(0, 5)];
146        let a_10 = self[(1, 0)];
147        let a_11 = self[(1, 1)];
148        let a_12 = self[(1, 2)];
149        let a_13 = self[(1, 3)];
150        let a_14 = self[(1, 4)];
151        let a_15 = self[(1, 5)];
152        let a_20 = self[(2, 0)];
153        let a_21 = self[(2, 1)];
154        let a_22 = self[(2, 2)];
155        let a_23 = self[(2, 3)];
156        let a_24 = self[(2, 4)];
157        let a_25 = self[(2, 5)];
158        let a_30 = self[(3, 0)];
159        let a_31 = self[(3, 1)];
160        let a_32 = self[(3, 2)];
161        let a_33 = self[(3, 3)];
162        let a_34 = self[(3, 4)];
163        let a_35 = self[(3, 5)];
164        let a_40 = self[(4, 0)];
165        let a_41 = self[(4, 1)];
166        let a_42 = self[(4, 2)];
167        let a_43 = self[(4, 3)];
168        let a_44 = self[(4, 4)];
169        let a_45 = self[(4, 5)];
170        let a_50 = self[(5, 0)];
171        let a_51 = self[(5, 1)];
172        let a_52 = self[(5, 2)];
173        let a_53 = self[(5, 3)];
174        let a_54 = self[(5, 4)];
175        let a_55 = self[(5, 5)];
176
177        a_00 * a_11 * a_22 * a_33 * a_44 * a_55
178            - a_00 * a_11 * a_22 * a_33 * a_45 * a_54
179            - a_00 * a_11 * a_22 * a_34 * a_43 * a_55
180            + a_00 * a_11 * a_22 * a_34 * a_45 * a_53
181            + a_00 * a_11 * a_22 * a_35 * a_43 * a_54
182            - a_00 * a_11 * a_22 * a_35 * a_44 * a_53
183            - a_00 * a_11 * a_23 * a_32 * a_44 * a_55
184            + a_00 * a_11 * a_23 * a_32 * a_45 * a_54
185            + a_00 * a_11 * a_23 * a_34 * a_42 * a_55
186            - a_00 * a_11 * a_23 * a_34 * a_45 * a_52
187            - a_00 * a_11 * a_23 * a_35 * a_42 * a_54
188            + a_00 * a_11 * a_23 * a_35 * a_44 * a_52
189            + a_00 * a_11 * a_24 * a_32 * a_43 * a_55
190            - a_00 * a_11 * a_24 * a_32 * a_45 * a_53
191            - a_00 * a_11 * a_24 * a_33 * a_42 * a_55
192            + a_00 * a_11 * a_24 * a_33 * a_45 * a_52
193            + a_00 * a_11 * a_24 * a_35 * a_42 * a_53
194            - a_00 * a_11 * a_24 * a_35 * a_43 * a_52
195            - a_00 * a_11 * a_25 * a_32 * a_43 * a_54
196            + a_00 * a_11 * a_25 * a_32 * a_44 * a_53
197            + a_00 * a_11 * a_25 * a_33 * a_42 * a_54
198            - a_00 * a_11 * a_25 * a_33 * a_44 * a_52
199            - a_00 * a_11 * a_25 * a_34 * a_42 * a_53
200            + a_00 * a_11 * a_25 * a_34 * a_43 * a_52
201            - a_00 * a_12 * a_21 * a_33 * a_44 * a_55
202            + a_00 * a_12 * a_21 * a_33 * a_45 * a_54
203            + a_00 * a_12 * a_21 * a_34 * a_43 * a_55
204            - a_00 * a_12 * a_21 * a_34 * a_45 * a_53
205            - a_00 * a_12 * a_21 * a_35 * a_43 * a_54
206            + a_00 * a_12 * a_21 * a_35 * a_44 * a_53
207            + a_00 * a_12 * a_23 * a_31 * a_44 * a_55
208            - a_00 * a_12 * a_23 * a_31 * a_45 * a_54
209            - a_00 * a_12 * a_23 * a_34 * a_41 * a_55
210            + a_00 * a_12 * a_23 * a_34 * a_45 * a_51
211            + a_00 * a_12 * a_23 * a_35 * a_41 * a_54
212            - a_00 * a_12 * a_23 * a_35 * a_44 * a_51
213            - a_00 * a_12 * a_24 * a_31 * a_43 * a_55
214            + a_00 * a_12 * a_24 * a_31 * a_45 * a_53
215            + a_00 * a_12 * a_24 * a_33 * a_41 * a_55
216            - a_00 * a_12 * a_24 * a_33 * a_45 * a_51
217            - a_00 * a_12 * a_24 * a_35 * a_41 * a_53
218            + a_00 * a_12 * a_24 * a_35 * a_43 * a_51
219            + a_00 * a_12 * a_25 * a_31 * a_43 * a_54
220            - a_00 * a_12 * a_25 * a_31 * a_44 * a_53
221            - a_00 * a_12 * a_25 * a_33 * a_41 * a_54
222            + a_00 * a_12 * a_25 * a_33 * a_44 * a_51
223            + a_00 * a_12 * a_25 * a_34 * a_41 * a_53
224            - a_00 * a_12 * a_25 * a_34 * a_43 * a_51
225            + a_00 * a_13 * a_21 * a_32 * a_44 * a_55
226            - a_00 * a_13 * a_21 * a_32 * a_45 * a_54
227            - a_00 * a_13 * a_21 * a_34 * a_42 * a_55
228            + a_00 * a_13 * a_21 * a_34 * a_45 * a_52
229            + a_00 * a_13 * a_21 * a_35 * a_42 * a_54
230            - a_00 * a_13 * a_21 * a_35 * a_44 * a_52
231            - a_00 * a_13 * a_22 * a_31 * a_44 * a_55
232            + a_00 * a_13 * a_22 * a_31 * a_45 * a_54
233            + a_00 * a_13 * a_22 * a_34 * a_41 * a_55
234            - a_00 * a_13 * a_22 * a_34 * a_45 * a_51
235            - a_00 * a_13 * a_22 * a_35 * a_41 * a_54
236            + a_00 * a_13 * a_22 * a_35 * a_44 * a_51
237            + a_00 * a_13 * a_24 * a_31 * a_42 * a_55
238            - a_00 * a_13 * a_24 * a_31 * a_45 * a_52
239            - a_00 * a_13 * a_24 * a_32 * a_41 * a_55
240            + a_00 * a_13 * a_24 * a_32 * a_45 * a_51
241            + a_00 * a_13 * a_24 * a_35 * a_41 * a_52
242            - a_00 * a_13 * a_24 * a_35 * a_42 * a_51
243            - a_00 * a_13 * a_25 * a_31 * a_42 * a_54
244            + a_00 * a_13 * a_25 * a_31 * a_44 * a_52
245            + a_00 * a_13 * a_25 * a_32 * a_41 * a_54
246            - a_00 * a_13 * a_25 * a_32 * a_44 * a_51
247            - a_00 * a_13 * a_25 * a_34 * a_41 * a_52
248            + a_00 * a_13 * a_25 * a_34 * a_42 * a_51
249            - a_00 * a_14 * a_21 * a_32 * a_43 * a_55
250            + a_00 * a_14 * a_21 * a_32 * a_45 * a_53
251            + a_00 * a_14 * a_21 * a_33 * a_42 * a_55
252            - a_00 * a_14 * a_21 * a_33 * a_45 * a_52
253            - a_00 * a_14 * a_21 * a_35 * a_42 * a_53
254            + a_00 * a_14 * a_21 * a_35 * a_43 * a_52
255            + a_00 * a_14 * a_22 * a_31 * a_43 * a_55
256            - a_00 * a_14 * a_22 * a_31 * a_45 * a_53
257            - a_00 * a_14 * a_22 * a_33 * a_41 * a_55
258            + a_00 * a_14 * a_22 * a_33 * a_45 * a_51
259            + a_00 * a_14 * a_22 * a_35 * a_41 * a_53
260            - a_00 * a_14 * a_22 * a_35 * a_43 * a_51
261            - a_00 * a_14 * a_23 * a_31 * a_42 * a_55
262            + a_00 * a_14 * a_23 * a_31 * a_45 * a_52
263            + a_00 * a_14 * a_23 * a_32 * a_41 * a_55
264            - a_00 * a_14 * a_23 * a_32 * a_45 * a_51
265            - a_00 * a_14 * a_23 * a_35 * a_41 * a_52
266            + a_00 * a_14 * a_23 * a_35 * a_42 * a_51
267            + a_00 * a_14 * a_25 * a_31 * a_42 * a_53
268            - a_00 * a_14 * a_25 * a_31 * a_43 * a_52
269            - a_00 * a_14 * a_25 * a_32 * a_41 * a_53
270            + a_00 * a_14 * a_25 * a_32 * a_43 * a_51
271            + a_00 * a_14 * a_25 * a_33 * a_41 * a_52
272            - a_00 * a_14 * a_25 * a_33 * a_42 * a_51
273            + a_00 * a_15 * a_21 * a_32 * a_43 * a_54
274            - a_00 * a_15 * a_21 * a_32 * a_44 * a_53
275            - a_00 * a_15 * a_21 * a_33 * a_42 * a_54
276            + a_00 * a_15 * a_21 * a_33 * a_44 * a_52
277            + a_00 * a_15 * a_21 * a_34 * a_42 * a_53
278            - a_00 * a_15 * a_21 * a_34 * a_43 * a_52
279            - a_00 * a_15 * a_22 * a_31 * a_43 * a_54
280            + a_00 * a_15 * a_22 * a_31 * a_44 * a_53
281            + a_00 * a_15 * a_22 * a_33 * a_41 * a_54
282            - a_00 * a_15 * a_22 * a_33 * a_44 * a_51
283            - a_00 * a_15 * a_22 * a_34 * a_41 * a_53
284            + a_00 * a_15 * a_22 * a_34 * a_43 * a_51
285            + a_00 * a_15 * a_23 * a_31 * a_42 * a_54
286            - a_00 * a_15 * a_23 * a_31 * a_44 * a_52
287            - a_00 * a_15 * a_23 * a_32 * a_41 * a_54
288            + a_00 * a_15 * a_23 * a_32 * a_44 * a_51
289            + a_00 * a_15 * a_23 * a_34 * a_41 * a_52
290            - a_00 * a_15 * a_23 * a_34 * a_42 * a_51
291            - a_00 * a_15 * a_24 * a_31 * a_42 * a_53
292            + a_00 * a_15 * a_24 * a_31 * a_43 * a_52
293            + a_00 * a_15 * a_24 * a_32 * a_41 * a_53
294            - a_00 * a_15 * a_24 * a_32 * a_43 * a_51
295            - a_00 * a_15 * a_24 * a_33 * a_41 * a_52
296            + a_00 * a_15 * a_24 * a_33 * a_42 * a_51
297            - a_01 * a_10 * a_22 * a_33 * a_44 * a_55
298            + a_01 * a_10 * a_22 * a_33 * a_45 * a_54
299            + a_01 * a_10 * a_22 * a_34 * a_43 * a_55
300            - a_01 * a_10 * a_22 * a_34 * a_45 * a_53
301            - a_01 * a_10 * a_22 * a_35 * a_43 * a_54
302            + a_01 * a_10 * a_22 * a_35 * a_44 * a_53
303            + a_01 * a_10 * a_23 * a_32 * a_44 * a_55
304            - a_01 * a_10 * a_23 * a_32 * a_45 * a_54
305            - a_01 * a_10 * a_23 * a_34 * a_42 * a_55
306            + a_01 * a_10 * a_23 * a_34 * a_45 * a_52
307            + a_01 * a_10 * a_23 * a_35 * a_42 * a_54
308            - a_01 * a_10 * a_23 * a_35 * a_44 * a_52
309            - a_01 * a_10 * a_24 * a_32 * a_43 * a_55
310            + a_01 * a_10 * a_24 * a_32 * a_45 * a_53
311            + a_01 * a_10 * a_24 * a_33 * a_42 * a_55
312            - a_01 * a_10 * a_24 * a_33 * a_45 * a_52
313            - a_01 * a_10 * a_24 * a_35 * a_42 * a_53
314            + a_01 * a_10 * a_24 * a_35 * a_43 * a_52
315            + a_01 * a_10 * a_25 * a_32 * a_43 * a_54
316            - a_01 * a_10 * a_25 * a_32 * a_44 * a_53
317            - a_01 * a_10 * a_25 * a_33 * a_42 * a_54
318            + a_01 * a_10 * a_25 * a_33 * a_44 * a_52
319            + a_01 * a_10 * a_25 * a_34 * a_42 * a_53
320            - a_01 * a_10 * a_25 * a_34 * a_43 * a_52
321            + a_01 * a_12 * a_20 * a_33 * a_44 * a_55
322            - a_01 * a_12 * a_20 * a_33 * a_45 * a_54
323            - a_01 * a_12 * a_20 * a_34 * a_43 * a_55
324            + a_01 * a_12 * a_20 * a_34 * a_45 * a_53
325            + a_01 * a_12 * a_20 * a_35 * a_43 * a_54
326            - a_01 * a_12 * a_20 * a_35 * a_44 * a_53
327            - a_01 * a_12 * a_23 * a_30 * a_44 * a_55
328            + a_01 * a_12 * a_23 * a_30 * a_45 * a_54
329            + a_01 * a_12 * a_23 * a_34 * a_40 * a_55
330            - a_01 * a_12 * a_23 * a_34 * a_45 * a_50
331            - a_01 * a_12 * a_23 * a_35 * a_40 * a_54
332            + a_01 * a_12 * a_23 * a_35 * a_44 * a_50
333            + a_01 * a_12 * a_24 * a_30 * a_43 * a_55
334            - a_01 * a_12 * a_24 * a_30 * a_45 * a_53
335            - a_01 * a_12 * a_24 * a_33 * a_40 * a_55
336            + a_01 * a_12 * a_24 * a_33 * a_45 * a_50
337            + a_01 * a_12 * a_24 * a_35 * a_40 * a_53
338            - a_01 * a_12 * a_24 * a_35 * a_43 * a_50
339            - a_01 * a_12 * a_25 * a_30 * a_43 * a_54
340            + a_01 * a_12 * a_25 * a_30 * a_44 * a_53
341            + a_01 * a_12 * a_25 * a_33 * a_40 * a_54
342            - a_01 * a_12 * a_25 * a_33 * a_44 * a_50
343            - a_01 * a_12 * a_25 * a_34 * a_40 * a_53
344            + a_01 * a_12 * a_25 * a_34 * a_43 * a_50
345            - a_01 * a_13 * a_20 * a_32 * a_44 * a_55
346            + a_01 * a_13 * a_20 * a_32 * a_45 * a_54
347            + a_01 * a_13 * a_20 * a_34 * a_42 * a_55
348            - a_01 * a_13 * a_20 * a_34 * a_45 * a_52
349            - a_01 * a_13 * a_20 * a_35 * a_42 * a_54
350            + a_01 * a_13 * a_20 * a_35 * a_44 * a_52
351            + a_01 * a_13 * a_22 * a_30 * a_44 * a_55
352            - a_01 * a_13 * a_22 * a_30 * a_45 * a_54
353            - a_01 * a_13 * a_22 * a_34 * a_40 * a_55
354            + a_01 * a_13 * a_22 * a_34 * a_45 * a_50
355            + a_01 * a_13 * a_22 * a_35 * a_40 * a_54
356            - a_01 * a_13 * a_22 * a_35 * a_44 * a_50
357            - a_01 * a_13 * a_24 * a_30 * a_42 * a_55
358            + a_01 * a_13 * a_24 * a_30 * a_45 * a_52
359            + a_01 * a_13 * a_24 * a_32 * a_40 * a_55
360            - a_01 * a_13 * a_24 * a_32 * a_45 * a_50
361            - a_01 * a_13 * a_24 * a_35 * a_40 * a_52
362            + a_01 * a_13 * a_24 * a_35 * a_42 * a_50
363            + a_01 * a_13 * a_25 * a_30 * a_42 * a_54
364            - a_01 * a_13 * a_25 * a_30 * a_44 * a_52
365            - a_01 * a_13 * a_25 * a_32 * a_40 * a_54
366            + a_01 * a_13 * a_25 * a_32 * a_44 * a_50
367            + a_01 * a_13 * a_25 * a_34 * a_40 * a_52
368            - a_01 * a_13 * a_25 * a_34 * a_42 * a_50
369            + a_01 * a_14 * a_20 * a_32 * a_43 * a_55
370            - a_01 * a_14 * a_20 * a_32 * a_45 * a_53
371            - a_01 * a_14 * a_20 * a_33 * a_42 * a_55
372            + a_01 * a_14 * a_20 * a_33 * a_45 * a_52
373            + a_01 * a_14 * a_20 * a_35 * a_42 * a_53
374            - a_01 * a_14 * a_20 * a_35 * a_43 * a_52
375            - a_01 * a_14 * a_22 * a_30 * a_43 * a_55
376            + a_01 * a_14 * a_22 * a_30 * a_45 * a_53
377            + a_01 * a_14 * a_22 * a_33 * a_40 * a_55
378            - a_01 * a_14 * a_22 * a_33 * a_45 * a_50
379            - a_01 * a_14 * a_22 * a_35 * a_40 * a_53
380            + a_01 * a_14 * a_22 * a_35 * a_43 * a_50
381            + a_01 * a_14 * a_23 * a_30 * a_42 * a_55
382            - a_01 * a_14 * a_23 * a_30 * a_45 * a_52
383            - a_01 * a_14 * a_23 * a_32 * a_40 * a_55
384            + a_01 * a_14 * a_23 * a_32 * a_45 * a_50
385            + a_01 * a_14 * a_23 * a_35 * a_40 * a_52
386            - a_01 * a_14 * a_23 * a_35 * a_42 * a_50
387            - a_01 * a_14 * a_25 * a_30 * a_42 * a_53
388            + a_01 * a_14 * a_25 * a_30 * a_43 * a_52
389            + a_01 * a_14 * a_25 * a_32 * a_40 * a_53
390            - a_01 * a_14 * a_25 * a_32 * a_43 * a_50
391            - a_01 * a_14 * a_25 * a_33 * a_40 * a_52
392            + a_01 * a_14 * a_25 * a_33 * a_42 * a_50
393            - a_01 * a_15 * a_20 * a_32 * a_43 * a_54
394            + a_01 * a_15 * a_20 * a_32 * a_44 * a_53
395            + a_01 * a_15 * a_20 * a_33 * a_42 * a_54
396            - a_01 * a_15 * a_20 * a_33 * a_44 * a_52
397            - a_01 * a_15 * a_20 * a_34 * a_42 * a_53
398            + a_01 * a_15 * a_20 * a_34 * a_43 * a_52
399            + a_01 * a_15 * a_22 * a_30 * a_43 * a_54
400            - a_01 * a_15 * a_22 * a_30 * a_44 * a_53
401            - a_01 * a_15 * a_22 * a_33 * a_40 * a_54
402            + a_01 * a_15 * a_22 * a_33 * a_44 * a_50
403            + a_01 * a_15 * a_22 * a_34 * a_40 * a_53
404            - a_01 * a_15 * a_22 * a_34 * a_43 * a_50
405            - a_01 * a_15 * a_23 * a_30 * a_42 * a_54
406            + a_01 * a_15 * a_23 * a_30 * a_44 * a_52
407            + a_01 * a_15 * a_23 * a_32 * a_40 * a_54
408            - a_01 * a_15 * a_23 * a_32 * a_44 * a_50
409            - a_01 * a_15 * a_23 * a_34 * a_40 * a_52
410            + a_01 * a_15 * a_23 * a_34 * a_42 * a_50
411            + a_01 * a_15 * a_24 * a_30 * a_42 * a_53
412            - a_01 * a_15 * a_24 * a_30 * a_43 * a_52
413            - a_01 * a_15 * a_24 * a_32 * a_40 * a_53
414            + a_01 * a_15 * a_24 * a_32 * a_43 * a_50
415            + a_01 * a_15 * a_24 * a_33 * a_40 * a_52
416            - a_01 * a_15 * a_24 * a_33 * a_42 * a_50
417            + a_02 * a_10 * a_21 * a_33 * a_44 * a_55
418            - a_02 * a_10 * a_21 * a_33 * a_45 * a_54
419            - a_02 * a_10 * a_21 * a_34 * a_43 * a_55
420            + a_02 * a_10 * a_21 * a_34 * a_45 * a_53
421            + a_02 * a_10 * a_21 * a_35 * a_43 * a_54
422            - a_02 * a_10 * a_21 * a_35 * a_44 * a_53
423            - a_02 * a_10 * a_23 * a_31 * a_44 * a_55
424            + a_02 * a_10 * a_23 * a_31 * a_45 * a_54
425            + a_02 * a_10 * a_23 * a_34 * a_41 * a_55
426            - a_02 * a_10 * a_23 * a_34 * a_45 * a_51
427            - a_02 * a_10 * a_23 * a_35 * a_41 * a_54
428            + a_02 * a_10 * a_23 * a_35 * a_44 * a_51
429            + a_02 * a_10 * a_24 * a_31 * a_43 * a_55
430            - a_02 * a_10 * a_24 * a_31 * a_45 * a_53
431            - a_02 * a_10 * a_24 * a_33 * a_41 * a_55
432            + a_02 * a_10 * a_24 * a_33 * a_45 * a_51
433            + a_02 * a_10 * a_24 * a_35 * a_41 * a_53
434            - a_02 * a_10 * a_24 * a_35 * a_43 * a_51
435            - a_02 * a_10 * a_25 * a_31 * a_43 * a_54
436            + a_02 * a_10 * a_25 * a_31 * a_44 * a_53
437            + a_02 * a_10 * a_25 * a_33 * a_41 * a_54
438            - a_02 * a_10 * a_25 * a_33 * a_44 * a_51
439            - a_02 * a_10 * a_25 * a_34 * a_41 * a_53
440            + a_02 * a_10 * a_25 * a_34 * a_43 * a_51
441            - a_02 * a_11 * a_20 * a_33 * a_44 * a_55
442            + a_02 * a_11 * a_20 * a_33 * a_45 * a_54
443            + a_02 * a_11 * a_20 * a_34 * a_43 * a_55
444            - a_02 * a_11 * a_20 * a_34 * a_45 * a_53
445            - a_02 * a_11 * a_20 * a_35 * a_43 * a_54
446            + a_02 * a_11 * a_20 * a_35 * a_44 * a_53
447            + a_02 * a_11 * a_23 * a_30 * a_44 * a_55
448            - a_02 * a_11 * a_23 * a_30 * a_45 * a_54
449            - a_02 * a_11 * a_23 * a_34 * a_40 * a_55
450            + a_02 * a_11 * a_23 * a_34 * a_45 * a_50
451            + a_02 * a_11 * a_23 * a_35 * a_40 * a_54
452            - a_02 * a_11 * a_23 * a_35 * a_44 * a_50
453            - a_02 * a_11 * a_24 * a_30 * a_43 * a_55
454            + a_02 * a_11 * a_24 * a_30 * a_45 * a_53
455            + a_02 * a_11 * a_24 * a_33 * a_40 * a_55
456            - a_02 * a_11 * a_24 * a_33 * a_45 * a_50
457            - a_02 * a_11 * a_24 * a_35 * a_40 * a_53
458            + a_02 * a_11 * a_24 * a_35 * a_43 * a_50
459            + a_02 * a_11 * a_25 * a_30 * a_43 * a_54
460            - a_02 * a_11 * a_25 * a_30 * a_44 * a_53
461            - a_02 * a_11 * a_25 * a_33 * a_40 * a_54
462            + a_02 * a_11 * a_25 * a_33 * a_44 * a_50
463            + a_02 * a_11 * a_25 * a_34 * a_40 * a_53
464            - a_02 * a_11 * a_25 * a_34 * a_43 * a_50
465            + a_02 * a_13 * a_20 * a_31 * a_44 * a_55
466            - a_02 * a_13 * a_20 * a_31 * a_45 * a_54
467            - a_02 * a_13 * a_20 * a_34 * a_41 * a_55
468            + a_02 * a_13 * a_20 * a_34 * a_45 * a_51
469            + a_02 * a_13 * a_20 * a_35 * a_41 * a_54
470            - a_02 * a_13 * a_20 * a_35 * a_44 * a_51
471            - a_02 * a_13 * a_21 * a_30 * a_44 * a_55
472            + a_02 * a_13 * a_21 * a_30 * a_45 * a_54
473            + a_02 * a_13 * a_21 * a_34 * a_40 * a_55
474            - a_02 * a_13 * a_21 * a_34 * a_45 * a_50
475            - a_02 * a_13 * a_21 * a_35 * a_40 * a_54
476            + a_02 * a_13 * a_21 * a_35 * a_44 * a_50
477            + a_02 * a_13 * a_24 * a_30 * a_41 * a_55
478            - a_02 * a_13 * a_24 * a_30 * a_45 * a_51
479            - a_02 * a_13 * a_24 * a_31 * a_40 * a_55
480            + a_02 * a_13 * a_24 * a_31 * a_45 * a_50
481            + a_02 * a_13 * a_24 * a_35 * a_40 * a_51
482            - a_02 * a_13 * a_24 * a_35 * a_41 * a_50
483            - a_02 * a_13 * a_25 * a_30 * a_41 * a_54
484            + a_02 * a_13 * a_25 * a_30 * a_44 * a_51
485            + a_02 * a_13 * a_25 * a_31 * a_40 * a_54
486            - a_02 * a_13 * a_25 * a_31 * a_44 * a_50
487            - a_02 * a_13 * a_25 * a_34 * a_40 * a_51
488            + a_02 * a_13 * a_25 * a_34 * a_41 * a_50
489            - a_02 * a_14 * a_20 * a_31 * a_43 * a_55
490            + a_02 * a_14 * a_20 * a_31 * a_45 * a_53
491            + a_02 * a_14 * a_20 * a_33 * a_41 * a_55
492            - a_02 * a_14 * a_20 * a_33 * a_45 * a_51
493            - a_02 * a_14 * a_20 * a_35 * a_41 * a_53
494            + a_02 * a_14 * a_20 * a_35 * a_43 * a_51
495            + a_02 * a_14 * a_21 * a_30 * a_43 * a_55
496            - a_02 * a_14 * a_21 * a_30 * a_45 * a_53
497            - a_02 * a_14 * a_21 * a_33 * a_40 * a_55
498            + a_02 * a_14 * a_21 * a_33 * a_45 * a_50
499            + a_02 * a_14 * a_21 * a_35 * a_40 * a_53
500            - a_02 * a_14 * a_21 * a_35 * a_43 * a_50
501            - a_02 * a_14 * a_23 * a_30 * a_41 * a_55
502            + a_02 * a_14 * a_23 * a_30 * a_45 * a_51
503            + a_02 * a_14 * a_23 * a_31 * a_40 * a_55
504            - a_02 * a_14 * a_23 * a_31 * a_45 * a_50
505            - a_02 * a_14 * a_23 * a_35 * a_40 * a_51
506            + a_02 * a_14 * a_23 * a_35 * a_41 * a_50
507            + a_02 * a_14 * a_25 * a_30 * a_41 * a_53
508            - a_02 * a_14 * a_25 * a_30 * a_43 * a_51
509            - a_02 * a_14 * a_25 * a_31 * a_40 * a_53
510            + a_02 * a_14 * a_25 * a_31 * a_43 * a_50
511            + a_02 * a_14 * a_25 * a_33 * a_40 * a_51
512            - a_02 * a_14 * a_25 * a_33 * a_41 * a_50
513            + a_02 * a_15 * a_20 * a_31 * a_43 * a_54
514            - a_02 * a_15 * a_20 * a_31 * a_44 * a_53
515            - a_02 * a_15 * a_20 * a_33 * a_41 * a_54
516            + a_02 * a_15 * a_20 * a_33 * a_44 * a_51
517            + a_02 * a_15 * a_20 * a_34 * a_41 * a_53
518            - a_02 * a_15 * a_20 * a_34 * a_43 * a_51
519            - a_02 * a_15 * a_21 * a_30 * a_43 * a_54
520            + a_02 * a_15 * a_21 * a_30 * a_44 * a_53
521            + a_02 * a_15 * a_21 * a_33 * a_40 * a_54
522            - a_02 * a_15 * a_21 * a_33 * a_44 * a_50
523            - a_02 * a_15 * a_21 * a_34 * a_40 * a_53
524            + a_02 * a_15 * a_21 * a_34 * a_43 * a_50
525            + a_02 * a_15 * a_23 * a_30 * a_41 * a_54
526            - a_02 * a_15 * a_23 * a_30 * a_44 * a_51
527            - a_02 * a_15 * a_23 * a_31 * a_40 * a_54
528            + a_02 * a_15 * a_23 * a_31 * a_44 * a_50
529            + a_02 * a_15 * a_23 * a_34 * a_40 * a_51
530            - a_02 * a_15 * a_23 * a_34 * a_41 * a_50
531            - a_02 * a_15 * a_24 * a_30 * a_41 * a_53
532            + a_02 * a_15 * a_24 * a_30 * a_43 * a_51
533            + a_02 * a_15 * a_24 * a_31 * a_40 * a_53
534            - a_02 * a_15 * a_24 * a_31 * a_43 * a_50
535            - a_02 * a_15 * a_24 * a_33 * a_40 * a_51
536            + a_02 * a_15 * a_24 * a_33 * a_41 * a_50
537            - a_03 * a_10 * a_21 * a_32 * a_44 * a_55
538            + a_03 * a_10 * a_21 * a_32 * a_45 * a_54
539            + a_03 * a_10 * a_21 * a_34 * a_42 * a_55
540            - a_03 * a_10 * a_21 * a_34 * a_45 * a_52
541            - a_03 * a_10 * a_21 * a_35 * a_42 * a_54
542            + a_03 * a_10 * a_21 * a_35 * a_44 * a_52
543            + a_03 * a_10 * a_22 * a_31 * a_44 * a_55
544            - a_03 * a_10 * a_22 * a_31 * a_45 * a_54
545            - a_03 * a_10 * a_22 * a_34 * a_41 * a_55
546            + a_03 * a_10 * a_22 * a_34 * a_45 * a_51
547            + a_03 * a_10 * a_22 * a_35 * a_41 * a_54
548            - a_03 * a_10 * a_22 * a_35 * a_44 * a_51
549            - a_03 * a_10 * a_24 * a_31 * a_42 * a_55
550            + a_03 * a_10 * a_24 * a_31 * a_45 * a_52
551            + a_03 * a_10 * a_24 * a_32 * a_41 * a_55
552            - a_03 * a_10 * a_24 * a_32 * a_45 * a_51
553            - a_03 * a_10 * a_24 * a_35 * a_41 * a_52
554            + a_03 * a_10 * a_24 * a_35 * a_42 * a_51
555            + a_03 * a_10 * a_25 * a_31 * a_42 * a_54
556            - a_03 * a_10 * a_25 * a_31 * a_44 * a_52
557            - a_03 * a_10 * a_25 * a_32 * a_41 * a_54
558            + a_03 * a_10 * a_25 * a_32 * a_44 * a_51
559            + a_03 * a_10 * a_25 * a_34 * a_41 * a_52
560            - a_03 * a_10 * a_25 * a_34 * a_42 * a_51
561            + a_03 * a_11 * a_20 * a_32 * a_44 * a_55
562            - a_03 * a_11 * a_20 * a_32 * a_45 * a_54
563            - a_03 * a_11 * a_20 * a_34 * a_42 * a_55
564            + a_03 * a_11 * a_20 * a_34 * a_45 * a_52
565            + a_03 * a_11 * a_20 * a_35 * a_42 * a_54
566            - a_03 * a_11 * a_20 * a_35 * a_44 * a_52
567            - a_03 * a_11 * a_22 * a_30 * a_44 * a_55
568            + a_03 * a_11 * a_22 * a_30 * a_45 * a_54
569            + a_03 * a_11 * a_22 * a_34 * a_40 * a_55
570            - a_03 * a_11 * a_22 * a_34 * a_45 * a_50
571            - a_03 * a_11 * a_22 * a_35 * a_40 * a_54
572            + a_03 * a_11 * a_22 * a_35 * a_44 * a_50
573            + a_03 * a_11 * a_24 * a_30 * a_42 * a_55
574            - a_03 * a_11 * a_24 * a_30 * a_45 * a_52
575            - a_03 * a_11 * a_24 * a_32 * a_40 * a_55
576            + a_03 * a_11 * a_24 * a_32 * a_45 * a_50
577            + a_03 * a_11 * a_24 * a_35 * a_40 * a_52
578            - a_03 * a_11 * a_24 * a_35 * a_42 * a_50
579            - a_03 * a_11 * a_25 * a_30 * a_42 * a_54
580            + a_03 * a_11 * a_25 * a_30 * a_44 * a_52
581            + a_03 * a_11 * a_25 * a_32 * a_40 * a_54
582            - a_03 * a_11 * a_25 * a_32 * a_44 * a_50
583            - a_03 * a_11 * a_25 * a_34 * a_40 * a_52
584            + a_03 * a_11 * a_25 * a_34 * a_42 * a_50
585            - a_03 * a_12 * a_20 * a_31 * a_44 * a_55
586            + a_03 * a_12 * a_20 * a_31 * a_45 * a_54
587            + a_03 * a_12 * a_20 * a_34 * a_41 * a_55
588            - a_03 * a_12 * a_20 * a_34 * a_45 * a_51
589            - a_03 * a_12 * a_20 * a_35 * a_41 * a_54
590            + a_03 * a_12 * a_20 * a_35 * a_44 * a_51
591            + a_03 * a_12 * a_21 * a_30 * a_44 * a_55
592            - a_03 * a_12 * a_21 * a_30 * a_45 * a_54
593            - a_03 * a_12 * a_21 * a_34 * a_40 * a_55
594            + a_03 * a_12 * a_21 * a_34 * a_45 * a_50
595            + a_03 * a_12 * a_21 * a_35 * a_40 * a_54
596            - a_03 * a_12 * a_21 * a_35 * a_44 * a_50
597            - a_03 * a_12 * a_24 * a_30 * a_41 * a_55
598            + a_03 * a_12 * a_24 * a_30 * a_45 * a_51
599            + a_03 * a_12 * a_24 * a_31 * a_40 * a_55
600            - a_03 * a_12 * a_24 * a_31 * a_45 * a_50
601            - a_03 * a_12 * a_24 * a_35 * a_40 * a_51
602            + a_03 * a_12 * a_24 * a_35 * a_41 * a_50
603            + a_03 * a_12 * a_25 * a_30 * a_41 * a_54
604            - a_03 * a_12 * a_25 * a_30 * a_44 * a_51
605            - a_03 * a_12 * a_25 * a_31 * a_40 * a_54
606            + a_03 * a_12 * a_25 * a_31 * a_44 * a_50
607            + a_03 * a_12 * a_25 * a_34 * a_40 * a_51
608            - a_03 * a_12 * a_25 * a_34 * a_41 * a_50
609            + a_03 * a_14 * a_20 * a_31 * a_42 * a_55
610            - a_03 * a_14 * a_20 * a_31 * a_45 * a_52
611            - a_03 * a_14 * a_20 * a_32 * a_41 * a_55
612            + a_03 * a_14 * a_20 * a_32 * a_45 * a_51
613            + a_03 * a_14 * a_20 * a_35 * a_41 * a_52
614            - a_03 * a_14 * a_20 * a_35 * a_42 * a_51
615            - a_03 * a_14 * a_21 * a_30 * a_42 * a_55
616            + a_03 * a_14 * a_21 * a_30 * a_45 * a_52
617            + a_03 * a_14 * a_21 * a_32 * a_40 * a_55
618            - a_03 * a_14 * a_21 * a_32 * a_45 * a_50
619            - a_03 * a_14 * a_21 * a_35 * a_40 * a_52
620            + a_03 * a_14 * a_21 * a_35 * a_42 * a_50
621            + a_03 * a_14 * a_22 * a_30 * a_41 * a_55
622            - a_03 * a_14 * a_22 * a_30 * a_45 * a_51
623            - a_03 * a_14 * a_22 * a_31 * a_40 * a_55
624            + a_03 * a_14 * a_22 * a_31 * a_45 * a_50
625            + a_03 * a_14 * a_22 * a_35 * a_40 * a_51
626            - a_03 * a_14 * a_22 * a_35 * a_41 * a_50
627            - a_03 * a_14 * a_25 * a_30 * a_41 * a_52
628            + a_03 * a_14 * a_25 * a_30 * a_42 * a_51
629            + a_03 * a_14 * a_25 * a_31 * a_40 * a_52
630            - a_03 * a_14 * a_25 * a_31 * a_42 * a_50
631            - a_03 * a_14 * a_25 * a_32 * a_40 * a_51
632            + a_03 * a_14 * a_25 * a_32 * a_41 * a_50
633            - a_03 * a_15 * a_20 * a_31 * a_42 * a_54
634            + a_03 * a_15 * a_20 * a_31 * a_44 * a_52
635            + a_03 * a_15 * a_20 * a_32 * a_41 * a_54
636            - a_03 * a_15 * a_20 * a_32 * a_44 * a_51
637            - a_03 * a_15 * a_20 * a_34 * a_41 * a_52
638            + a_03 * a_15 * a_20 * a_34 * a_42 * a_51
639            + a_03 * a_15 * a_21 * a_30 * a_42 * a_54
640            - a_03 * a_15 * a_21 * a_30 * a_44 * a_52
641            - a_03 * a_15 * a_21 * a_32 * a_40 * a_54
642            + a_03 * a_15 * a_21 * a_32 * a_44 * a_50
643            + a_03 * a_15 * a_21 * a_34 * a_40 * a_52
644            - a_03 * a_15 * a_21 * a_34 * a_42 * a_50
645            - a_03 * a_15 * a_22 * a_30 * a_41 * a_54
646            + a_03 * a_15 * a_22 * a_30 * a_44 * a_51
647            + a_03 * a_15 * a_22 * a_31 * a_40 * a_54
648            - a_03 * a_15 * a_22 * a_31 * a_44 * a_50
649            - a_03 * a_15 * a_22 * a_34 * a_40 * a_51
650            + a_03 * a_15 * a_22 * a_34 * a_41 * a_50
651            + a_03 * a_15 * a_24 * a_30 * a_41 * a_52
652            - a_03 * a_15 * a_24 * a_30 * a_42 * a_51
653            - a_03 * a_15 * a_24 * a_31 * a_40 * a_52
654            + a_03 * a_15 * a_24 * a_31 * a_42 * a_50
655            + a_03 * a_15 * a_24 * a_32 * a_40 * a_51
656            - a_03 * a_15 * a_24 * a_32 * a_41 * a_50
657            + a_04 * a_10 * a_21 * a_32 * a_43 * a_55
658            - a_04 * a_10 * a_21 * a_32 * a_45 * a_53
659            - a_04 * a_10 * a_21 * a_33 * a_42 * a_55
660            + a_04 * a_10 * a_21 * a_33 * a_45 * a_52
661            + a_04 * a_10 * a_21 * a_35 * a_42 * a_53
662            - a_04 * a_10 * a_21 * a_35 * a_43 * a_52
663            - a_04 * a_10 * a_22 * a_31 * a_43 * a_55
664            + a_04 * a_10 * a_22 * a_31 * a_45 * a_53
665            + a_04 * a_10 * a_22 * a_33 * a_41 * a_55
666            - a_04 * a_10 * a_22 * a_33 * a_45 * a_51
667            - a_04 * a_10 * a_22 * a_35 * a_41 * a_53
668            + a_04 * a_10 * a_22 * a_35 * a_43 * a_51
669            + a_04 * a_10 * a_23 * a_31 * a_42 * a_55
670            - a_04 * a_10 * a_23 * a_31 * a_45 * a_52
671            - a_04 * a_10 * a_23 * a_32 * a_41 * a_55
672            + a_04 * a_10 * a_23 * a_32 * a_45 * a_51
673            + a_04 * a_10 * a_23 * a_35 * a_41 * a_52
674            - a_04 * a_10 * a_23 * a_35 * a_42 * a_51
675            - a_04 * a_10 * a_25 * a_31 * a_42 * a_53
676            + a_04 * a_10 * a_25 * a_31 * a_43 * a_52
677            + a_04 * a_10 * a_25 * a_32 * a_41 * a_53
678            - a_04 * a_10 * a_25 * a_32 * a_43 * a_51
679            - a_04 * a_10 * a_25 * a_33 * a_41 * a_52
680            + a_04 * a_10 * a_25 * a_33 * a_42 * a_51
681            - a_04 * a_11 * a_20 * a_32 * a_43 * a_55
682            + a_04 * a_11 * a_20 * a_32 * a_45 * a_53
683            + a_04 * a_11 * a_20 * a_33 * a_42 * a_55
684            - a_04 * a_11 * a_20 * a_33 * a_45 * a_52
685            - a_04 * a_11 * a_20 * a_35 * a_42 * a_53
686            + a_04 * a_11 * a_20 * a_35 * a_43 * a_52
687            + a_04 * a_11 * a_22 * a_30 * a_43 * a_55
688            - a_04 * a_11 * a_22 * a_30 * a_45 * a_53
689            - a_04 * a_11 * a_22 * a_33 * a_40 * a_55
690            + a_04 * a_11 * a_22 * a_33 * a_45 * a_50
691            + a_04 * a_11 * a_22 * a_35 * a_40 * a_53
692            - a_04 * a_11 * a_22 * a_35 * a_43 * a_50
693            - a_04 * a_11 * a_23 * a_30 * a_42 * a_55
694            + a_04 * a_11 * a_23 * a_30 * a_45 * a_52
695            + a_04 * a_11 * a_23 * a_32 * a_40 * a_55
696            - a_04 * a_11 * a_23 * a_32 * a_45 * a_50
697            - a_04 * a_11 * a_23 * a_35 * a_40 * a_52
698            + a_04 * a_11 * a_23 * a_35 * a_42 * a_50
699            + a_04 * a_11 * a_25 * a_30 * a_42 * a_53
700            - a_04 * a_11 * a_25 * a_30 * a_43 * a_52
701            - a_04 * a_11 * a_25 * a_32 * a_40 * a_53
702            + a_04 * a_11 * a_25 * a_32 * a_43 * a_50
703            + a_04 * a_11 * a_25 * a_33 * a_40 * a_52
704            - a_04 * a_11 * a_25 * a_33 * a_42 * a_50
705            + a_04 * a_12 * a_20 * a_31 * a_43 * a_55
706            - a_04 * a_12 * a_20 * a_31 * a_45 * a_53
707            - a_04 * a_12 * a_20 * a_33 * a_41 * a_55
708            + a_04 * a_12 * a_20 * a_33 * a_45 * a_51
709            + a_04 * a_12 * a_20 * a_35 * a_41 * a_53
710            - a_04 * a_12 * a_20 * a_35 * a_43 * a_51
711            - a_04 * a_12 * a_21 * a_30 * a_43 * a_55
712            + a_04 * a_12 * a_21 * a_30 * a_45 * a_53
713            + a_04 * a_12 * a_21 * a_33 * a_40 * a_55
714            - a_04 * a_12 * a_21 * a_33 * a_45 * a_50
715            - a_04 * a_12 * a_21 * a_35 * a_40 * a_53
716            + a_04 * a_12 * a_21 * a_35 * a_43 * a_50
717            + a_04 * a_12 * a_23 * a_30 * a_41 * a_55
718            - a_04 * a_12 * a_23 * a_30 * a_45 * a_51
719            - a_04 * a_12 * a_23 * a_31 * a_40 * a_55
720            + a_04 * a_12 * a_23 * a_31 * a_45 * a_50
721            + a_04 * a_12 * a_23 * a_35 * a_40 * a_51
722            - a_04 * a_12 * a_23 * a_35 * a_41 * a_50
723            - a_04 * a_12 * a_25 * a_30 * a_41 * a_53
724            + a_04 * a_12 * a_25 * a_30 * a_43 * a_51
725            + a_04 * a_12 * a_25 * a_31 * a_40 * a_53
726            - a_04 * a_12 * a_25 * a_31 * a_43 * a_50
727            - a_04 * a_12 * a_25 * a_33 * a_40 * a_51
728            + a_04 * a_12 * a_25 * a_33 * a_41 * a_50
729            - a_04 * a_13 * a_20 * a_31 * a_42 * a_55
730            + a_04 * a_13 * a_20 * a_31 * a_45 * a_52
731            + a_04 * a_13 * a_20 * a_32 * a_41 * a_55
732            - a_04 * a_13 * a_20 * a_32 * a_45 * a_51
733            - a_04 * a_13 * a_20 * a_35 * a_41 * a_52
734            + a_04 * a_13 * a_20 * a_35 * a_42 * a_51
735            + a_04 * a_13 * a_21 * a_30 * a_42 * a_55
736            - a_04 * a_13 * a_21 * a_30 * a_45 * a_52
737            - a_04 * a_13 * a_21 * a_32 * a_40 * a_55
738            + a_04 * a_13 * a_21 * a_32 * a_45 * a_50
739            + a_04 * a_13 * a_21 * a_35 * a_40 * a_52
740            - a_04 * a_13 * a_21 * a_35 * a_42 * a_50
741            - a_04 * a_13 * a_22 * a_30 * a_41 * a_55
742            + a_04 * a_13 * a_22 * a_30 * a_45 * a_51
743            + a_04 * a_13 * a_22 * a_31 * a_40 * a_55
744            - a_04 * a_13 * a_22 * a_31 * a_45 * a_50
745            - a_04 * a_13 * a_22 * a_35 * a_40 * a_51
746            + a_04 * a_13 * a_22 * a_35 * a_41 * a_50
747            + a_04 * a_13 * a_25 * a_30 * a_41 * a_52
748            - a_04 * a_13 * a_25 * a_30 * a_42 * a_51
749            - a_04 * a_13 * a_25 * a_31 * a_40 * a_52
750            + a_04 * a_13 * a_25 * a_31 * a_42 * a_50
751            + a_04 * a_13 * a_25 * a_32 * a_40 * a_51
752            - a_04 * a_13 * a_25 * a_32 * a_41 * a_50
753            + a_04 * a_15 * a_20 * a_31 * a_42 * a_53
754            - a_04 * a_15 * a_20 * a_31 * a_43 * a_52
755            - a_04 * a_15 * a_20 * a_32 * a_41 * a_53
756            + a_04 * a_15 * a_20 * a_32 * a_43 * a_51
757            + a_04 * a_15 * a_20 * a_33 * a_41 * a_52
758            - a_04 * a_15 * a_20 * a_33 * a_42 * a_51
759            - a_04 * a_15 * a_21 * a_30 * a_42 * a_53
760            + a_04 * a_15 * a_21 * a_30 * a_43 * a_52
761            + a_04 * a_15 * a_21 * a_32 * a_40 * a_53
762            - a_04 * a_15 * a_21 * a_32 * a_43 * a_50
763            - a_04 * a_15 * a_21 * a_33 * a_40 * a_52
764            + a_04 * a_15 * a_21 * a_33 * a_42 * a_50
765            + a_04 * a_15 * a_22 * a_30 * a_41 * a_53
766            - a_04 * a_15 * a_22 * a_30 * a_43 * a_51
767            - a_04 * a_15 * a_22 * a_31 * a_40 * a_53
768            + a_04 * a_15 * a_22 * a_31 * a_43 * a_50
769            + a_04 * a_15 * a_22 * a_33 * a_40 * a_51
770            - a_04 * a_15 * a_22 * a_33 * a_41 * a_50
771            - a_04 * a_15 * a_23 * a_30 * a_41 * a_52
772            + a_04 * a_15 * a_23 * a_30 * a_42 * a_51
773            + a_04 * a_15 * a_23 * a_31 * a_40 * a_52
774            - a_04 * a_15 * a_23 * a_31 * a_42 * a_50
775            - a_04 * a_15 * a_23 * a_32 * a_40 * a_51
776            + a_04 * a_15 * a_23 * a_32 * a_41 * a_50
777            - a_05 * a_10 * a_21 * a_32 * a_43 * a_54
778            + a_05 * a_10 * a_21 * a_32 * a_44 * a_53
779            + a_05 * a_10 * a_21 * a_33 * a_42 * a_54
780            - a_05 * a_10 * a_21 * a_33 * a_44 * a_52
781            - a_05 * a_10 * a_21 * a_34 * a_42 * a_53
782            + a_05 * a_10 * a_21 * a_34 * a_43 * a_52
783            + a_05 * a_10 * a_22 * a_31 * a_43 * a_54
784            - a_05 * a_10 * a_22 * a_31 * a_44 * a_53
785            - a_05 * a_10 * a_22 * a_33 * a_41 * a_54
786            + a_05 * a_10 * a_22 * a_33 * a_44 * a_51
787            + a_05 * a_10 * a_22 * a_34 * a_41 * a_53
788            - a_05 * a_10 * a_22 * a_34 * a_43 * a_51
789            - a_05 * a_10 * a_23 * a_31 * a_42 * a_54
790            + a_05 * a_10 * a_23 * a_31 * a_44 * a_52
791            + a_05 * a_10 * a_23 * a_32 * a_41 * a_54
792            - a_05 * a_10 * a_23 * a_32 * a_44 * a_51
793            - a_05 * a_10 * a_23 * a_34 * a_41 * a_52
794            + a_05 * a_10 * a_23 * a_34 * a_42 * a_51
795            + a_05 * a_10 * a_24 * a_31 * a_42 * a_53
796            - a_05 * a_10 * a_24 * a_31 * a_43 * a_52
797            - a_05 * a_10 * a_24 * a_32 * a_41 * a_53
798            + a_05 * a_10 * a_24 * a_32 * a_43 * a_51
799            + a_05 * a_10 * a_24 * a_33 * a_41 * a_52
800            - a_05 * a_10 * a_24 * a_33 * a_42 * a_51
801            + a_05 * a_11 * a_20 * a_32 * a_43 * a_54
802            - a_05 * a_11 * a_20 * a_32 * a_44 * a_53
803            - a_05 * a_11 * a_20 * a_33 * a_42 * a_54
804            + a_05 * a_11 * a_20 * a_33 * a_44 * a_52
805            + a_05 * a_11 * a_20 * a_34 * a_42 * a_53
806            - a_05 * a_11 * a_20 * a_34 * a_43 * a_52
807            - a_05 * a_11 * a_22 * a_30 * a_43 * a_54
808            + a_05 * a_11 * a_22 * a_30 * a_44 * a_53
809            + a_05 * a_11 * a_22 * a_33 * a_40 * a_54
810            - a_05 * a_11 * a_22 * a_33 * a_44 * a_50
811            - a_05 * a_11 * a_22 * a_34 * a_40 * a_53
812            + a_05 * a_11 * a_22 * a_34 * a_43 * a_50
813            + a_05 * a_11 * a_23 * a_30 * a_42 * a_54
814            - a_05 * a_11 * a_23 * a_30 * a_44 * a_52
815            - a_05 * a_11 * a_23 * a_32 * a_40 * a_54
816            + a_05 * a_11 * a_23 * a_32 * a_44 * a_50
817            + a_05 * a_11 * a_23 * a_34 * a_40 * a_52
818            - a_05 * a_11 * a_23 * a_34 * a_42 * a_50
819            - a_05 * a_11 * a_24 * a_30 * a_42 * a_53
820            + a_05 * a_11 * a_24 * a_30 * a_43 * a_52
821            + a_05 * a_11 * a_24 * a_32 * a_40 * a_53
822            - a_05 * a_11 * a_24 * a_32 * a_43 * a_50
823            - a_05 * a_11 * a_24 * a_33 * a_40 * a_52
824            + a_05 * a_11 * a_24 * a_33 * a_42 * a_50
825            - a_05 * a_12 * a_20 * a_31 * a_43 * a_54
826            + a_05 * a_12 * a_20 * a_31 * a_44 * a_53
827            + a_05 * a_12 * a_20 * a_33 * a_41 * a_54
828            - a_05 * a_12 * a_20 * a_33 * a_44 * a_51
829            - a_05 * a_12 * a_20 * a_34 * a_41 * a_53
830            + a_05 * a_12 * a_20 * a_34 * a_43 * a_51
831            + a_05 * a_12 * a_21 * a_30 * a_43 * a_54
832            - a_05 * a_12 * a_21 * a_30 * a_44 * a_53
833            - a_05 * a_12 * a_21 * a_33 * a_40 * a_54
834            + a_05 * a_12 * a_21 * a_33 * a_44 * a_50
835            + a_05 * a_12 * a_21 * a_34 * a_40 * a_53
836            - a_05 * a_12 * a_21 * a_34 * a_43 * a_50
837            - a_05 * a_12 * a_23 * a_30 * a_41 * a_54
838            + a_05 * a_12 * a_23 * a_30 * a_44 * a_51
839            + a_05 * a_12 * a_23 * a_31 * a_40 * a_54
840            - a_05 * a_12 * a_23 * a_31 * a_44 * a_50
841            - a_05 * a_12 * a_23 * a_34 * a_40 * a_51
842            + a_05 * a_12 * a_23 * a_34 * a_41 * a_50
843            + a_05 * a_12 * a_24 * a_30 * a_41 * a_53
844            - a_05 * a_12 * a_24 * a_30 * a_43 * a_51
845            - a_05 * a_12 * a_24 * a_31 * a_40 * a_53
846            + a_05 * a_12 * a_24 * a_31 * a_43 * a_50
847            + a_05 * a_12 * a_24 * a_33 * a_40 * a_51
848            - a_05 * a_12 * a_24 * a_33 * a_41 * a_50
849            + a_05 * a_13 * a_20 * a_31 * a_42 * a_54
850            - a_05 * a_13 * a_20 * a_31 * a_44 * a_52
851            - a_05 * a_13 * a_20 * a_32 * a_41 * a_54
852            + a_05 * a_13 * a_20 * a_32 * a_44 * a_51
853            + a_05 * a_13 * a_20 * a_34 * a_41 * a_52
854            - a_05 * a_13 * a_20 * a_34 * a_42 * a_51
855            - a_05 * a_13 * a_21 * a_30 * a_42 * a_54
856            + a_05 * a_13 * a_21 * a_30 * a_44 * a_52
857            + a_05 * a_13 * a_21 * a_32 * a_40 * a_54
858            - a_05 * a_13 * a_21 * a_32 * a_44 * a_50
859            - a_05 * a_13 * a_21 * a_34 * a_40 * a_52
860            + a_05 * a_13 * a_21 * a_34 * a_42 * a_50
861            + a_05 * a_13 * a_22 * a_30 * a_41 * a_54
862            - a_05 * a_13 * a_22 * a_30 * a_44 * a_51
863            - a_05 * a_13 * a_22 * a_31 * a_40 * a_54
864            + a_05 * a_13 * a_22 * a_31 * a_44 * a_50
865            + a_05 * a_13 * a_22 * a_34 * a_40 * a_51
866            - a_05 * a_13 * a_22 * a_34 * a_41 * a_50
867            - a_05 * a_13 * a_24 * a_30 * a_41 * a_52
868            + a_05 * a_13 * a_24 * a_30 * a_42 * a_51
869            + a_05 * a_13 * a_24 * a_31 * a_40 * a_52
870            - a_05 * a_13 * a_24 * a_31 * a_42 * a_50
871            - a_05 * a_13 * a_24 * a_32 * a_40 * a_51
872            + a_05 * a_13 * a_24 * a_32 * a_41 * a_50
873            - a_05 * a_14 * a_20 * a_31 * a_42 * a_53
874            + a_05 * a_14 * a_20 * a_31 * a_43 * a_52
875            + a_05 * a_14 * a_20 * a_32 * a_41 * a_53
876            - a_05 * a_14 * a_20 * a_32 * a_43 * a_51
877            - a_05 * a_14 * a_20 * a_33 * a_41 * a_52
878            + a_05 * a_14 * a_20 * a_33 * a_42 * a_51
879            + a_05 * a_14 * a_21 * a_30 * a_42 * a_53
880            - a_05 * a_14 * a_21 * a_30 * a_43 * a_52
881            - a_05 * a_14 * a_21 * a_32 * a_40 * a_53
882            + a_05 * a_14 * a_21 * a_32 * a_43 * a_50
883            + a_05 * a_14 * a_21 * a_33 * a_40 * a_52
884            - a_05 * a_14 * a_21 * a_33 * a_42 * a_50
885            - a_05 * a_14 * a_22 * a_30 * a_41 * a_53
886            + a_05 * a_14 * a_22 * a_30 * a_43 * a_51
887            + a_05 * a_14 * a_22 * a_31 * a_40 * a_53
888            - a_05 * a_14 * a_22 * a_31 * a_43 * a_50
889            - a_05 * a_14 * a_22 * a_33 * a_40 * a_51
890            + a_05 * a_14 * a_22 * a_33 * a_41 * a_50
891            + a_05 * a_14 * a_23 * a_30 * a_41 * a_52
892            - a_05 * a_14 * a_23 * a_30 * a_42 * a_51
893            - a_05 * a_14 * a_23 * a_31 * a_40 * a_52
894            + a_05 * a_14 * a_23 * a_31 * a_42 * a_50
895            + a_05 * a_14 * a_23 * a_32 * a_40 * a_51
896            - a_05 * a_14 * a_23 * a_32 * a_41 * a_50
897    }
898    ///
899    /// Calculate the inverse of the M66 via tha Adjoint Matrix:
900    ///
901    /// A^(-1) = (1/det) * Adj
902    ///
903    /// where: Adj = Cofactor.Transpose()
904    ///
905    /// Cofactor = (-1)^(i+j) * M(i, j).det()
906    #[inline(always)]
907    fn inverse(&self) -> Option<Self> {
908        let one = T::one();
909        let det = self.det();
910        if !nearly_zero(det) {
911            let mut cofactors: M66<T> = M66::zeros();
912            for i in 0..6 {
913                for j in 0..6 {
914                    let sign = if (i + j) % 2 == 0 {one} else {-one};
915                    // transpose in place
916                    cofactors[(j, i)] = sign * self.get_submatrix((i, j)).det();
917                }
918            }
919            Some(cofactors * det.recip())
920        } else {
921            None
922        }
923    }
924
925    /// Calculate de QR factorization of the M66 via gram-schmidt
926    /// orthogonalization process
927    fn qr(&self) -> Option<(Self, Self)> {
928        if !nearly_zero(self.det()) {
929            let cols = self.get_cols();
930            let mut q: [V6<T>; 6] = *M66::zeros().get_cols();
931            for i in 0..q.len() {
932                let mut q_tilde = cols[i];
933                for elem in q.iter().take(i) {
934                    q_tilde -= *elem * project_x_over_y(&*cols[i], &**elem);
935                }
936                normalize(&mut *q_tilde);
937                q[i] = q_tilde;
938            }
939            // TODO(elsuizo:2020-08-05): do this with a another for loop
940            let basis = V6::new_from(q[0], q[1], q[2], q[3], q[4], q[5]);
941            let q     = M66::new_from_vecs(basis);
942            let r     = q.transpose() * (*self);
943            Some((q, r))
944        } else {
945            None
946        }
947    }
948
949}
950
951// TODO(elsuizo:2020-08-29): check with this in the future!!!
952// impl<T: Float> M66<T> {
953//
954//     const fn get_sign(i: usize, j: usize) -> T {
955//         let one = T::one();
956//
957//         let m = m66_new!(one,-one, one,-one, one,-one;
958//                         -one, one,-one, one,-one, one;
959//                          one,-one, one,-one, one,-one;
960//                         -one, one,-one, one,-one, one;
961//                          one,-one, one,-one, one,-one;
962//                         -one, one,-one, one,-one, one);
963//         m[(i, j)]
964//     }
965//
966// }
967
968
969// M66 + M66
970impl<T: Num + Copy> Add for M66<T> {
971    type Output = Self;
972
973    fn add(self, rhs: Self) -> Self {
974        let a_00 = self[(0, 0)];
975        let a_01 = self[(0, 1)];
976        let a_02 = self[(0, 2)];
977        let a_03 = self[(0, 3)];
978        let a_04 = self[(0, 4)];
979        let a_05 = self[(0, 5)];
980        let a_10 = self[(1, 0)];
981        let a_11 = self[(1, 1)];
982        let a_12 = self[(1, 2)];
983        let a_13 = self[(1, 3)];
984        let a_14 = self[(1, 4)];
985        let a_15 = self[(1, 5)];
986        let a_20 = self[(2, 0)];
987        let a_21 = self[(2, 1)];
988        let a_22 = self[(2, 2)];
989        let a_23 = self[(2, 3)];
990        let a_24 = self[(2, 4)];
991        let a_25 = self[(2, 5)];
992        let a_30 = self[(3, 0)];
993        let a_31 = self[(3, 1)];
994        let a_32 = self[(3, 2)];
995        let a_33 = self[(3, 3)];
996        let a_34 = self[(3, 4)];
997        let a_35 = self[(3, 5)];
998        let a_40 = self[(4, 0)];
999        let a_41 = self[(4, 1)];
1000        let a_42 = self[(4, 2)];
1001        let a_43 = self[(4, 3)];
1002        let a_44 = self[(4, 4)];
1003        let a_45 = self[(4, 5)];
1004        let a_50 = self[(5, 0)];
1005        let a_51 = self[(5, 1)];
1006        let a_52 = self[(5, 2)];
1007        let a_53 = self[(5, 3)];
1008        let a_54 = self[(5, 4)];
1009        let a_55 = self[(5, 5)];
1010
1011        let b_00 = rhs[(0, 0)];
1012        let b_01 = rhs[(0, 1)];
1013        let b_02 = rhs[(0, 2)];
1014        let b_03 = rhs[(0, 3)];
1015        let b_04 = rhs[(0, 4)];
1016        let b_05 = rhs[(0, 5)];
1017        let b_10 = rhs[(1, 0)];
1018        let b_11 = rhs[(1, 1)];
1019        let b_12 = rhs[(1, 2)];
1020        let b_13 = rhs[(1, 3)];
1021        let b_14 = rhs[(1, 4)];
1022        let b_15 = rhs[(1, 5)];
1023        let b_20 = rhs[(2, 0)];
1024        let b_21 = rhs[(2, 1)];
1025        let b_22 = rhs[(2, 2)];
1026        let b_23 = rhs[(2, 3)];
1027        let b_24 = rhs[(2, 4)];
1028        let b_25 = rhs[(2, 5)];
1029        let b_30 = rhs[(3, 0)];
1030        let b_31 = rhs[(3, 1)];
1031        let b_32 = rhs[(3, 2)];
1032        let b_33 = rhs[(3, 3)];
1033        let b_34 = rhs[(3, 4)];
1034        let b_35 = rhs[(3, 5)];
1035        let b_40 = rhs[(4, 0)];
1036        let b_41 = rhs[(4, 1)];
1037        let b_42 = rhs[(4, 2)];
1038        let b_43 = rhs[(4, 3)];
1039        let b_44 = rhs[(4, 4)];
1040        let b_45 = rhs[(4, 5)];
1041        let b_50 = rhs[(5, 0)];
1042        let b_51 = rhs[(5, 1)];
1043        let b_52 = rhs[(5, 2)];
1044        let b_53 = rhs[(5, 3)];
1045        let b_54 = rhs[(5, 4)];
1046        let b_55 = rhs[(5, 5)];
1047
1048        M66::new([
1049            [
1050                a_00 + b_00,
1051                a_01 + b_01,
1052                a_02 + b_02,
1053                a_03 + b_03,
1054                a_04 + b_04,
1055                a_05 + b_05,
1056            ],
1057            [
1058                a_10 + b_10,
1059                a_11 + b_11,
1060                a_12 + b_12,
1061                a_13 + b_13,
1062                a_14 + b_14,
1063                a_15 + b_15,
1064            ],
1065            [
1066                a_20 + b_20,
1067                a_21 + b_21,
1068                a_22 + b_22,
1069                a_23 + b_23,
1070                a_24 + b_24,
1071                a_25 + b_25,
1072            ],
1073            [
1074                a_30 + b_30,
1075                a_31 + b_31,
1076                a_32 + b_32,
1077                a_33 + b_33,
1078                a_34 + b_34,
1079                a_35 + b_35,
1080            ],
1081            [
1082                a_40 + b_40,
1083                a_41 + b_41,
1084                a_42 + b_42,
1085                a_43 + b_43,
1086                a_44 + b_44,
1087                a_45 + b_45,
1088            ],
1089            [
1090                a_50 + b_50,
1091                a_51 + b_51,
1092                a_52 + b_52,
1093                a_53 + b_53,
1094                a_54 + b_54,
1095                a_55 + b_55,
1096            ],
1097        ])
1098    }
1099}
1100
1101// M66 += M66
1102impl<T: Num + Copy> AddAssign for M66<T> {
1103    fn add_assign(&mut self, other: Self) {
1104        *self = *self + other
1105    }
1106}
1107
1108// M66 - M66
1109impl<T: Num + Copy> Sub for M66<T> {
1110    type Output = Self;
1111
1112    fn sub(self, rhs: Self) -> Self {
1113        let a_00 = self[(0, 0)];
1114        let a_01 = self[(0, 1)];
1115        let a_02 = self[(0, 2)];
1116        let a_03 = self[(0, 3)];
1117        let a_04 = self[(0, 4)];
1118        let a_05 = self[(0, 5)];
1119        let a_10 = self[(1, 0)];
1120        let a_11 = self[(1, 1)];
1121        let a_12 = self[(1, 2)];
1122        let a_13 = self[(1, 3)];
1123        let a_14 = self[(1, 4)];
1124        let a_15 = self[(1, 5)];
1125        let a_20 = self[(2, 0)];
1126        let a_21 = self[(2, 1)];
1127        let a_22 = self[(2, 2)];
1128        let a_23 = self[(2, 3)];
1129        let a_24 = self[(2, 4)];
1130        let a_25 = self[(2, 5)];
1131        let a_30 = self[(3, 0)];
1132        let a_31 = self[(3, 1)];
1133        let a_32 = self[(3, 2)];
1134        let a_33 = self[(3, 3)];
1135        let a_34 = self[(3, 4)];
1136        let a_35 = self[(3, 5)];
1137        let a_40 = self[(4, 0)];
1138        let a_41 = self[(4, 1)];
1139        let a_42 = self[(4, 2)];
1140        let a_43 = self[(4, 3)];
1141        let a_44 = self[(4, 4)];
1142        let a_45 = self[(4, 5)];
1143        let a_50 = self[(5, 0)];
1144        let a_51 = self[(5, 1)];
1145        let a_52 = self[(5, 2)];
1146        let a_53 = self[(5, 3)];
1147        let a_54 = self[(5, 4)];
1148        let a_55 = self[(5, 5)];
1149
1150        let b_00 = rhs[(0, 0)];
1151        let b_01 = rhs[(0, 1)];
1152        let b_02 = rhs[(0, 2)];
1153        let b_03 = rhs[(0, 3)];
1154        let b_04 = rhs[(0, 4)];
1155        let b_05 = rhs[(0, 5)];
1156        let b_10 = rhs[(1, 0)];
1157        let b_11 = rhs[(1, 1)];
1158        let b_12 = rhs[(1, 2)];
1159        let b_13 = rhs[(1, 3)];
1160        let b_14 = rhs[(1, 4)];
1161        let b_15 = rhs[(1, 5)];
1162        let b_20 = rhs[(2, 0)];
1163        let b_21 = rhs[(2, 1)];
1164        let b_22 = rhs[(2, 2)];
1165        let b_23 = rhs[(2, 3)];
1166        let b_24 = rhs[(2, 4)];
1167        let b_25 = rhs[(2, 5)];
1168        let b_30 = rhs[(3, 0)];
1169        let b_31 = rhs[(3, 1)];
1170        let b_32 = rhs[(3, 2)];
1171        let b_33 = rhs[(3, 3)];
1172        let b_34 = rhs[(3, 4)];
1173        let b_35 = rhs[(3, 5)];
1174        let b_40 = rhs[(4, 0)];
1175        let b_41 = rhs[(4, 1)];
1176        let b_42 = rhs[(4, 2)];
1177        let b_43 = rhs[(4, 3)];
1178        let b_44 = rhs[(4, 4)];
1179        let b_45 = rhs[(4, 5)];
1180        let b_50 = rhs[(5, 0)];
1181        let b_51 = rhs[(5, 1)];
1182        let b_52 = rhs[(5, 2)];
1183        let b_53 = rhs[(5, 3)];
1184        let b_54 = rhs[(5, 4)];
1185        let b_55 = rhs[(5, 5)];
1186
1187        M66::new([
1188            [
1189                a_00 - b_00,
1190                a_01 - b_01,
1191                a_02 - b_02,
1192                a_03 - b_03,
1193                a_04 - b_04,
1194                a_05 - b_05,
1195            ],
1196            [
1197                a_10 - b_10,
1198                a_11 - b_11,
1199                a_12 - b_12,
1200                a_13 - b_13,
1201                a_14 - b_14,
1202                a_15 - b_15,
1203            ],
1204            [
1205                a_20 - b_20,
1206                a_21 - b_21,
1207                a_22 - b_22,
1208                a_23 - b_23,
1209                a_24 - b_24,
1210                a_25 - b_25,
1211            ],
1212            [
1213                a_30 - b_30,
1214                a_31 - b_31,
1215                a_32 - b_32,
1216                a_33 - b_33,
1217                a_34 - b_34,
1218                a_35 - b_35,
1219            ],
1220            [
1221                a_40 - b_40,
1222                a_41 - b_41,
1223                a_42 - b_42,
1224                a_43 - b_43,
1225                a_44 - b_44,
1226                a_45 - b_45,
1227            ],
1228            [
1229                a_50 - b_50,
1230                a_51 - b_51,
1231                a_52 - b_52,
1232                a_53 - b_53,
1233                a_54 - b_54,
1234                a_55 - b_55,
1235            ],
1236        ])
1237    }
1238}
1239
1240// M66 -= M66
1241impl<T: Num + Copy> SubAssign for M66<T> {
1242    fn sub_assign(&mut self, other: Self) {
1243        *self = *self - other
1244    }
1245}
1246
1247// M66 * T
1248impl<T: Num + Copy> Mul<T> for M66<T> {
1249    type Output = M66<T>;
1250
1251    fn mul(self, rhs: T) -> M66<T> {
1252        let a_00 = self[(0, 0)] * rhs;
1253        let a_01 = self[(0, 1)] * rhs;
1254        let a_02 = self[(0, 2)] * rhs;
1255        let a_03 = self[(0, 3)] * rhs;
1256        let a_04 = self[(0, 4)] * rhs;
1257        let a_05 = self[(0, 5)] * rhs;
1258        let a_10 = self[(1, 0)] * rhs;
1259        let a_11 = self[(1, 1)] * rhs;
1260        let a_12 = self[(1, 2)] * rhs;
1261        let a_13 = self[(1, 3)] * rhs;
1262        let a_14 = self[(1, 4)] * rhs;
1263        let a_15 = self[(1, 5)] * rhs;
1264        let a_20 = self[(2, 0)] * rhs;
1265        let a_21 = self[(2, 1)] * rhs;
1266        let a_22 = self[(2, 2)] * rhs;
1267        let a_23 = self[(2, 3)] * rhs;
1268        let a_24 = self[(2, 4)] * rhs;
1269        let a_25 = self[(2, 5)] * rhs;
1270        let a_30 = self[(3, 0)] * rhs;
1271        let a_31 = self[(3, 1)] * rhs;
1272        let a_32 = self[(3, 2)] * rhs;
1273        let a_33 = self[(3, 3)] * rhs;
1274        let a_34 = self[(3, 4)] * rhs;
1275        let a_35 = self[(3, 5)] * rhs;
1276        let a_40 = self[(4, 0)] * rhs;
1277        let a_41 = self[(4, 1)] * rhs;
1278        let a_42 = self[(4, 2)] * rhs;
1279        let a_43 = self[(4, 3)] * rhs;
1280        let a_44 = self[(4, 4)] * rhs;
1281        let a_45 = self[(4, 5)] * rhs;
1282        let a_50 = self[(5, 0)] * rhs;
1283        let a_51 = self[(5, 1)] * rhs;
1284        let a_52 = self[(5, 2)] * rhs;
1285        let a_53 = self[(5, 3)] * rhs;
1286        let a_54 = self[(5, 4)] * rhs;
1287        let a_55 = self[(5, 5)] * rhs;
1288
1289        M66::new([
1290            [a_00, a_01, a_02, a_03, a_04, a_05],
1291            [a_10, a_11, a_12, a_13, a_14, a_15],
1292            [a_20, a_21, a_22, a_23, a_24, a_25],
1293            [a_30, a_31, a_32, a_33, a_34, a_35],
1294            [a_40, a_41, a_42, a_43, a_44, a_45],
1295            [a_50, a_51, a_52, a_53, a_54, a_55],
1296        ])
1297    }
1298}
1299
1300// M66 / constant
1301impl<T: Num + Copy> Div<T> for M66<T> {
1302    type Output = Self;
1303
1304    fn div(self, rhs: T) -> Self::Output {
1305        let a_00 = self[(0, 0)] / rhs;
1306        let a_01 = self[(0, 1)] / rhs;
1307        let a_02 = self[(0, 2)] / rhs;
1308        let a_03 = self[(0, 3)] / rhs;
1309        let a_04 = self[(0, 4)] / rhs;
1310        let a_05 = self[(0, 5)] / rhs;
1311        let a_10 = self[(1, 0)] / rhs;
1312        let a_11 = self[(1, 1)] / rhs;
1313        let a_12 = self[(1, 2)] / rhs;
1314        let a_13 = self[(1, 3)] / rhs;
1315        let a_14 = self[(1, 4)] / rhs;
1316        let a_15 = self[(1, 5)] / rhs;
1317        let a_20 = self[(2, 0)] / rhs;
1318        let a_21 = self[(2, 1)] / rhs;
1319        let a_22 = self[(2, 2)] / rhs;
1320        let a_23 = self[(2, 3)] / rhs;
1321        let a_24 = self[(2, 4)] / rhs;
1322        let a_25 = self[(2, 5)] / rhs;
1323        let a_30 = self[(3, 0)] / rhs;
1324        let a_31 = self[(3, 1)] / rhs;
1325        let a_32 = self[(3, 2)] / rhs;
1326        let a_33 = self[(3, 3)] / rhs;
1327        let a_34 = self[(3, 4)] / rhs;
1328        let a_35 = self[(3, 5)] / rhs;
1329        let a_40 = self[(4, 0)] / rhs;
1330        let a_41 = self[(4, 1)] / rhs;
1331        let a_42 = self[(4, 2)] / rhs;
1332        let a_43 = self[(4, 3)] / rhs;
1333        let a_44 = self[(4, 4)] / rhs;
1334        let a_45 = self[(4, 5)] / rhs;
1335        let a_50 = self[(5, 0)] / rhs;
1336        let a_51 = self[(5, 1)] / rhs;
1337        let a_52 = self[(5, 2)] / rhs;
1338        let a_53 = self[(5, 3)] / rhs;
1339        let a_54 = self[(5, 4)] / rhs;
1340        let a_55 = self[(5, 5)] / rhs;
1341
1342        M66::new([
1343            [a_00, a_01, a_02, a_03, a_04, a_05],
1344            [a_10, a_11, a_12, a_13, a_14, a_15],
1345            [a_20, a_21, a_22, a_23, a_24, a_25],
1346            [a_30, a_31, a_32, a_33, a_34, a_35],
1347            [a_40, a_41, a_42, a_43, a_44, a_45],
1348            [a_50, a_51, a_52, a_53, a_54, a_55],
1349        ])
1350    }
1351}
1352
1353// -M66
1354impl<T: Num + Copy + Signed> Neg for M66<T> {
1355    type Output = Self;
1356
1357    fn neg(self) -> Self {
1358        let a_00 = -self[(0, 0)];
1359        let a_01 = -self[(0, 1)];
1360        let a_02 = -self[(0, 2)];
1361        let a_03 = -self[(0, 3)];
1362        let a_04 = -self[(0, 4)];
1363        let a_05 = -self[(0, 5)];
1364        let a_10 = -self[(1, 0)];
1365        let a_11 = -self[(1, 1)];
1366        let a_12 = -self[(1, 2)];
1367        let a_13 = -self[(1, 3)];
1368        let a_14 = -self[(1, 4)];
1369        let a_15 = -self[(1, 5)];
1370        let a_20 = -self[(2, 0)];
1371        let a_21 = -self[(2, 1)];
1372        let a_22 = -self[(2, 2)];
1373        let a_23 = -self[(2, 3)];
1374        let a_24 = -self[(2, 4)];
1375        let a_25 = -self[(2, 5)];
1376        let a_30 = -self[(3, 0)];
1377        let a_31 = -self[(3, 1)];
1378        let a_32 = -self[(3, 2)];
1379        let a_33 = -self[(3, 3)];
1380        let a_34 = -self[(3, 4)];
1381        let a_35 = -self[(3, 5)];
1382        let a_40 = -self[(4, 0)];
1383        let a_41 = -self[(4, 1)];
1384        let a_42 = -self[(4, 2)];
1385        let a_43 = -self[(4, 3)];
1386        let a_44 = -self[(4, 4)];
1387        let a_45 = -self[(4, 5)];
1388        let a_50 = -self[(5, 0)];
1389        let a_51 = -self[(5, 1)];
1390        let a_52 = -self[(5, 2)];
1391        let a_53 = -self[(5, 3)];
1392        let a_54 = -self[(5, 4)];
1393        let a_55 = -self[(5, 5)];
1394
1395    M66::new([
1396        [a_00, a_01, a_02, a_03, a_04, a_05],
1397        [a_10, a_11, a_12, a_13, a_14, a_15],
1398        [a_20, a_21, a_22, a_23, a_24, a_25],
1399        [a_30, a_31, a_32, a_33, a_34, a_35],
1400        [a_40, a_41, a_42, a_43, a_44, a_45],
1401        [a_50, a_51, a_52, a_53, a_54, a_55],
1402    ])
1403    }
1404}
1405
1406// M66 * V6
1407impl<T: Num + Copy> Mul<V6<T>> for M66<T> {
1408    type Output = V6<T>;
1409
1410    #[inline]
1411    fn mul(self, rhs: V6<T>) -> V6<T> {
1412
1413        let rhs_0 = rhs[0];
1414        let rhs_1 = rhs[1];
1415        let rhs_2 = rhs[2];
1416        let rhs_3 = rhs[3];
1417        let rhs_4 = rhs[4];
1418        let rhs_5 = rhs[5];
1419
1420        let v0 = self[(0, 0)] * rhs_0 + self[(0, 1)] * rhs_1 + self[(0, 2)] * rhs_2 + self[(0, 3)] * rhs_3 + self[(0, 4)] * rhs_4 + self[(0, 5)] * rhs_5;
1421        let v1 = self[(1, 0)] * rhs_0 + self[(1, 1)] * rhs_1 + self[(1, 2)] * rhs_2 + self[(1, 3)] * rhs_3 + self[(1, 4)] * rhs_4 + self[(1, 5)] * rhs_5;
1422        let v2 = self[(2, 0)] * rhs_0 + self[(2, 1)] * rhs_1 + self[(2, 2)] * rhs_2 + self[(2, 3)] * rhs_3 + self[(2, 4)] * rhs_4 + self[(2, 5)] * rhs_5;
1423        let v3 = self[(3, 0)] * rhs_0 + self[(3, 1)] * rhs_1 + self[(3, 2)] * rhs_2 + self[(3, 3)] * rhs_3 + self[(3, 4)] * rhs_4 + self[(3, 5)] * rhs_5;
1424        let v4 = self[(4, 0)] * rhs_0 + self[(4, 1)] * rhs_1 + self[(4, 2)] * rhs_2 + self[(4, 3)] * rhs_3 + self[(4, 4)] * rhs_4 + self[(4, 5)] * rhs_5;
1425        let v5 = self[(5, 0)] * rhs_0 + self[(5, 1)] * rhs_1 + self[(5, 2)] * rhs_2 + self[(5, 3)] * rhs_3 + self[(5, 4)] * rhs_4 + self[(5, 5)] * rhs_5;
1426
1427        V6::new_from(v0, v1, v2, v3, v4, v5)
1428    }
1429
1430}
1431
1432// M66 * M66
1433impl<T: Num + Copy> Mul for M66<T> {
1434    type Output = Self;
1435
1436    fn mul(self, rhs: Self) -> Self {
1437        let a_00 = self[(0, 0)];
1438        let a_01 = self[(0, 1)];
1439        let a_02 = self[(0, 2)];
1440        let a_03 = self[(0, 3)];
1441        let a_04 = self[(0, 4)];
1442        let a_05 = self[(0, 5)];
1443        let a_10 = self[(1, 0)];
1444        let a_11 = self[(1, 1)];
1445        let a_12 = self[(1, 2)];
1446        let a_13 = self[(1, 3)];
1447        let a_14 = self[(1, 4)];
1448        let a_15 = self[(1, 5)];
1449        let a_20 = self[(2, 0)];
1450        let a_21 = self[(2, 1)];
1451        let a_22 = self[(2, 2)];
1452        let a_23 = self[(2, 3)];
1453        let a_24 = self[(2, 4)];
1454        let a_25 = self[(2, 5)];
1455        let a_30 = self[(3, 0)];
1456        let a_31 = self[(3, 1)];
1457        let a_32 = self[(3, 2)];
1458        let a_33 = self[(3, 3)];
1459        let a_34 = self[(3, 4)];
1460        let a_35 = self[(3, 5)];
1461        let a_40 = self[(4, 0)];
1462        let a_41 = self[(4, 1)];
1463        let a_42 = self[(4, 2)];
1464        let a_43 = self[(4, 3)];
1465        let a_44 = self[(4, 4)];
1466        let a_45 = self[(4, 5)];
1467        let a_50 = self[(5, 0)];
1468        let a_51 = self[(5, 1)];
1469        let a_52 = self[(5, 2)];
1470        let a_53 = self[(5, 3)];
1471        let a_54 = self[(5, 4)];
1472        let a_55 = self[(5, 5)];
1473
1474        let b_00 = rhs[(0, 0)];
1475        let b_01 = rhs[(0, 1)];
1476        let b_02 = rhs[(0, 2)];
1477        let b_03 = rhs[(0, 3)];
1478        let b_04 = rhs[(0, 4)];
1479        let b_05 = rhs[(0, 5)];
1480        let b_10 = rhs[(1, 0)];
1481        let b_11 = rhs[(1, 1)];
1482        let b_12 = rhs[(1, 2)];
1483        let b_13 = rhs[(1, 3)];
1484        let b_14 = rhs[(1, 4)];
1485        let b_15 = rhs[(1, 5)];
1486        let b_20 = rhs[(2, 0)];
1487        let b_21 = rhs[(2, 1)];
1488        let b_22 = rhs[(2, 2)];
1489        let b_23 = rhs[(2, 3)];
1490        let b_24 = rhs[(2, 4)];
1491        let b_25 = rhs[(2, 5)];
1492        let b_30 = rhs[(3, 0)];
1493        let b_31 = rhs[(3, 1)];
1494        let b_32 = rhs[(3, 2)];
1495        let b_33 = rhs[(3, 3)];
1496        let b_34 = rhs[(3, 4)];
1497        let b_35 = rhs[(3, 5)];
1498        let b_40 = rhs[(4, 0)];
1499        let b_41 = rhs[(4, 1)];
1500        let b_42 = rhs[(4, 2)];
1501        let b_43 = rhs[(4, 3)];
1502        let b_44 = rhs[(4, 4)];
1503        let b_45 = rhs[(4, 5)];
1504        let b_50 = rhs[(5, 0)];
1505        let b_51 = rhs[(5, 1)];
1506        let b_52 = rhs[(5, 2)];
1507        let b_53 = rhs[(5, 3)];
1508        let b_54 = rhs[(5, 4)];
1509        let b_55 = rhs[(5, 5)];
1510
1511        M66::new([
1512            [
1513                a_00 * b_00 + a_01 * b_10 + a_02 * b_20 + a_03 * b_30 + a_04 * b_40 + a_05 * b_50,
1514                a_00 * b_01 + a_01 * b_11 + a_02 * b_21 + a_03 * b_31 + a_04 * b_41 + a_05 * b_51,
1515                a_00 * b_02 + a_01 * b_12 + a_02 * b_22 + a_03 * b_32 + a_04 * b_42 + a_05 * b_52,
1516                a_00 * b_03 + a_01 * b_13 + a_02 * b_23 + a_03 * b_33 + a_04 * b_43 + a_05 * b_53,
1517                a_00 * b_04 + a_01 * b_14 + a_02 * b_24 + a_03 * b_34 + a_04 * b_44 + a_05 * b_54,
1518                a_00 * b_05 + a_01 * b_15 + a_02 * b_25 + a_03 * b_35 + a_04 * b_45 + a_05 * b_55,
1519            ],
1520            [
1521                a_10 * b_00 + a_11 * b_10 + a_12 * b_20 + a_13 * b_30 + a_14 * b_40 + a_15 * b_50,
1522                a_10 * b_01 + a_11 * b_11 + a_12 * b_21 + a_13 * b_31 + a_14 * b_41 + a_15 * b_51,
1523                a_10 * b_02 + a_11 * b_12 + a_12 * b_22 + a_13 * b_32 + a_14 * b_42 + a_15 * b_52,
1524                a_10 * b_03 + a_11 * b_13 + a_12 * b_23 + a_13 * b_33 + a_14 * b_43 + a_15 * b_53,
1525                a_10 * b_04 + a_11 * b_14 + a_12 * b_24 + a_13 * b_34 + a_14 * b_44 + a_15 * b_54,
1526                a_10 * b_05 + a_11 * b_15 + a_12 * b_25 + a_13 * b_35 + a_14 * b_45 + a_15 * b_55,
1527            ],
1528            [
1529                a_20 * b_00 + a_21 * b_10 + a_22 * b_20 + a_23 * b_30 + a_24 * b_40 + a_25 * b_50,
1530                a_20 * b_01 + a_21 * b_11 + a_22 * b_21 + a_23 * b_31 + a_24 * b_41 + a_25 * b_51,
1531                a_20 * b_02 + a_21 * b_12 + a_22 * b_22 + a_23 * b_32 + a_24 * b_42 + a_25 * b_52,
1532                a_20 * b_03 + a_21 * b_13 + a_22 * b_23 + a_23 * b_33 + a_24 * b_43 + a_25 * b_53,
1533                a_20 * b_04 + a_21 * b_14 + a_22 * b_24 + a_23 * b_34 + a_24 * b_44 + a_25 * b_54,
1534                a_20 * b_05 + a_21 * b_15 + a_22 * b_25 + a_23 * b_35 + a_24 * b_45 + a_25 * b_55,
1535            ],
1536            [
1537                a_30 * b_00 + a_31 * b_10 + a_32 * b_20 + a_33 * b_30 + a_34 * b_40 + a_35 * b_50,
1538                a_30 * b_01 + a_31 * b_11 + a_32 * b_21 + a_33 * b_31 + a_34 * b_41 + a_35 * b_51,
1539                a_30 * b_02 + a_31 * b_12 + a_32 * b_22 + a_33 * b_32 + a_34 * b_42 + a_35 * b_52,
1540                a_30 * b_03 + a_31 * b_13 + a_32 * b_23 + a_33 * b_33 + a_34 * b_43 + a_35 * b_53,
1541                a_30 * b_04 + a_31 * b_14 + a_32 * b_24 + a_33 * b_34 + a_34 * b_44 + a_35 * b_54,
1542                a_30 * b_05 + a_31 * b_15 + a_32 * b_25 + a_33 * b_35 + a_34 * b_45 + a_35 * b_55,
1543            ],
1544            [
1545                a_40 * b_00 + a_41 * b_10 + a_42 * b_20 + a_43 * b_30 + a_44 * b_40 + a_45 * b_50,
1546                a_40 * b_01 + a_41 * b_11 + a_42 * b_21 + a_43 * b_31 + a_44 * b_41 + a_45 * b_51,
1547                a_40 * b_02 + a_41 * b_12 + a_42 * b_22 + a_43 * b_32 + a_44 * b_42 + a_45 * b_52,
1548                a_40 * b_03 + a_41 * b_13 + a_42 * b_23 + a_43 * b_33 + a_44 * b_43 + a_45 * b_53,
1549                a_40 * b_04 + a_41 * b_14 + a_42 * b_24 + a_43 * b_34 + a_44 * b_44 + a_45 * b_54,
1550                a_40 * b_05 + a_41 * b_15 + a_42 * b_25 + a_43 * b_35 + a_44 * b_45 + a_45 * b_55,
1551            ],
1552            [
1553                a_50 * b_00 + a_51 * b_10 + a_52 * b_20 + a_53 * b_30 + a_54 * b_40 + a_55 * b_50,
1554                a_50 * b_01 + a_51 * b_11 + a_52 * b_21 + a_53 * b_31 + a_54 * b_41 + a_55 * b_51,
1555                a_50 * b_02 + a_51 * b_12 + a_52 * b_22 + a_53 * b_32 + a_54 * b_42 + a_55 * b_52,
1556                a_50 * b_03 + a_51 * b_13 + a_52 * b_23 + a_53 * b_33 + a_54 * b_43 + a_55 * b_53,
1557                a_50 * b_04 + a_51 * b_14 + a_52 * b_24 + a_53 * b_34 + a_54 * b_44 + a_55 * b_54,
1558                a_50 * b_05 + a_51 * b_15 + a_52 * b_25 + a_53 * b_35 + a_54 * b_45 + a_55 * b_55,
1559            ],
1560        ])
1561    }
1562}
1563
1564impl<T: Num + Copy> M66<T> {
1565    /// contruct identity matrix
1566    pub fn identity() -> M66<T> {
1567        <M66<T> as One>::one()
1568    }
1569
1570    /// construct the matrix with all zeros
1571    pub fn zeros() -> M66<T> {
1572        <M66<T> as Zero>::zero()
1573    }
1574
1575    /// transform the matrix to a flatten vector
1576    pub fn as_vec(&self) -> [T; 36] {
1577        let mut result = [T::zero(); 36];
1578        for (index, element) in self.iter().flatten().enumerate() {
1579            result[index] = *element;
1580        }
1581        result
1582    }
1583
1584    /// get the diagonal of the matrix
1585    pub fn get_diagonal(&self) -> V6<T> {
1586        let mut result = V6::zeros();
1587        let mut index: usize = 0;
1588        for i in 0..self.rows() {
1589            for j in 0..self.cols() {
1590                if i == j {
1591                    result[index] = self[(i, j)];
1592                    index += 1;
1593                }
1594            }
1595        }
1596        result
1597    }
1598
1599    pub fn new_from_vecs(cols: V6<V6<T>>) -> Self {
1600        let mut result = Self::zeros();
1601
1602        for i in 0..result.cols() {
1603            result[(i, 0)] = cols[0][i];
1604            result[(i, 1)] = cols[1][i];
1605            result[(i, 2)] = cols[2][i];
1606            result[(i, 3)] = cols[3][i];
1607            result[(i, 4)] = cols[4][i];
1608            result[(i, 5)] = cols[5][i];
1609        }
1610        result
1611    }
1612
1613    /// get the a submatrix from discard row `i` and column `j`
1614    ///
1615    fn get_submatrix(&self, selected: (usize, usize)) -> M55<T> {
1616        let mut values: [T; 25] = [T::zero(); 25];
1617        let mut result: M55<T> = M55::zeros();
1618        let mut index: usize = 0;
1619        for i in 0..6 {
1620            for j in 0..6 {
1621                if !(i == selected.0 || j == selected.1) {
1622                    values[index] = self[(i, j)];
1623                    index += 1;
1624                }
1625            }
1626        }
1627        index = 0;
1628        for r in 0.. 5 {
1629            for c in 0..5 {
1630                result[(r, c)] = values[index];
1631                index += 1;
1632            }
1633        }
1634        result
1635    }
1636
1637    pub fn get_rows(self) -> V6<V6<T>> {
1638        let mut r0 = V6::zeros();
1639        let mut r1 = V6::zeros();
1640        let mut r2 = V6::zeros();
1641        let mut r3 = V6::zeros();
1642        let mut r4 = V6::zeros();
1643        let mut r5 = V6::zeros();
1644
1645        for j in 0..self.rows() {
1646            r0[j] = self[(0, j)];
1647            r1[j] = self[(1, j)];
1648            r2[j] = self[(2, j)];
1649            r3[j] = self[(3, j)];
1650            r4[j] = self[(4, j)];
1651            r5[j] = self[(5, j)];
1652        }
1653        V6::new([r0, r1, r2, r3, r4, r5])
1654    }
1655
1656    pub fn get_cols(self) -> V6<V6<T>> {
1657        let mut c0 = V6::zeros();
1658        let mut c1 = V6::zeros();
1659        let mut c2 = V6::zeros();
1660        let mut c3 = V6::zeros();
1661        let mut c4 = V6::zeros();
1662        let mut c5 = V6::zeros();
1663
1664        for i in 0..self.cols() {
1665            c0[i] = self[(i, 0)];
1666            c1[i] = self[(i, 1)];
1667            c2[i] = self[(i, 2)];
1668            c3[i] = self[(i, 3)];
1669            c4[i] = self[(i, 4)];
1670            c5[i] = self[(i, 5)];
1671        }
1672        V6::new([c0, c1, c2, c3, c4, c5])
1673    }
1674
1675    pub fn get_upper_triangular(&self) -> [T; 15] {
1676        let zero = T::zero();
1677        let mut result: [T; 15] = [zero; 15];
1678        let mut index = 0;
1679        for i in 0..self.rows() {
1680            for j in 0..self.cols() {
1681                if i < j {
1682                    result[index] = self[(i, j)];
1683                    index += 1;
1684                }
1685            }
1686        }
1687        result
1688    }
1689
1690    pub fn get_lower_triangular(&self) -> [T; 15] {
1691        let zero = T::zero();
1692        let mut result: [T; 15] = [zero; 15];
1693        let mut index = 0;
1694        for i in 0..self.rows() {
1695            for j in 0..self.cols() {
1696                if i > j {
1697                    result[index] = self[(i, j)];
1698                    index += 1;
1699                }
1700            }
1701        }
1702        result
1703    }
1704
1705    /// Applies `f` of each element in the M66
1706    pub fn for_each(&self, f: impl Fn(T) -> T) -> Self {
1707        let mut result = Self::zeros();
1708        for i in 0..self.rows() {
1709            for j in 0..self.cols() {
1710                result[(i, j)] = f(self[(i, j)]);
1711            }
1712        }
1713        result
1714    }
1715
1716    /// Copy elements from a M33<T> matrix in one of the 4 cuadrants of the actual
1717    /// matrix, where the quadrants are enumerated as:
1718    /// +---+---+
1719    /// | 1 | 2 |
1720    /// +---+---+
1721    /// | 3 | 4 |
1722    /// +---+---+
1723    ///
1724    /// Function arguments:
1725    /// `r`: M33<T> submatrix elements to copy
1726    ///
1727    /// `quadrant`: number to choose the cuadrant where do the copy of the elements
1728    ///
1729    pub fn copy_elements_from(&mut self, r: &M33<T>, quadrant: usize) {
1730        match quadrant {
1731            1 => {
1732                for i in 0..3 {
1733                    for j in 0..3 {
1734                        self[(i, j)] = r[(i, j)];
1735                    }
1736                }
1737            },
1738            2 => {
1739                for i in 0..3 {
1740                    for j in 3..6 {
1741                        self[(i, j)] = r[(i, j-3)];
1742                    }
1743                }
1744            },
1745            3 => {
1746                for i in 3..6 {
1747                    for j in 0..3 {
1748                        self[(i, j)] = r[(i-3, j)];
1749                    }
1750                }
1751            },
1752            4 => {
1753                for i in 3..6 {
1754                    for j in 3..6 {
1755                        self[(i, j)] = r[(i-3, j-3)];
1756                    }
1757                }
1758            },
1759            _ => panic!("no more than 4 quadrants !!!")
1760        }
1761    }
1762}
1763
1764impl<T: Num + Copy> Zero for M66<T> {
1765    fn zero() -> M66<T> {
1766        M66::new([[T::zero(); 6]; 6])
1767    }
1768
1769    fn is_zero(&self) -> bool {
1770        *self == M66::zero()
1771    }
1772}
1773
1774impl<T: Num + Copy> One for M66<T> {
1775    /// Create an identity matrix
1776    #[inline]
1777    fn one() -> M66<T> {
1778        let one = T::one();
1779        let zero = T::zero();
1780        M66::new([
1781            [one, zero, zero, zero, zero, zero],
1782            [zero, one, zero, zero, zero, zero],
1783            [zero, zero, one, zero, zero, zero],
1784            [zero, zero, zero, one, zero, zero],
1785            [zero, zero, zero, zero, one, zero],
1786            [zero, zero, zero, zero, zero, one],
1787        ])
1788    }
1789}
1790//
1791impl<T> Deref for M66<T> {
1792    type Target = [[T; 6]; 6];
1793    #[inline]
1794    fn deref(&self) -> &Self::Target {
1795        &self.0
1796    }
1797}
1798
1799impl<T> DerefMut for M66<T> {
1800    #[inline]
1801    fn deref_mut(&mut self) -> &mut Self::Target {
1802        &mut self.0
1803    }
1804}
1805
1806impl<T> From<[[T; 6]; 6]> for M66<T> {
1807    fn from(data: [[T; 6]; 6]) -> M66<T> {
1808        M66(data)
1809    }
1810}
1811
1812impl<T> Index<(usize, usize)> for M66<T> {
1813    type Output = T;
1814    #[inline(always)]
1815    fn index(&self, index: (usize, usize)) -> &T {
1816        &self.0[index.0][index.1]
1817    }
1818}
1819
1820impl<T> IndexMut<(usize, usize)> for M66<T> {
1821    #[inline(always)]
1822    fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
1823        &mut self.0[index.0][index.1]
1824    }
1825}
1826
1827//-------------------------------------------------------------------------
1828//                        macros
1829//-------------------------------------------------------------------------
1830#[macro_export]
1831macro_rules! m66_new {
1832    ($($first_row:expr),*;
1833     $($second_row:expr),*;
1834     $($third_row:expr),*;
1835     $($fourth_row:expr),*;
1836     $($fifth_row:expr),*;
1837     $($sixth_row:expr),*
1838     ) => {
1839        M66::new([[$($first_row),*],
1840                 [$($second_row),*],
1841                 [$($third_row),*],
1842                 [$($fourth_row),*],
1843                 [$($fifth_row),*],
1844                 [$($sixth_row),*]])
1845    }
1846}
1847
1848//-------------------------------------------------------------------------
1849//                        Display
1850//-------------------------------------------------------------------------
1851impl<T: Num + fmt::Display> fmt::Display for M66<T> {
1852    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
1853        println!();
1854        writeln!(
1855            dest,
1856            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1857            self[(0, 0)],
1858            self[(0, 1)],
1859            self[(0, 2)],
1860            self[(0, 3)],
1861            self[(0, 4)],
1862            self[(0, 5)]
1863        )?;
1864        writeln!(
1865            dest,
1866            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1867            self[(1, 0)],
1868            self[(1, 1)],
1869            self[(1, 2)],
1870            self[(1, 3)],
1871            self[(1, 4)],
1872            self[(1, 5)]
1873        )?;
1874        writeln!(
1875            dest,
1876            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1877            self[(2, 0)],
1878            self[(2, 1)],
1879            self[(2, 2)],
1880            self[(2, 3)],
1881            self[(2, 4)],
1882            self[(2, 5)]
1883        )?;
1884        writeln!(
1885            dest,
1886            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1887            self[(3, 0)],
1888            self[(3, 1)],
1889            self[(3, 2)],
1890            self[(3, 3)],
1891            self[(3, 4)],
1892            self[(3, 5)]
1893        )?;
1894        writeln!(
1895            dest,
1896            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1897            self[(4, 0)],
1898            self[(4, 1)],
1899            self[(4, 2)],
1900            self[(4, 3)],
1901            self[(4, 4)],
1902            self[(4, 5)]
1903        )?;
1904        writeln!(
1905            dest,
1906            "|{0:<7.2} {1:^7.2} {2:^7.2} {3:^7.2} {4:^7.2} {5:>7.2}|",
1907            self[(5, 0)],
1908            self[(5, 1)],
1909            self[(5, 2)],
1910            self[(5, 3)],
1911            self[(5, 4)],
1912            self[(5, 5)]
1913        )
1914    }
1915}
1916
1917
1918//-------------------------------------------------------------------------
1919//                        tests
1920//-------------------------------------------------------------------------
1921#[cfg(test)]
1922mod test_matrix6x6 {
1923
1924    use crate::traits::LinearAlgebra;
1925    use crate::matrix6x6::M66;
1926    use crate::utils::nearly_equal;
1927    use crate::utils::compare_vecs;
1928    use crate::vector6::V6;
1929
1930    // TODO(elsuizo:2020-06-02): ver porque tenemos que bajar el EPS para que ande inverse()
1931    const EPS: f32 = 1e-4;
1932
1933    #[test]
1934    fn sub_test() {
1935        let m1 = m66_new!( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0;
1936                           6.0,  7.0,  8.0,  9.0, 10.0, 11.0;
1937                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0;
1938                          18.0, 19.0, 20.0, 21.0, 22.0, 23.0;
1939                          24.0, 25.0, 26.0, 27.0, 28.0, 29.0;
1940                          30.0, 31.0, 32.0, 33.0, 34.0, 35.0);
1941
1942        let m2 = m66_new!( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0;
1943                           6.0,  7.0,  8.0,  9.0, 10.0, 11.0;
1944                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0;
1945                          18.0, 19.0, 20.0, 21.0, 22.0, 23.0;
1946                          24.0, 25.0, 26.0, 27.0, 28.0, 29.0;
1947                          30.0, 31.0, 32.0, 33.0, 34.0, 35.0);
1948
1949        let result = m1 - m2;
1950        let expected = m66_new!( 0.0,  0.0,  0.0,  0.0,  0.0,  0.0;
1951                                 0.0,  0.0,  0.0,  0.0,  0.0,  0.0;
1952                                 0.0,  0.0,  0.0,  0.0,  0.0,  0.0;
1953                                 0.0,  0.0,  0.0,  0.0,  0.0,  0.0;
1954                                 0.0,  0.0,  0.0,  0.0,  0.0,  0.0;
1955                                 0.0,  0.0,  0.0,  0.0,  0.0,  0.0);
1956
1957        assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
1958    }
1959
1960    #[test]
1961    fn sum_test() {
1962        let m1 = m66_new!( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0;
1963                           6.0,  7.0,  8.0,  9.0, 10.0, 11.0;
1964                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0;
1965                          18.0, 19.0, 20.0, 21.0, 22.0, 23.0;
1966                          24.0, 25.0, 26.0, 27.0, 28.0, 29.0;
1967                          30.0, 31.0, 32.0, 33.0, 34.0, 35.0);
1968
1969        let m2 = m66_new!( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0;
1970                           6.0,  7.0,  8.0,  9.0, 10.0, 11.0;
1971                          12.0, 13.0, 14.0, 15.0, 16.0, 17.0;
1972                          18.0, 19.0, 20.0, 21.0, 22.0, 23.0;
1973                          24.0, 25.0, 26.0, 27.0, 28.0, 29.0;
1974                          30.0, 31.0, 32.0, 33.0, 34.0, 35.0);
1975
1976        let result = m1 + m2;
1977
1978        let expected = m66_new!( 0.0,  2.0,  4.0,   6.0,  8.0, 10.0;
1979                                12.0, 14.0, 16.0,  18.0, 20.0, 22.0;
1980                                24.0, 26.0, 28.0,  30.0, 32.0, 34.0;
1981                                36.0, 38.0, 40.0,  42.0, 44.0, 46.0;
1982                                48.0, 50.0, 52.0,  54.0, 56.0, 58.0;
1983                                60.0, 62.0, 64.0,  66.0, 68.0, 70.0);
1984
1985        assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
1986    }
1987
1988    #[test]
1989    fn matrix6x6_det_test() {
1990
1991        use super::test_matrix6x6::EPS;
1992
1993        // let m: M66<f64> = Matrix6x6::zeros();
1994        let m = M66::new([
1995            [1.0, 1.0, 3.0, 4.0, 9.0, 3.0],
1996            [10.0, 10.0, 1.0, 2.0, 2.0, 5.0],
1997            [2.0, 9.0, 6.0, 10.0, 10.0, 9.0],
1998            [10.0, 9.0, 9.0, 7.0, 3.0, 6.0],
1999            [7.0, 6.0, 6.0, 2.0, 9.0, 5.0],
2000            [3.0, 8.0, 1.0, 4.0, 1.0, 5.0],
2001        ]);
2002        let result = m.det();
2003        let expected = 3271.9999999999723;
2004        assert!(nearly_equal(result, expected, EPS));
2005    }
2006
2007    #[test]
2008    fn matrix6x6_mul_test() {
2009
2010        use super::test_matrix6x6::EPS;
2011
2012        let m = M66::new([
2013            [0.0, 1.0, 2.0, 3.0, 4.0, 5.0],
2014            [6.0, 7.0, 8.0, 9.0, 10.0, 11.0],
2015            [12.0, 13.0, 14.0, 15.0, 16.0, 17.0],
2016            [18.0, 19.0, 20.0, 21.0, 22.0, 23.0],
2017            [24.0, 25.0, 26.0, 27.0, 28.0, 29.0],
2018            [30.0, 31.0, 32.0, 33.0, 34.0, 35.0],
2019        ]);
2020        let result = m * m;
2021        let expected = M66::new([
2022            [330.0, 345.0, 360.0, 375.0, 390.0, 405.0],
2023            [870.0, 921.0, 972.0, 1023.0, 1074.0, 1125.0],
2024            [1410.0, 1497.0, 1584.0, 1671.0, 1758.0, 1845.0],
2025            [1950.0, 2073.0, 2196.0, 2319.0, 2442.0, 2565.0],
2026            [2490.0, 2649.0, 2808.0, 2967.0, 3126.0, 3285.0],
2027            [3030.0, 3225.0, 3420.0, 3615.0, 3810.0, 4005.0],
2028        ]);
2029
2030        assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
2031    }
2032
2033    #[test]
2034    fn matrix6x6_norm2_test() {
2035
2036        use super::test_matrix6x6::EPS;
2037
2038        let m = m66_new!( 0.0,  1.0,  2.0,  3.0,  4.0,  5.0;
2039                          6.0,  7.0,  8.0,  9.0, 10.0, 11.0;
2040                         12.0, 13.0, 14.0, 15.0, 16.0, 17.0;
2041                         18.0, 19.0, 20.0, 21.0, 22.0, 23.0;
2042                         24.0, 25.0, 26.0, 27.0, 28.0, 29.0;
2043                         30.0, 31.0, 32.0, 33.0, 34.0, 35.0);
2044
2045        let result = m.norm2();
2046        let expected = 122.10651088291729;
2047        assert!(nearly_equal(result, expected, EPS));
2048    }
2049
2050    #[test]
2051    fn matrix6x6_inv_test() {
2052
2053        use super::test_matrix6x6::EPS;
2054
2055        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2056                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2057                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2058                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2059                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2060                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2061
2062        let expected = m66_new!(-0.538814,  0.577934,  0.665342, -0.0837408, -0.169621, -1.18215;
2063                                  2.16076,  -1.52751,  -2.44071,    0.44132,  0.324572,  3.77017;
2064                                 0.214548, -0.415037, -0.394254,   0.147922,  0.197433, 0.621027;
2065                                 0.700183, -0.240526, -0.525978,   0.203545, -0.211797, 0.734719;
2066                                  0.85055, -0.471577, -0.827934,   0.110636,  0.114609,  1.20416;
2067                                 -3.90709,   2.46699,   4.17115,  -0.870416, -0.310513, -6.07579);
2068
2069        if let Some(result) = m.inverse() {
2070            assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
2071        }
2072    }
2073
2074    #[test]
2075    fn inverse_fail() {
2076        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2077                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2078                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2079                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2080                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2081                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2082
2083        let result = m.inverse();
2084        let expected = None;
2085        assert_eq!(result, expected);
2086
2087    }
2088
2089    #[test]
2090    fn mul_vec_rhs() {
2091        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2092                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2093                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2094                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2095                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2096                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2097
2098        let v = V6::new([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
2099        let result = m * v;
2100
2101        let expected = V6::new([70.0, 51.0, 136.0, 90.0, 85.0, 51.0]);
2102
2103        assert_eq!(
2104            &result[..],
2105            &expected[..],
2106            "\nExpected\n{:?}\nfound\n{:?}",
2107            &result[..],
2108            &expected[..]
2109        );
2110
2111
2112    }
2113
2114    #[test]
2115    fn get_cols_test() {
2116        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2117                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2118                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2119                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2120                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2121                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2122
2123        let result = m.get_cols();
2124        let expected0 = V6::new([1.0, 10.0, 2.0, 10.0, 7.0, 3.0]);
2125        let expected1 = V6::new([1.0, 10.0, 9.0, 9.0, 6.0, 8.0]);
2126        let expected2 = V6::new([3.0, 1.0, 6.0, 9.0, 6.0, 1.0]);
2127        let expected3 = V6::new([4.0, 2.0, 10.0, 7.0, 2.0, 4.0]);
2128        let expected4 = V6::new([9.0, 2.0, 10.0, 3.0, 9.0, 1.0]);
2129        let expected5 = V6::new([3.0, 5.0, 9.0, 6.0, 5.0, 5.0]);
2130
2131        let expected = V6::new([expected0, expected1, expected2, expected3, expected4, expected5]);
2132        assert_eq!(
2133            &result[..],
2134            &expected[..],
2135            "\nExpected\n{:?}\nfound\n{:?}",
2136            &result[..],
2137            &expected[..]
2138        );
2139    }
2140
2141    #[test]
2142    fn get_rows_test() {
2143        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2144                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2145                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2146                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2147                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2148                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2149
2150        let result = m.transpose().get_rows();
2151
2152        let expected0 = V6::new([1.0, 10.0, 2.0, 10.0, 7.0, 3.0]);
2153        let expected1 = V6::new([1.0, 10.0, 9.0, 9.0, 6.0, 8.0]);
2154        let expected2 = V6::new([3.0, 1.0, 6.0, 9.0, 6.0, 1.0]);
2155        let expected3 = V6::new([4.0, 2.0, 10.0, 7.0, 2.0, 4.0]);
2156        let expected4 = V6::new([9.0, 2.0, 10.0, 3.0, 9.0, 1.0]);
2157        let expected5 = V6::new([3.0, 5.0, 9.0, 6.0, 5.0, 5.0]);
2158
2159        let expected = V6::new([expected0, expected1, expected2, expected3, expected4, expected5]);
2160        assert_eq!(
2161            &result[..],
2162            &expected[..],
2163            "\nExpected\n{:?}\nfound\n{:?}",
2164            &result[..],
2165            &expected[..]
2166        );
2167    }
2168
2169    #[test]
2170    fn new_from_vecs_test() {
2171        let expected = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2172                                10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2173                                 2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2174                                10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2175                                 7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2176                                 3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2177
2178
2179        let cols = expected.get_cols();
2180
2181        let result = M66::new_from_vecs(cols);
2182
2183        assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
2184    }
2185
2186    #[test]
2187    fn qr_test() {
2188        let expected = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2189                                10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2190                                 2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2191                                10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2192                                 7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2193                                 3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2194        if let Some((q, r)) = expected.qr() {
2195            let result = q * r;
2196            assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
2197            assert!(nearly_equal(q.det().abs(), 1.0, EPS));
2198        }
2199    }
2200
2201    #[test]
2202    fn get_diagonal_test() {
2203        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2204                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2205                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2206                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2207                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2208                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2209        let result = m.get_diagonal();
2210        let expected = V6::new([1.0, 10.0, 6.0, 7.0, 9.0, 5.0]);
2211        assert_eq!(
2212            &result[..],
2213            &expected[..],
2214            "\nExpected\n{:?}\nfound\n{:?}",
2215            &result[..],
2216            &expected[..]
2217        );
2218    }
2219
2220    #[test]
2221    fn get_upper_triangular_test() {
2222        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2223                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2224                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2225                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2226                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2227                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2228        let result = m.get_upper_triangular();
2229        let expected = [1.0, 3.0, 4.0, 9.0, 3.0, 1.0, 2.0, 2.0, 5.0, 10.0, 10.0, 9.0, 3.0, 6.0, 5.0];
2230        assert_eq!(
2231            &result[..],
2232            &expected[..],
2233            "\nExpected\n{:?}\nfound\n{:?}",
2234            &result[..],
2235            &expected[..]
2236        );
2237    }
2238
2239    #[test]
2240    fn get_lower_triangular_test() {
2241        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2242                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2243                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2244                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2245                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2246                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2247        let result = m.get_lower_triangular();
2248        let expected = [10.0, 2.0, 9.0, 10.0, 9.0, 9.0, 7.0, 6.0, 6.0, 2.0, 3.0, 8.0, 1.0, 4.0, 1.0];
2249        assert_eq!(
2250            &result[..],
2251            &expected[..],
2252            "\nExpected\n{:?}\nfound\n{:?}",
2253            &result[..],
2254            &expected[..]
2255        );
2256    }
2257
2258    #[test]
2259    fn for_each_test() {
2260        let m = m66_new!( 1.0,  1.0, 3.0,  4.0,  9.0, 3.0;
2261                         10.0, 10.0, 1.0,  2.0,  2.0, 5.0;
2262                          2.0,  9.0, 6.0, 10.0, 10.0, 9.0;
2263                         10.0,  9.0, 9.0,  7.0,  3.0, 6.0;
2264                          7.0,  6.0, 6.0,  2.0,  9.0, 5.0;
2265                          3.0,  8.0, 1.0,  4.0,  1.0, 5.0);
2266
2267        let result = m.for_each(|element| element + 1.0);
2268
2269        let expected = m66_new!( 2.0,  2.0, 4.0,  5.0, 10.0, 4.0;
2270                                11.0, 11.0, 2.0,  3.0,  3.0, 6.0;
2271                                 3.0, 10.0, 7.0, 11.0, 11.0,10.0;
2272                                11.0, 10.0,10.0,  8.0,  4.0, 7.0;
2273                                 8.0,  7.0, 7.0,  3.0, 10.0, 6.0;
2274                                 4.0,  9.0, 2.0,  5.0,  2.0, 6.0);
2275
2276        assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
2277    }
2278}