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