acme_tensor/linalg/
specs.rs

1/*
2    Appellation: specs <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use core::iter::Sum;
6use core::ops::{Add, Mul};
7
8/// [Affine] describes a type of geometric transformation which preserves
9/// lines and parallelisms.
10///
11/// ### General Formula
12/// f(x) = A * x + b
13pub trait Affine<A, B> {
14    type Output;
15
16    fn affine(&self, mul: A, add: B) -> Self::Output;
17}
18
19impl<S, A, B, C> Affine<A, B> for S
20where
21    S: Clone + Mul<A, Output = C>,
22    C: Add<B, Output = C>,
23{
24    type Output = C;
25
26    fn affine(&self, mul: A, add: B) -> Self::Output {
27        self.clone() * mul + add
28    }
29}
30
31/// Inversion
32///
33/// The inverse of a matrix is a matrix that, when multiplied with the original matrix, gives the
34/// identity matrix.
35pub trait Inverse {
36    type Output;
37
38    fn inv(&self) -> Self::Output;
39}
40
41impl<S, T> Inverse for S
42where
43    S: Clone + num::traits::Inv<Output = T>,
44{
45    type Output = T;
46
47    fn inv(&self) -> Self::Output {
48        self.clone().inv()
49    }
50}
51
52/// Matrix multiplication
53pub trait Matmul<Rhs = Self> {
54    type Output;
55
56    fn matmul(&self, rhs: &Rhs) -> Self::Output;
57}
58
59impl<A, B, C> Matmul<Vec<B>> for Vec<A>
60where
61    A: Clone + Mul<B, Output = C>,
62    B: Clone,
63    C: Sum,
64{
65    type Output = C;
66
67    fn matmul(&self, rhs: &Vec<B>) -> Self::Output {
68        self.iter()
69            .cloned()
70            .zip(rhs.iter().cloned())
71            .map(|(a, b)| a * b)
72            .sum()
73    }
74}
75
76// impl_matmul!(Vec, Vec, Vec);