Skip to main content

glam/f64/
dmat2.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f64::math, swizzles::*, DMat3, DVec2, Mat2};
4use core::fmt;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8#[cfg(feature = "zerocopy-08")]
9use zerocopy_derive_08::*;
10
11/// Creates a 2x2 matrix from two column vectors.
12#[inline(always)]
13#[must_use]
14pub const fn dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat2 {
15    DMat2::from_cols(x_axis, y_axis)
16}
17
18/// A 2x2 column major matrix.
19#[derive(Clone, Copy)]
20#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
21#[cfg_attr(
22    feature = "zerocopy-08",
23    derive(FromBytes, Immutable, IntoBytes, KnownLayout)
24)]
25#[cfg_attr(feature = "cuda", repr(align(16)))]
26#[repr(C)]
27pub struct DMat2 {
28    pub x_axis: DVec2,
29    pub y_axis: DVec2,
30}
31
32impl DMat2 {
33    /// A 2x2 matrix with all elements set to `0.0`.
34    pub const ZERO: Self = Self::from_cols(DVec2::ZERO, DVec2::ZERO);
35
36    /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
37    pub const IDENTITY: Self = Self::from_cols(DVec2::X, DVec2::Y);
38
39    /// All NAN:s.
40    pub const NAN: Self = Self::from_cols(DVec2::NAN, DVec2::NAN);
41
42    #[allow(clippy::too_many_arguments)]
43    #[inline(always)]
44    #[must_use]
45    const fn new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self {
46        Self {
47            x_axis: DVec2::new(m00, m01),
48            y_axis: DVec2::new(m10, m11),
49        }
50    }
51
52    /// Creates a 2x2 matrix from two column vectors.
53    ///
54    /// See also [`Self::from_rows`] when the data is in row major order.
55    #[inline(always)]
56    #[must_use]
57    pub const fn from_cols(x_axis: DVec2, y_axis: DVec2) -> Self {
58        Self { x_axis, y_axis }
59    }
60
61    /// Creates a 2x2 matrix from two row vectors.
62    ///
63    /// Matrices are stored in column major order, so the given rows are permuted into
64    /// the matrix layout. Use [`Self::from_cols`] instead when the data is already in
65    /// column major order.
66    #[inline(always)]
67    #[must_use]
68    pub const fn from_rows(row0: DVec2, row1: DVec2) -> Self {
69        let [m00, m01] = row0.to_array();
70        let [m10, m11] = row1.to_array();
71        Self::new(m00, m10, m01, m11)
72    }
73
74    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in column major order.
75    ///
76    /// If the data is in row major order use [`Self::from_rows_array`] instead.
77    #[inline]
78    #[must_use]
79    pub const fn from_cols_array(m: &[f64; 4]) -> Self {
80        Self::new(m[0], m[1], m[2], m[3])
81    }
82
83    /// Creates a `[f64; 4]` array storing data in column major order.
84    ///
85    /// If you require the data in row major order use [`Self::to_rows_array`] instead.
86    #[inline]
87    #[must_use]
88    pub const fn to_cols_array(&self) -> [f64; 4] {
89        [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
90    }
91
92    /// Creates a 2x2 matrix from a `[[f64; 2]; 2]` 2D array stored in column major order.
93    ///
94    /// If the data is in row major order `transpose` the returned matrix.
95    #[inline]
96    #[must_use]
97    pub const fn from_cols_array_2d(m: &[[f64; 2]; 2]) -> Self {
98        Self::from_cols(DVec2::from_array(m[0]), DVec2::from_array(m[1]))
99    }
100
101    /// Creates a `[[f64; 2]; 2]` 2D array storing data in column major order.
102    ///
103    /// If you require row major order `transpose` the matrix first.
104    #[inline]
105    #[must_use]
106    pub const fn to_cols_array_2d(&self) -> [[f64; 2]; 2] {
107        [self.x_axis.to_array(), self.y_axis.to_array()]
108    }
109
110    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in row major order.
111    ///
112    /// Matrices are stored in column major order, so the array is permuted into the
113    /// matrix layout. Use [`Self::from_cols_array`] instead when the data is already in
114    /// column major order.
115    #[inline]
116    #[must_use]
117    pub const fn from_rows_array(m: &[f64; 4]) -> Self {
118        Self::new(m[0], m[2], m[1], m[3])
119    }
120
121    /// Creates a `[f64; 4]` array storing data in row major order.
122    ///
123    /// Matrices are stored in column major order, so the array is permuted out of the
124    /// column major storage. Use [`Self::to_cols_array`] instead when you want data in
125    /// column major order.
126    #[inline]
127    #[must_use]
128    pub const fn to_rows_array(&self) -> [f64; 4] {
129        let m = self.to_cols_array();
130        [m[0], m[2], m[1], m[3]]
131    }
132
133    /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
134    #[doc(alias = "scale")]
135    #[inline]
136    #[must_use]
137    pub const fn from_diagonal(diagonal: DVec2) -> Self {
138        Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
139    }
140
141    /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
142    /// `angle` (in radians).
143    #[inline]
144    #[must_use]
145    pub fn from_scale_angle(scale: DVec2, angle: f64) -> Self {
146        let (sin, cos) = math::sin_cos(angle);
147        Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
148    }
149
150    /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
151    #[inline]
152    #[must_use]
153    pub fn from_angle(angle: f64) -> Self {
154        let (sin, cos) = math::sin_cos(angle);
155        Self::new(cos, sin, -sin, cos)
156    }
157
158    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
159    #[inline]
160    #[must_use]
161    pub fn from_mat3(m: DMat3) -> Self {
162        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
163    }
164
165    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
166    /// and `j`th row.
167    ///
168    /// # Panics
169    ///
170    /// Panics if `i` or `j` is greater than 2.
171    #[inline]
172    #[must_use]
173    pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
174        match (i, j) {
175            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
176            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
177            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
178            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
179            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
180            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
181            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
182            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
183            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
184            _ => panic!("index out of bounds"),
185        }
186    }
187
188    /// Creates a 2x2 matrix from the first 4 values in `slice`.
189    ///
190    /// See also [`Self::from_rows_slice`] when the slice is in row major order.
191    ///
192    /// # Panics
193    ///
194    /// Panics if `slice` is less than 4 elements long.
195    #[inline]
196    #[must_use]
197    pub const fn from_cols_slice(slice: &[f64]) -> Self {
198        Self::new(slice[0], slice[1], slice[2], slice[3])
199    }
200
201    /// Writes the columns of `self` to the first 4 elements in `slice`.
202    ///
203    /// # Panics
204    ///
205    /// Panics if `slice` is less than 4 elements long.
206    #[inline]
207    pub fn write_cols_to_slice(&self, slice: &mut [f64]) {
208        slice[0] = self.x_axis.x;
209        slice[1] = self.x_axis.y;
210        slice[2] = self.y_axis.x;
211        slice[3] = self.y_axis.y;
212    }
213
214    /// Creates a 2x2 matrix from the first 4 values in `slice`, stored in row
215    /// major order.
216    ///
217    /// Matrices are stored in column major order, so the slice is permuted into the
218    /// matrix layout. Use [`Self::from_cols_slice`] instead when the slice is already in
219    /// column major order.
220    ///
221    /// # Panics
222    ///
223    /// Panics if `slice` is less than 4 elements long.
224    #[inline]
225    #[must_use]
226    pub const fn from_rows_slice(slice: &[f64]) -> Self {
227        Self::new(slice[0], slice[2], slice[1], slice[3])
228    }
229
230    /// Returns the matrix column for the given `index`.
231    ///
232    /// # Panics
233    ///
234    /// Panics if `index` is greater than 1.
235    #[inline]
236    #[must_use]
237    pub fn col(&self, index: usize) -> DVec2 {
238        match index {
239            0 => self.x_axis,
240            1 => self.y_axis,
241            _ => panic!("index out of bounds"),
242        }
243    }
244
245    /// Returns a mutable reference to the matrix column for the given `index`.
246    ///
247    /// # Panics
248    ///
249    /// Panics if `index` is greater than 1.
250    #[inline]
251    pub fn col_mut(&mut self, index: usize) -> &mut DVec2 {
252        match index {
253            0 => &mut self.x_axis,
254            1 => &mut self.y_axis,
255            _ => panic!("index out of bounds"),
256        }
257    }
258
259    /// Returns the matrix row for the given `index`.
260    ///
261    /// See also [`Self::set_row`] when you need to change the row.
262    ///
263    /// # Panics
264    ///
265    /// Panics if `index` is greater than 1.
266    #[inline]
267    #[must_use]
268    pub fn row(&self, index: usize) -> DVec2 {
269        match index {
270            0 => DVec2::new(self.x_axis.x, self.y_axis.x),
271            1 => DVec2::new(self.x_axis.y, self.y_axis.y),
272            _ => panic!("index out of bounds"),
273        }
274    }
275
276    /// Sets the matrix row for the given `index`.
277    ///
278    /// Matrices are stored in column major order, so the row is spread across all
279    /// 2 columns and writing it touches every column. Use [`Self::col_mut`]
280    /// instead when you can work with columns. See also [`Self::row`].
281    ///
282    /// # Panics
283    ///
284    /// Panics if `index` is greater than 1.
285    #[inline]
286    pub fn set_row(&mut self, index: usize, row: DVec2) {
287        match index {
288            0 => {
289                self.x_axis.x = row.x;
290                self.y_axis.x = row.y;
291            }
292            1 => {
293                self.x_axis.y = row.x;
294                self.y_axis.y = row.y;
295            }
296            _ => panic!("index out of bounds"),
297        }
298    }
299
300    /// Returns `true` if, and only if, all elements are finite.
301    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
302    #[inline]
303    #[must_use]
304    pub fn is_finite(&self) -> bool {
305        self.x_axis.is_finite() && self.y_axis.is_finite()
306    }
307
308    /// Returns `true` if any elements are `NaN`.
309    #[inline]
310    #[must_use]
311    pub fn is_nan(&self) -> bool {
312        self.x_axis.is_nan() || self.y_axis.is_nan()
313    }
314
315    /// Returns the transpose of `self`.
316    #[inline]
317    #[must_use]
318    pub fn transpose(&self) -> Self {
319        Self {
320            x_axis: DVec2::new(self.x_axis.x, self.y_axis.x),
321            y_axis: DVec2::new(self.x_axis.y, self.y_axis.y),
322        }
323    }
324
325    /// Returns the diagonal of `self`.
326    #[inline]
327    #[must_use]
328    pub fn diagonal(&self) -> DVec2 {
329        DVec2::new(self.x_axis.x, self.y_axis.y)
330    }
331
332    /// Returns the determinant of `self`.
333    #[inline]
334    #[must_use]
335    pub fn determinant(&self) -> f64 {
336        self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
337    }
338
339    /// If `CHECKED` is true then if the determinant is zero this function will return a tuple
340    /// containing a zero matrix and false. If the determinant is non zero a tuple containing the
341    /// inverted matrix and true is returned.
342    ///
343    /// If `CHECKED` is false then the determinant is not checked and if it is zero the resulting
344    /// inverted matrix will be invalid. Will panic if the determinant of `self` is zero when
345    /// `glam_assert` is enabled.
346    ///
347    /// A tuple containing the inverted matrix and a bool is used instead of an option here as
348    /// regular Rust enums put the discriminant first which can result in a lot of padding if the
349    /// matrix is aligned.
350    #[inline(always)]
351    #[must_use]
352    fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
353        let det = self.determinant();
354        if CHECKED {
355            if det == 0.0 {
356                return (Self::ZERO, false);
357            }
358        } else {
359            glam_assert!(det != 0.0);
360        }
361        let inv_det = 1.0 / det;
362        (
363            Self::new(
364                self.y_axis.y * inv_det,
365                self.x_axis.y * -inv_det,
366                self.y_axis.x * -inv_det,
367                self.x_axis.x * inv_det,
368            ),
369            true,
370        )
371    }
372
373    /// Returns the inverse of `self`.
374    ///
375    /// If the matrix is not invertible the returned matrix will be invalid.
376    ///
377    /// # Panics
378    ///
379    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
380    #[inline]
381    #[must_use]
382    pub fn inverse(&self) -> Self {
383        self.inverse_checked::<false>().0
384    }
385
386    /// Returns the inverse of `self` or `None` if the matrix is not invertible.
387    #[inline]
388    #[must_use]
389    pub fn try_inverse(&self) -> Option<Self> {
390        let (m, is_valid) = self.inverse_checked::<true>();
391        if is_valid {
392            Some(m)
393        } else {
394            None
395        }
396    }
397
398    /// Returns the inverse of `self` or `DMat2::ZERO` if the matrix is not invertible.
399    #[inline]
400    #[must_use]
401    pub fn inverse_or_zero(&self) -> Self {
402        self.inverse_checked::<true>().0
403    }
404
405    /// Transforms a 2D vector.
406    #[inline]
407    #[must_use]
408    pub fn mul_vec2(&self, rhs: DVec2) -> DVec2 {
409        #[allow(clippy::suspicious_operation_groupings)]
410        DVec2::new(
411            (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
412            (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
413        )
414    }
415
416    /// Transforms a 2D vector by the transpose of `self`.
417    #[inline]
418    #[must_use]
419    pub fn mul_transpose_vec2(&self, rhs: DVec2) -> DVec2 {
420        DVec2::new(self.x_axis.dot(rhs), self.y_axis.dot(rhs))
421    }
422
423    /// Multiplies two 2x2 matrices.
424    #[inline]
425    #[must_use]
426    pub fn mul_mat2(&self, rhs: &Self) -> Self {
427        self.mul(rhs)
428    }
429
430    /// Adds two 2x2 matrices.
431    #[inline]
432    #[must_use]
433    pub fn add_mat2(&self, rhs: &Self) -> Self {
434        self.add(rhs)
435    }
436
437    /// Subtracts two 2x2 matrices.
438    #[inline]
439    #[must_use]
440    pub fn sub_mat2(&self, rhs: &Self) -> Self {
441        self.sub(rhs)
442    }
443
444    /// Multiplies a 2x2 matrix by a scalar.
445    #[inline]
446    #[must_use]
447    pub fn mul_scalar(&self, rhs: f64) -> Self {
448        Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
449    }
450
451    /// Multiply `self` by a scaling vector `scale`.
452    /// This is faster than creating a whole diagonal scaling matrix and then multiplying that.
453    /// This operation is commutative.
454    #[inline]
455    #[must_use]
456    pub fn mul_diagonal_scale(&self, scale: DVec2) -> Self {
457        Self::from_cols(self.x_axis * scale.x, self.y_axis * scale.y)
458    }
459
460    /// Divides a 2x2 matrix by a scalar.
461    #[inline]
462    #[must_use]
463    pub fn div_scalar(&self, rhs: f64) -> Self {
464        let rhs = DVec2::splat(rhs);
465        Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
466    }
467
468    /// Returns a matrix containing the reciprocal `1.0/n` of each element of `self`.
469    #[inline]
470    #[must_use]
471    pub fn recip(&self) -> Self {
472        Self::from_cols(self.x_axis.recip(), self.y_axis.recip())
473    }
474
475    /// Returns true if the absolute difference of all elements between `self` and `rhs`
476    /// is less than or equal to `max_abs_diff`.
477    ///
478    /// This can be used to compare if two matrices contain similar elements. It works best
479    /// when comparing with a known value. The `max_abs_diff` that should be used used
480    /// depends on the values being compared against.
481    ///
482    /// For more see
483    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
484    #[inline]
485    #[must_use]
486    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
487        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
488            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
489    }
490
491    /// Takes the absolute value of each element in `self`
492    #[inline]
493    #[must_use]
494    pub fn abs(&self) -> Self {
495        Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
496    }
497
498    #[cfg(feature = "f64")]
499    #[inline]
500    #[must_use]
501    pub fn as_mat2(&self) -> Mat2 {
502        Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
503    }
504}
505
506impl Default for DMat2 {
507    #[inline]
508    fn default() -> Self {
509        Self::IDENTITY
510    }
511}
512
513impl Add for DMat2 {
514    type Output = Self;
515    #[inline]
516    fn add(self, rhs: Self) -> Self {
517        Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
518    }
519}
520
521impl Add<&Self> for DMat2 {
522    type Output = Self;
523    #[inline]
524    fn add(self, rhs: &Self) -> Self {
525        self.add(*rhs)
526    }
527}
528
529impl Add<&DMat2> for &DMat2 {
530    type Output = DMat2;
531    #[inline]
532    fn add(self, rhs: &DMat2) -> DMat2 {
533        (*self).add(*rhs)
534    }
535}
536
537impl Add<DMat2> for &DMat2 {
538    type Output = DMat2;
539    #[inline]
540    fn add(self, rhs: DMat2) -> DMat2 {
541        (*self).add(rhs)
542    }
543}
544
545impl AddAssign for DMat2 {
546    #[inline]
547    fn add_assign(&mut self, rhs: Self) {
548        *self = self.add(rhs);
549    }
550}
551
552impl AddAssign<&Self> for DMat2 {
553    #[inline]
554    fn add_assign(&mut self, rhs: &Self) {
555        self.add_assign(*rhs);
556    }
557}
558
559impl Sub for DMat2 {
560    type Output = Self;
561    #[inline]
562    fn sub(self, rhs: Self) -> Self {
563        Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
564    }
565}
566
567impl Sub<&Self> for DMat2 {
568    type Output = Self;
569    #[inline]
570    fn sub(self, rhs: &Self) -> Self {
571        self.sub(*rhs)
572    }
573}
574
575impl Sub<&DMat2> for &DMat2 {
576    type Output = DMat2;
577    #[inline]
578    fn sub(self, rhs: &DMat2) -> DMat2 {
579        (*self).sub(*rhs)
580    }
581}
582
583impl Sub<DMat2> for &DMat2 {
584    type Output = DMat2;
585    #[inline]
586    fn sub(self, rhs: DMat2) -> DMat2 {
587        (*self).sub(rhs)
588    }
589}
590
591impl SubAssign for DMat2 {
592    #[inline]
593    fn sub_assign(&mut self, rhs: Self) {
594        *self = self.sub(rhs);
595    }
596}
597
598impl SubAssign<&Self> for DMat2 {
599    #[inline]
600    fn sub_assign(&mut self, rhs: &Self) {
601        self.sub_assign(*rhs);
602    }
603}
604
605impl Neg for DMat2 {
606    type Output = Self;
607    #[inline]
608    fn neg(self) -> Self::Output {
609        Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
610    }
611}
612
613impl Neg for &DMat2 {
614    type Output = DMat2;
615    #[inline]
616    fn neg(self) -> DMat2 {
617        (*self).neg()
618    }
619}
620
621impl Mul for DMat2 {
622    type Output = Self;
623    #[inline]
624    fn mul(self, rhs: Self) -> Self {
625        Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
626    }
627}
628
629impl Mul<&Self> for DMat2 {
630    type Output = Self;
631    #[inline]
632    fn mul(self, rhs: &Self) -> Self {
633        self.mul(*rhs)
634    }
635}
636
637impl Mul<&DMat2> for &DMat2 {
638    type Output = DMat2;
639    #[inline]
640    fn mul(self, rhs: &DMat2) -> DMat2 {
641        (*self).mul(*rhs)
642    }
643}
644
645impl Mul<DMat2> for &DMat2 {
646    type Output = DMat2;
647    #[inline]
648    fn mul(self, rhs: DMat2) -> DMat2 {
649        (*self).mul(rhs)
650    }
651}
652
653impl MulAssign for DMat2 {
654    #[inline]
655    fn mul_assign(&mut self, rhs: Self) {
656        *self = self.mul(rhs);
657    }
658}
659
660impl MulAssign<&Self> for DMat2 {
661    #[inline]
662    fn mul_assign(&mut self, rhs: &Self) {
663        self.mul_assign(*rhs);
664    }
665}
666
667impl Mul<DVec2> for DMat2 {
668    type Output = DVec2;
669    #[inline]
670    fn mul(self, rhs: DVec2) -> Self::Output {
671        self.mul_vec2(rhs)
672    }
673}
674
675impl Mul<&DVec2> for DMat2 {
676    type Output = DVec2;
677    #[inline]
678    fn mul(self, rhs: &DVec2) -> DVec2 {
679        self.mul(*rhs)
680    }
681}
682
683impl Mul<&DVec2> for &DMat2 {
684    type Output = DVec2;
685    #[inline]
686    fn mul(self, rhs: &DVec2) -> DVec2 {
687        (*self).mul(*rhs)
688    }
689}
690
691impl Mul<DVec2> for &DMat2 {
692    type Output = DVec2;
693    #[inline]
694    fn mul(self, rhs: DVec2) -> DVec2 {
695        (*self).mul(rhs)
696    }
697}
698
699impl Mul<DMat2> for f64 {
700    type Output = DMat2;
701    #[inline]
702    fn mul(self, rhs: DMat2) -> Self::Output {
703        rhs.mul_scalar(self)
704    }
705}
706
707impl Mul<&DMat2> for f64 {
708    type Output = DMat2;
709    #[inline]
710    fn mul(self, rhs: &DMat2) -> DMat2 {
711        self.mul(*rhs)
712    }
713}
714
715impl Mul<&DMat2> for &f64 {
716    type Output = DMat2;
717    #[inline]
718    fn mul(self, rhs: &DMat2) -> DMat2 {
719        (*self).mul(*rhs)
720    }
721}
722
723impl Mul<DMat2> for &f64 {
724    type Output = DMat2;
725    #[inline]
726    fn mul(self, rhs: DMat2) -> DMat2 {
727        (*self).mul(rhs)
728    }
729}
730
731impl Mul<f64> for DMat2 {
732    type Output = Self;
733    #[inline]
734    fn mul(self, rhs: f64) -> Self {
735        self.mul_scalar(rhs)
736    }
737}
738
739impl Mul<&f64> for DMat2 {
740    type Output = Self;
741    #[inline]
742    fn mul(self, rhs: &f64) -> Self {
743        self.mul(*rhs)
744    }
745}
746
747impl Mul<&f64> for &DMat2 {
748    type Output = DMat2;
749    #[inline]
750    fn mul(self, rhs: &f64) -> DMat2 {
751        (*self).mul(*rhs)
752    }
753}
754
755impl Mul<f64> for &DMat2 {
756    type Output = DMat2;
757    #[inline]
758    fn mul(self, rhs: f64) -> DMat2 {
759        (*self).mul(rhs)
760    }
761}
762
763impl MulAssign<f64> for DMat2 {
764    #[inline]
765    fn mul_assign(&mut self, rhs: f64) {
766        *self = self.mul(rhs);
767    }
768}
769
770impl MulAssign<&f64> for DMat2 {
771    #[inline]
772    fn mul_assign(&mut self, rhs: &f64) {
773        self.mul_assign(*rhs);
774    }
775}
776
777impl Div<DMat2> for f64 {
778    type Output = DMat2;
779    #[inline]
780    fn div(self, rhs: DMat2) -> Self::Output {
781        DMat2::from_cols(self.div(rhs.x_axis), self.div(rhs.y_axis))
782    }
783}
784
785impl Div<&DMat2> for f64 {
786    type Output = DMat2;
787    #[inline]
788    fn div(self, rhs: &DMat2) -> DMat2 {
789        self.div(*rhs)
790    }
791}
792
793impl Div<&DMat2> for &f64 {
794    type Output = DMat2;
795    #[inline]
796    fn div(self, rhs: &DMat2) -> DMat2 {
797        (*self).div(*rhs)
798    }
799}
800
801impl Div<DMat2> for &f64 {
802    type Output = DMat2;
803    #[inline]
804    fn div(self, rhs: DMat2) -> DMat2 {
805        (*self).div(rhs)
806    }
807}
808
809impl Div<f64> for DMat2 {
810    type Output = Self;
811    #[inline]
812    fn div(self, rhs: f64) -> Self {
813        self.div_scalar(rhs)
814    }
815}
816
817impl Div<&f64> for DMat2 {
818    type Output = Self;
819    #[inline]
820    fn div(self, rhs: &f64) -> Self {
821        self.div(*rhs)
822    }
823}
824
825impl Div<&f64> for &DMat2 {
826    type Output = DMat2;
827    #[inline]
828    fn div(self, rhs: &f64) -> DMat2 {
829        (*self).div(*rhs)
830    }
831}
832
833impl Div<f64> for &DMat2 {
834    type Output = DMat2;
835    #[inline]
836    fn div(self, rhs: f64) -> DMat2 {
837        (*self).div(rhs)
838    }
839}
840
841impl DivAssign<f64> for DMat2 {
842    #[inline]
843    fn div_assign(&mut self, rhs: f64) {
844        *self = self.div(rhs);
845    }
846}
847
848impl DivAssign<&f64> for DMat2 {
849    #[inline]
850    fn div_assign(&mut self, rhs: &f64) {
851        self.div_assign(*rhs);
852    }
853}
854
855impl Sum<Self> for DMat2 {
856    fn sum<I>(iter: I) -> Self
857    where
858        I: Iterator<Item = Self>,
859    {
860        iter.fold(Self::ZERO, Self::add)
861    }
862}
863
864impl<'a> Sum<&'a Self> for DMat2 {
865    fn sum<I>(iter: I) -> Self
866    where
867        I: Iterator<Item = &'a Self>,
868    {
869        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
870    }
871}
872
873impl Product for DMat2 {
874    fn product<I>(iter: I) -> Self
875    where
876        I: Iterator<Item = Self>,
877    {
878        iter.fold(Self::IDENTITY, Self::mul)
879    }
880}
881
882impl<'a> Product<&'a Self> for DMat2 {
883    fn product<I>(iter: I) -> Self
884    where
885        I: Iterator<Item = &'a Self>,
886    {
887        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
888    }
889}
890
891impl PartialEq for DMat2 {
892    #[inline]
893    fn eq(&self, rhs: &Self) -> bool {
894        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
895    }
896}
897
898impl AsRef<[f64; 4]> for DMat2 {
899    #[inline]
900    fn as_ref(&self) -> &[f64; 4] {
901        unsafe { &*(self as *const Self as *const [f64; 4]) }
902    }
903}
904
905impl AsMut<[f64; 4]> for DMat2 {
906    #[inline]
907    fn as_mut(&mut self) -> &mut [f64; 4] {
908        unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
909    }
910}
911
912impl fmt::Debug for DMat2 {
913    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
914        fmt.debug_struct(stringify!(DMat2))
915            .field("x_axis", &self.x_axis)
916            .field("y_axis", &self.y_axis)
917            .finish()
918    }
919}
920
921impl fmt::Display for DMat2 {
922    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
923        if let Some(p) = f.precision() {
924            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
925        } else {
926            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
927        }
928    }
929}