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
139
use basic_dsp_vector::*;
use basic_dsp_vector::numbers::*;
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[..] {
						  try!(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);