concision_core/traits/arr/
ops.rs1use nd::linalg::Dot;
6use nd::*;
7use num::traits::{Num, NumAssign};
8
9pub trait Affine<X, Y = X> {
10 type Output;
11
12 fn affine(&self, mul: X, add: Y) -> Self::Output;
13}
14
15pub trait Inverse {
16 type Output;
17
18 fn inverse(&self) -> Self::Output;
19}
20
21pub trait Matmul<Rhs = Self> {
22 type Output;
23
24 fn matmul(&self, rhs: &Rhs) -> Self::Output;
25}
26
27pub trait Matpow<Rhs = Self> {
28 type Output;
29
30 fn pow(&self, rhs: Rhs) -> Self::Output;
31}
32
33impl<A, D> Affine<A> for Array<A, D>
37where
38 A: LinalgScalar + ScalarOperand,
39 D: Dimension,
40{
41 type Output = Array<A, D>;
42
43 fn affine(&self, mul: A, add: A) -> Self::Output {
44 self * mul + add
45 }
46}
47
48impl<T> Inverse for Array<T, Ix2>
50where
51 T: Copy + NumAssign + ScalarOperand,
52{
53 type Output = Option<Self>;
54 fn inverse(&self) -> Self::Output {
55 crate::inverse(self)
56 }
57}
58
59impl<S, X, Y> Matmul<X> for S
60where
61 S: Dot<X, Output = Y>,
62{
63 type Output = Y;
64
65 fn matmul(&self, rhs: &X) -> Self::Output {
66 self.dot(rhs)
67 }
68}
69
70impl<A, S> Matpow<i32> for ArrayBase<S, nd::Ix2>
71where
72 A: Copy + Num + 'static,
73 S: Data<Elem = A>,
74 ArrayBase<S, Ix2>: Clone + Dot<ArrayBase<S, Ix2>, Output = Array<A, Ix2>>,
75{
76 type Output = Array<A, Ix2>;
77
78 fn pow(&self, rhs: i32) -> Self::Output {
79 if !self.is_square() {
80 panic!("Matrix must be square to be raised to a power");
81 }
82 let mut res = Array::eye(self.shape()[0]);
83 for _ in 0..rhs {
84 res = res.dot(self);
85 }
86 res
87 }
88}