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
use basic_dsp_vector::*;
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[..]
                }
            }
        )*
    }
}

add_mat_impl!(MatrixMxN; Matrix2xN; Matrix3xN; Matrix4xN);