1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
use super::*;
/// A trait for matrix types. In this lib a matrix is simply a collection of
/// vectors. The idea is that the matrix types can be used to reduce the size
/// of a large matrix and that the return types are basic enough
/// so that other specialized matrix libs can do the rest of the work, e.g.
/// inverting the resulting matrix.
pub trait Matrix<V, T>: MetaData + ResizeOps
where
V: Vector<T>,
T: RealNumber,
{
/// The x-axis delta. If `domain` is time domain then `delta` is in `[s]`,
/// in frequency domain `delta` is in `[Hz]`.
fn delta(&self) -> T;
/// Sets the x-axis delta. If `domain` is time domain then `delta` is in `[s]`,
/// in frequency domain `delta` is in `[Hz]`.
fn set_delta(&mut self, delta: T);
/// The number of valid elements in each row of the matrix. This can be changed
/// with the `Resize` trait.
fn row_len(&self) -> usize;
/// The number of valid points in a row. If the matrix is complex then every valid point
/// consists of two floating point numbers,
/// while for real vectors every point only consists of one floating point number.
fn row_points(&self) -> usize;
/// The number of columns in the matrix.
fn col_len(&self) -> usize;
/// Gets the rows as vectors.
fn rows(&self) -> &[V];
/// Gets the rows as mutable vectors.
fn rows_mut(&mut self) -> &mut [V];
}
macro_rules! add_mat_impl {
($($matrix:ident);*) => {
$(
impl<V, S, T> MetaData for $matrix<V, S, T>
where T: RealNumber,
S: ToSlice<T>,
V: Vector<T> {
fn domain(&self) -> DataDomain {
if self.rows.len() == 0 {
return DataDomain::Time;
}
self.rows[0].domain()
}
fn is_complex(&self) -> bool {
if self.rows.len() == 0 {
return false;
}
self.rows[0].is_complex()
}
}
impl<V, S, T> ResizeOps for $matrix<V, S, T>
where T: RealNumber,
S: ToSlice<T>,
V: Vector<T> {
fn resize(&mut self, len: usize) -> VoidResult {
for v in &mut self.rows[..] {
v.resize(len)?;
}
Ok(())
}
}
impl<V, S, T> Matrix<V, T> for $matrix<V, S, T>
where T: RealNumber,
S: ToSlice<T>,
V: Vector<T> {
fn delta(&self) -> T {
if self.rows.len() == 0 {
return T::zero();
}
self.rows[0].delta()
}
fn set_delta(&mut self, delta: T) {
for v in &mut self.rows[..] {
v.set_delta(delta);
}
}
fn row_len(&self) -> usize {
if self.rows.len() == 0 {
return 0;
}
self.rows[0].len()
}
fn row_points(&self) -> usize {
if self.rows.len() == 0 {
return 0;
}
self.rows[0].points()
}
fn col_len(&self) -> usize {
self.rows.len()
}
fn rows(&self) -> &[V] {
&self.rows[..]
}
fn rows_mut(&mut self) -> &mut [V] {
&mut self.rows[..]
}
}
impl<V, S, T, N, D> GetMetaData<T, N, D> for $matrix<V, S, T>
where T: RealNumber,
S: ToSlice<T>,
V: Vector<T> + GetMetaData<T, N, D>,
N: NumberSpace,
D: Domain {
fn get_meta_data(&self) -> TypeMetaData<T, N, D> {
self.rows[0].get_meta_data()
}
}
)*
}
}
add_mat_impl!(MatrixMxN; Matrix2xN; Matrix3xN; Matrix4xN);