use crate::rv::nalgebra::DVector;
use std::ops::Mul;
#[derive(Clone, Debug)]
pub struct Vector2(pub [f64; 2]);
#[derive(Clone, Debug)]
pub struct Vector4(pub [f64; 4]);
#[derive(Clone, Debug)]
pub struct Matrix1x1(pub [f64; 1]);
#[derive(Clone, Debug)]
pub struct Matrix2x2(pub [f64; 4]);
#[derive(Clone, Debug)]
pub struct Matrix4x4(pub [f64; 16]);
impl Vector2 {
pub fn new() -> Self {
Vector2([0.0; 2])
}
}
impl Default for Vector2 {
fn default() -> Self {
Self::new()
}
}
impl Vector4 {
pub fn new() -> Self {
Vector4([0.0; 4])
}
}
impl Default for Vector4 {
fn default() -> Self {
Self::new()
}
}
impl Matrix1x1 {
pub fn new() -> Self {
Matrix1x1([0.0])
}
}
impl Default for Matrix1x1 {
fn default() -> Self {
Self::new()
}
}
impl Matrix2x2 {
pub fn new() -> Self {
Matrix2x2([0.0; 4])
}
pub fn from_diag(diag: [f64; 2]) -> Self {
let mut mat = Self::new();
mat.0[0] = diag[0];
mat.0[3] = diag[1];
mat
}
}
impl Default for Matrix2x2 {
fn default() -> Self {
Self::new()
}
}
impl Matrix4x4 {
pub fn new() -> Self {
Matrix4x4([0.0; 16])
}
pub fn from_diag(diag: [f64; 4]) -> Self {
let mut mat = Self::new();
mat.0[0] = diag[0];
mat.0[5] = diag[1];
mat.0[11] = diag[2];
mat.0[15] = diag[3];
mat
}
}
impl Default for Matrix4x4 {
fn default() -> Self {
Self::new()
}
}
pub trait MvSub {
fn mv_sub(self, other: &Self) -> Self;
}
impl MvSub for Matrix1x1 {
fn mv_sub(mut self, other: &Self) -> Self {
self.0[0] -= other.0[0];
self
}
}
impl MvSub for Vector2 {
fn mv_sub(mut self, other: &Self) -> Self {
self.0[0] -= other.0[0];
self.0[1] -= other.0[1];
self
}
}
impl MvSub for Matrix2x2 {
fn mv_sub(mut self, other: &Self) -> Self {
self.0[0] -= other.0[0];
self.0[1] -= other.0[1];
self.0[2] -= other.0[2];
self.0[3] -= other.0[3];
self
}
}
impl MvSub for Vector4 {
fn mv_sub(mut self, other: &Self) -> Self {
self.0[0] -= other.0[0];
self.0[1] -= other.0[1];
self.0[2] -= other.0[2];
self.0[3] -= other.0[3];
self
}
}
impl MvSub for Matrix4x4 {
fn mv_sub(mut self, other: &Self) -> Self {
self.0[0] -= other.0[0];
self.0[1] -= other.0[1];
self.0[2] -= other.0[2];
self.0[3] -= other.0[3];
self.0[4] -= other.0[4];
self.0[5] -= other.0[5];
self.0[6] -= other.0[6];
self.0[7] -= other.0[7];
self.0[8] -= other.0[8];
self.0[9] -= other.0[9];
self.0[10] -= other.0[10];
self.0[11] -= other.0[11];
self.0[12] -= other.0[12];
self.0[13] -= other.0[13];
self.0[14] -= other.0[14];
self.0[15] -= other.0[15];
self
}
}
pub trait MvAdd {
fn mv_add(self, other: &Self) -> Self;
}
impl MvAdd for Matrix1x1 {
fn mv_add(mut self, other: &Self) -> Self {
self.0[0] += other.0[0];
self
}
}
impl MvAdd for Vector2 {
fn mv_add(mut self, other: &Self) -> Self {
self.0[0] += other.0[0];
self.0[1] += other.0[1];
self
}
}
impl MvAdd for Matrix2x2 {
fn mv_add(mut self, other: &Self) -> Self {
self.0[0] += other.0[0];
self.0[1] += other.0[1];
self.0[2] += other.0[2];
self.0[3] += other.0[3];
self
}
}
impl MvAdd for Vector4 {
fn mv_add(mut self, other: &Self) -> Self {
self.0[0] += other.0[0];
self.0[1] += other.0[1];
self.0[2] += other.0[2];
self.0[3] += other.0[3];
self
}
}
impl MvAdd for Matrix4x4 {
fn mv_add(mut self, other: &Self) -> Self {
self.0[0] += other.0[0];
self.0[1] += other.0[1];
self.0[2] += other.0[2];
self.0[3] += other.0[3];
self.0[4] += other.0[4];
self.0[5] += other.0[5];
self.0[6] += other.0[6];
self.0[7] += other.0[7];
self.0[8] += other.0[8];
self.0[9] += other.0[9];
self.0[10] += other.0[10];
self.0[11] += other.0[11];
self.0[12] += other.0[12];
self.0[13] += other.0[13];
self.0[14] += other.0[14];
self.0[15] += other.0[15];
self
}
}
impl Mul<f64> for Matrix1x1 {
type Output = Matrix1x1;
fn mul(mut self, rhs: f64) -> Self::Output {
self.0[0] *= rhs;
self
}
}
impl Mul<f64> for Vector2 {
type Output = Vector2;
fn mul(mut self, rhs: f64) -> Self::Output {
self.0[0] *= rhs;
self.0[1] *= rhs;
self
}
}
impl Mul<f64> for Vector4 {
type Output = Vector4;
fn mul(mut self, rhs: f64) -> Self::Output {
self.0[0] *= rhs;
self.0[1] *= rhs;
self.0[2] *= rhs;
self.0[3] *= rhs;
self
}
}
impl Mul<f64> for Matrix2x2 {
type Output = Matrix2x2;
fn mul(mut self, rhs: f64) -> Self::Output {
self.0[0] *= rhs;
self.0[1] *= rhs;
self.0[2] *= rhs;
self.0[3] *= rhs;
self
}
}
impl Mul<f64> for Matrix4x4 {
type Output = Matrix4x4;
fn mul(mut self, rhs: f64) -> Self::Output {
self.0[0] *= rhs;
self.0[1] *= rhs;
self.0[2] *= rhs;
self.0[3] *= rhs;
self.0[4] *= rhs;
self.0[5] *= rhs;
self.0[6] *= rhs;
self.0[7] *= rhs;
self.0[8] *= rhs;
self.0[9] *= rhs;
self.0[10] *= rhs;
self.0[11] *= rhs;
self.0[12] *= rhs;
self.0[13] *= rhs;
self.0[14] *= rhs;
self.0[15] *= rhs;
self
}
}
pub trait SquareT {
type Output;
fn square_t(&self) -> Self::Output;
}
#[rustfmt::skip]
impl SquareT for Matrix1x1 {
type Output = Matrix1x1;
fn square_t(&self) -> Self::Output {
Matrix1x1([self.0[0].powi(2)])
}
}
#[rustfmt::skip]
impl SquareT for Vector2 {
type Output = Matrix2x2;
fn square_t(&self) -> Matrix2x2 {
let [x1, x2] = self.0;
Matrix2x2 ([
x1*x1, x1*x2,
x2*x1, x2*x2,
])
}
}
#[rustfmt::skip]
impl SquareT for Vector4 {
type Output = Matrix4x4;
fn square_t(&self) -> Matrix4x4 {
let [x1, x2, x3, x4] = self.0;
Matrix4x4 ([
x1*x1, x1*x2, x1*x3, x1*x4,
x2*x1, x2*x2, x2*x3, x2*x4,
x3*x1, x3*x2, x3*x3, x3*x4,
x4*x1, x4*x2, x4*x3, x4*x4,
])
}
}
pub trait MeanVector: Mul<f64> + MvAdd + MvSub + SquareT + Clone {
fn values(&self) -> &[f64];
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn from_dvector(vec: DVector<f64>) -> Self;
fn zeros() -> Self;
}
pub trait ScaleMatrix: Mul<f64> + MvAdd + MvSub + Clone {
fn values(&self) -> &[f64];
fn diagonalize(&mut self);
}
impl MeanVector for Matrix1x1 {
fn values(&self) -> &[f64] {
&self.0
}
fn len(&self) -> usize {
1
}
fn from_dvector(vec: DVector<f64>) -> Self {
Matrix1x1([vec[0]])
}
fn zeros() -> Self {
Matrix1x1([0.0])
}
}
impl MeanVector for Vector2 {
fn values(&self) -> &[f64] {
&self.0
}
fn len(&self) -> usize {
2
}
fn from_dvector(vec: DVector<f64>) -> Self {
Vector2([vec[0], vec[1]])
}
fn zeros() -> Self {
Self::new()
}
}
impl MeanVector for Vector4 {
fn values(&self) -> &[f64] {
&self.0
}
fn len(&self) -> usize {
4
}
fn from_dvector(vec: DVector<f64>) -> Self {
Vector4([vec[0], vec[1], vec[2], vec[3]])
}
fn zeros() -> Self {
Self::new()
}
}
impl ScaleMatrix for Matrix2x2 {
fn values(&self) -> &[f64] {
&self.0
}
fn diagonalize(&mut self) {
self.0[1] = 0.0;
self.0[2] = 0.0;
}
}
impl ScaleMatrix for Matrix4x4 {
fn values(&self) -> &[f64] {
&self.0
}
fn diagonalize(&mut self) {
self.0[1] = 0.0;
self.0[2] = 0.0;
self.0[3] = 0.0;
self.0[4] = self.0[4].max(1e-12);
self.0[4] = 0.0;
self.0[5] = self.0[5].max(1e-12);
self.0[6] = 0.0;
self.0[7] = 0.0;
self.0[8] = 0.0;
self.0[9] = 0.0;
self.0[10] = self.0[10].max(1e-12);
self.0[11] = 0.0;
self.0[12] = 0.0;
self.0[13] = 0.0;
self.0[14] = 0.0;
self.0[15] = self.0[15].max(1e-12);
}
}
impl ScaleMatrix for Matrix1x1 {
fn values(&self) -> &[f64] {
&self.0
}
fn diagonalize(&mut self) {}
}