use super::Matrix;
use crate::algebra::linear::scalar::Scalar;
use crate::algebra::linear::vec::Vector;
use crate::algebra::linear::SquareMatrix;
use fructose::algebra::field::{ComplexField, Field};
use fructose::algebra::linear::vector::{AffineSpace, InnerSpace, Norm, NormedSpace, VectorSpace};
use fructose::algebra::module::Module;
use fructose::algebra::ring::CommutativeRing;
use fructose::operators::{Additive, ClosedAdd, ClosedMul, ClosedOps, Multiplicative};
use fructose::properties::general::{Associative, Commutative, Identity, Invertible, Set, Total};
use fructose::properties::helpers::identity::{One, Zero};
use std::iter::Sum;
impl<T: Scalar + ClosedAdd, const M: usize, const N: usize> Set<Additive>
for Matrix<T, { M }, { N }>
{
fn operate(&self, rhs: Self) -> Self {
*self + rhs
}
}
impl<T: Scalar + ClosedAdd + Total<Additive>, const M: usize, const N: usize> Total<Additive>
for Matrix<T, { M }, { N }>
{
}
impl<T: Scalar + ClosedAdd + Associative<Additive>, const M: usize, const N: usize>
Associative<Additive> for Matrix<T, { M }, { N }>
{
}
impl<T: Scalar + ClosedAdd + Commutative<Additive>, const M: usize, const N: usize>
Commutative<Additive> for Matrix<T, { M }, { N }>
{
}
impl<T: Scalar + ClosedAdd + Identity<Additive> + PartialEq, const M: usize, const N: usize>
Identity<Additive> for Matrix<T, { M }, { N }>
{
fn identity() -> Self {
Self::broadcast(T::identity())
}
fn is_identity(&self) -> bool {
*self == Self::identity()
}
}
impl<T: Scalar + ClosedAdd + Invertible<Additive>, const M: usize, const N: usize>
Invertible<Additive> for Matrix<T, { M }, { N }>
{
fn inverse(&self) -> Self {
-*self
}
fn inverted(&mut self) {
*self = -*self;
}
}
impl<T: Scalar + ClosedAdd + ClosedMul, const N: usize> Set<Multiplicative>
for SquareMatrix<T, { N }>
{
fn operate(&self, rhs: Self) -> Self {
*self * rhs
}
}
impl<T: Scalar + ClosedAdd + ClosedMul + Total<Multiplicative>, const N: usize>
Total<Multiplicative> for SquareMatrix<T, { N }>
{
}
impl<T: Scalar + ClosedAdd + ClosedMul + Associative<Multiplicative>, const N: usize>
Associative<Multiplicative> for SquareMatrix<T, { N }>
{
}
impl<T: Scalar + ClosedAdd + ClosedMul + Commutative<Multiplicative>, const N: usize>
Commutative<Multiplicative> for SquareMatrix<T, { N }>
{
}
impl<T: Scalar + ClosedAdd + ClosedMul + Identity<Multiplicative> + PartialEq, const N: usize>
Identity<Multiplicative> for SquareMatrix<T, { N }>
{
fn identity() -> Self {
Self::broadcast(T::identity())
}
fn is_identity(&self) -> bool {
*self == Self::identity()
}
}
impl<T: Scalar + ClosedAdd + ClosedMul + Invertible<Multiplicative>, const N: usize>
Invertible<Multiplicative> for SquareMatrix<T, { N }>
{
fn inverse(&self) -> Self {
unimplemented!()
}
fn inverted(&mut self) {
*self = self.inverse()
}
}
impl<T: Scalar + ComplexField + ClosedOps + Norm, const M: usize, const N: usize> Norm
for Matrix<T, { M }, { N }>
{
type Norm = T;
}
impl<T: Scalar + ClosedAdd + CommutativeRing, const M: usize, const N: usize> Module
for Matrix<T, { M }, { N }>
{
type Ring = T;
}
impl<T: Scalar + ClosedOps + Field, const M: usize, const N: usize> VectorSpace
for Matrix<T, { M }, { N }>
{
type Field = T;
}
impl<
T: Scalar + ClosedOps + ComplexField<RealField = T> + Norm + Sum,
const M: usize,
const N: usize,
> NormedSpace for Matrix<T, { M }, { N }>
{
type ComplexField = T;
fn norm_squared(&self) -> Self::Norm {
self.data
.iter()
.map(|col| col.iter().map(|e| *e * *e).sum())
.sum()
}
fn norm(&self) -> Self::Norm {
self.norm_squared().sqrt()
}
fn normalize(&mut self) {
let magnitude = self.norm();
self.data
.iter_mut()
.for_each(|col| col.iter_mut().for_each(|e| *e /= magnitude));
}
fn normalized(&self) -> Self {
let mut mat = *self;
mat.normalize();
mat
}
}
impl<
T: Scalar + ClosedOps + ComplexField<RealField = T> + Norm + Sum + Zero + One,
const N: usize,
> InnerSpace for Vector<T, { N }>
{
fn inner_product(&self, other: &Self) -> Self::ComplexField {
self.dot(*other)
}
fn angle(&self, other: &Self) -> Self::Norm {
let dot = self.dot(*other);
let n1 = self.norm();
let n2 = other.norm();
if n1.is_zero() || n2.is_zero() {
T::zero()
} else {
let prod = dot.real() / (n1 * n2);
unimplemented!()
}
}
}
impl<T: Scalar + ClosedOps + ComplexField<RealField = T> + Norm, const N: usize> AffineSpace
for Vector<T, { N }>
{
type Translation = Self;
fn translate_by(&self, translation: &Self::Translation) -> Self {
*self + *translation
}
fn subtract(&self, rhs: &Self) -> Self::Translation {
*self - *rhs
}
}