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    #[cfg(feature = "f64")]
415    #[inline]
416    #[must_use]
417    pub fn as_mat2(&self) -> Mat2 {
418        Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
419    }
420}
421
422impl Default for DMat2 {
423    #[inline]
424    fn default() -> Self {
425        Self::IDENTITY
426    }
427}
428
429impl Add for DMat2 {
430    type Output = Self;
431    #[inline]
432    fn add(self, rhs: Self) -> Self {
433        Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
434    }
435}
436
437impl Add<&Self> for DMat2 {
438    type Output = Self;
439    #[inline]
440    fn add(self, rhs: &Self) -> Self {
441        self.add(*rhs)
442    }
443}
444
445impl Add<&DMat2> for &DMat2 {
446    type Output = DMat2;
447    #[inline]
448    fn add(self, rhs: &DMat2) -> DMat2 {
449        (*self).add(*rhs)
450    }
451}
452
453impl Add<DMat2> for &DMat2 {
454    type Output = DMat2;
455    #[inline]
456    fn add(self, rhs: DMat2) -> DMat2 {
457        (*self).add(rhs)
458    }
459}
460
461impl AddAssign for DMat2 {
462    #[inline]
463    fn add_assign(&mut self, rhs: Self) {
464        *self = self.add(rhs);
465    }
466}
467
468impl AddAssign<&Self> for DMat2 {
469    #[inline]
470    fn add_assign(&mut self, rhs: &Self) {
471        self.add_assign(*rhs);
472    }
473}
474
475impl Sub for DMat2 {
476    type Output = Self;
477    #[inline]
478    fn sub(self, rhs: Self) -> Self {
479        Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
480    }
481}
482
483impl Sub<&Self> for DMat2 {
484    type Output = Self;
485    #[inline]
486    fn sub(self, rhs: &Self) -> Self {
487        self.sub(*rhs)
488    }
489}
490
491impl Sub<&DMat2> for &DMat2 {
492    type Output = DMat2;
493    #[inline]
494    fn sub(self, rhs: &DMat2) -> DMat2 {
495        (*self).sub(*rhs)
496    }
497}
498
499impl Sub<DMat2> for &DMat2 {
500    type Output = DMat2;
501    #[inline]
502    fn sub(self, rhs: DMat2) -> DMat2 {
503        (*self).sub(rhs)
504    }
505}
506
507impl SubAssign for DMat2 {
508    #[inline]
509    fn sub_assign(&mut self, rhs: Self) {
510        *self = self.sub(rhs);
511    }
512}
513
514impl SubAssign<&Self> for DMat2 {
515    #[inline]
516    fn sub_assign(&mut self, rhs: &Self) {
517        self.sub_assign(*rhs);
518    }
519}
520
521impl Neg for DMat2 {
522    type Output = Self;
523    #[inline]
524    fn neg(self) -> Self::Output {
525        Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
526    }
527}
528
529impl Neg for &DMat2 {
530    type Output = DMat2;
531    #[inline]
532    fn neg(self) -> DMat2 {
533        (*self).neg()
534    }
535}
536
537impl Mul for DMat2 {
538    type Output = Self;
539    #[inline]
540    fn mul(self, rhs: Self) -> Self {
541        Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
542    }
543}
544
545impl Mul<&Self> for DMat2 {
546    type Output = Self;
547    #[inline]
548    fn mul(self, rhs: &Self) -> Self {
549        self.mul(*rhs)
550    }
551}
552
553impl Mul<&DMat2> for &DMat2 {
554    type Output = DMat2;
555    #[inline]
556    fn mul(self, rhs: &DMat2) -> DMat2 {
557        (*self).mul(*rhs)
558    }
559}
560
561impl Mul<DMat2> for &DMat2 {
562    type Output = DMat2;
563    #[inline]
564    fn mul(self, rhs: DMat2) -> DMat2 {
565        (*self).mul(rhs)
566    }
567}
568
569impl MulAssign for DMat2 {
570    #[inline]
571    fn mul_assign(&mut self, rhs: Self) {
572        *self = self.mul(rhs);
573    }
574}
575
576impl MulAssign<&Self> for DMat2 {
577    #[inline]
578    fn mul_assign(&mut self, rhs: &Self) {
579        self.mul_assign(*rhs);
580    }
581}
582
583impl Mul<DVec2> for DMat2 {
584    type Output = DVec2;
585    #[inline]
586    fn mul(self, rhs: DVec2) -> Self::Output {
587        self.mul_vec2(rhs)
588    }
589}
590
591impl Mul<&DVec2> for DMat2 {
592    type Output = DVec2;
593    #[inline]
594    fn mul(self, rhs: &DVec2) -> DVec2 {
595        self.mul(*rhs)
596    }
597}
598
599impl Mul<&DVec2> for &DMat2 {
600    type Output = DVec2;
601    #[inline]
602    fn mul(self, rhs: &DVec2) -> DVec2 {
603        (*self).mul(*rhs)
604    }
605}
606
607impl Mul<DVec2> for &DMat2 {
608    type Output = DVec2;
609    #[inline]
610    fn mul(self, rhs: DVec2) -> DVec2 {
611        (*self).mul(rhs)
612    }
613}
614
615impl Mul<DMat2> for f64 {
616    type Output = DMat2;
617    #[inline]
618    fn mul(self, rhs: DMat2) -> Self::Output {
619        rhs.mul_scalar(self)
620    }
621}
622
623impl Mul<&DMat2> for f64 {
624    type Output = DMat2;
625    #[inline]
626    fn mul(self, rhs: &DMat2) -> DMat2 {
627        self.mul(*rhs)
628    }
629}
630
631impl Mul<&DMat2> for &f64 {
632    type Output = DMat2;
633    #[inline]
634    fn mul(self, rhs: &DMat2) -> DMat2 {
635        (*self).mul(*rhs)
636    }
637}
638
639impl Mul<DMat2> for &f64 {
640    type Output = DMat2;
641    #[inline]
642    fn mul(self, rhs: DMat2) -> DMat2 {
643        (*self).mul(rhs)
644    }
645}
646
647impl Mul<f64> for DMat2 {
648    type Output = Self;
649    #[inline]
650    fn mul(self, rhs: f64) -> Self {
651        self.mul_scalar(rhs)
652    }
653}
654
655impl Mul<&f64> for DMat2 {
656    type Output = Self;
657    #[inline]
658    fn mul(self, rhs: &f64) -> Self {
659        self.mul(*rhs)
660    }
661}
662
663impl Mul<&f64> for &DMat2 {
664    type Output = DMat2;
665    #[inline]
666    fn mul(self, rhs: &f64) -> DMat2 {
667        (*self).mul(*rhs)
668    }
669}
670
671impl Mul<f64> for &DMat2 {
672    type Output = DMat2;
673    #[inline]
674    fn mul(self, rhs: f64) -> DMat2 {
675        (*self).mul(rhs)
676    }
677}
678
679impl MulAssign<f64> for DMat2 {
680    #[inline]
681    fn mul_assign(&mut self, rhs: f64) {
682        *self = self.mul(rhs);
683    }
684}
685
686impl MulAssign<&f64> for DMat2 {
687    #[inline]
688    fn mul_assign(&mut self, rhs: &f64) {
689        self.mul_assign(*rhs);
690    }
691}
692
693impl Div<DMat2> for f64 {
694    type Output = DMat2;
695    #[inline]
696    fn div(self, rhs: DMat2) -> Self::Output {
697        DMat2::from_cols(self.div(rhs.x_axis), self.div(rhs.y_axis))
698    }
699}
700
701impl Div<&DMat2> for f64 {
702    type Output = DMat2;
703    #[inline]
704    fn div(self, rhs: &DMat2) -> DMat2 {
705        self.div(*rhs)
706    }
707}
708
709impl Div<&DMat2> for &f64 {
710    type Output = DMat2;
711    #[inline]
712    fn div(self, rhs: &DMat2) -> DMat2 {
713        (*self).div(*rhs)
714    }
715}
716
717impl Div<DMat2> for &f64 {
718    type Output = DMat2;
719    #[inline]
720    fn div(self, rhs: DMat2) -> DMat2 {
721        (*self).div(rhs)
722    }
723}
724
725impl Div<f64> for DMat2 {
726    type Output = Self;
727    #[inline]
728    fn div(self, rhs: f64) -> Self {
729        self.div_scalar(rhs)
730    }
731}
732
733impl Div<&f64> for DMat2 {
734    type Output = Self;
735    #[inline]
736    fn div(self, rhs: &f64) -> Self {
737        self.div(*rhs)
738    }
739}
740
741impl Div<&f64> for &DMat2 {
742    type Output = DMat2;
743    #[inline]
744    fn div(self, rhs: &f64) -> DMat2 {
745        (*self).div(*rhs)
746    }
747}
748
749impl Div<f64> for &DMat2 {
750    type Output = DMat2;
751    #[inline]
752    fn div(self, rhs: f64) -> DMat2 {
753        (*self).div(rhs)
754    }
755}
756
757impl DivAssign<f64> for DMat2 {
758    #[inline]
759    fn div_assign(&mut self, rhs: f64) {
760        *self = self.div(rhs);
761    }
762}
763
764impl DivAssign<&f64> for DMat2 {
765    #[inline]
766    fn div_assign(&mut self, rhs: &f64) {
767        self.div_assign(*rhs);
768    }
769}
770
771impl Sum<Self> for DMat2 {
772    fn sum<I>(iter: I) -> Self
773    where
774        I: Iterator<Item = Self>,
775    {
776        iter.fold(Self::ZERO, Self::add)
777    }
778}
779
780impl<'a> Sum<&'a Self> for DMat2 {
781    fn sum<I>(iter: I) -> Self
782    where
783        I: Iterator<Item = &'a Self>,
784    {
785        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
786    }
787}
788
789impl Product for DMat2 {
790    fn product<I>(iter: I) -> Self
791    where
792        I: Iterator<Item = Self>,
793    {
794        iter.fold(Self::IDENTITY, Self::mul)
795    }
796}
797
798impl<'a> Product<&'a Self> for DMat2 {
799    fn product<I>(iter: I) -> Self
800    where
801        I: Iterator<Item = &'a Self>,
802    {
803        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
804    }
805}
806
807impl PartialEq for DMat2 {
808    #[inline]
809    fn eq(&self, rhs: &Self) -> bool {
810        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
811    }
812}
813
814impl AsRef<[f64; 4]> for DMat2 {
815    #[inline]
816    fn as_ref(&self) -> &[f64; 4] {
817        unsafe { &*(self as *const Self as *const [f64; 4]) }
818    }
819}
820
821impl AsMut<[f64; 4]> for DMat2 {
822    #[inline]
823    fn as_mut(&mut self) -> &mut [f64; 4] {
824        unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
825    }
826}
827
828impl fmt::Debug for DMat2 {
829    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
830        fmt.debug_struct(stringify!(DMat2))
831            .field("x_axis", &self.x_axis)
832            .field("y_axis", &self.y_axis)
833            .finish()
834    }
835}
836
837impl fmt::Display for DMat2 {
838    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
839        if let Some(p) = f.precision() {
840            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
841        } else {
842            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
843        }
844    }
845}