OpenShot Library | OpenShotAudio  0.2.2
juce_Matrix.h
1 
2 /** @weakgroup juce_dsp-maths
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16  27th April 2017).
17 
18  End User License Agreement: www.juce.com/juce-5-licence
19  Privacy Policy: www.juce.com/juce-5-privacy-policy
20 
21  Or: You may also use this code under the terms of the GPL v3 (see
22  www.gnu.org/licenses).
23 
24  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26  DISCLAIMED.
27 
28  ==============================================================================
29 */
30 
31 namespace juce
32 {
33 namespace dsp
34 {
35 
36 /**
37  General matrix and vectors class, meant for classic math manipulation such as
38  additions, multiplications, and linear systems of equations solving.
39 
40  @see LinearAlgebra
41 
42  @tags{DSP}
43 */
44 template<typename ElementType>
45 class Matrix
46 {
47 public:
48  //==============================================================================
49  /** Creates a new matrix with a given number of rows and columns. */
50  Matrix (size_t numRows, size_t numColumns)
51  : rows (numRows), columns (numColumns)
52  {
53  resize();
54  clear();
55  }
56 
57  /** Creates a new matrix with a given number of rows and columns, with initial
58  data coming from an array, stored in row-major order.
59  */
60  Matrix (size_t numRows, size_t numColumns, const ElementType* dataPointer)
61  : rows (numRows), columns (numColumns)
62  {
63  resize();
64  memcpy (data.getRawDataPointer(), dataPointer, rows * columns * sizeof (ElementType));
65  }
66 
67  /** Creates a copy of another matrix. */
68  Matrix (const Matrix&) = default;
69 
70  /** Moves a copy of another matrix. */
71  Matrix (Matrix&&) noexcept = default;
72 
73  /** Creates a copy of another matrix. */
74  Matrix& operator= (const Matrix&) = default;
75 
76  /** Moves another matrix into this one */
77  Matrix& operator= (Matrix&&) noexcept = default;
78 
79  //==============================================================================
80  /** Creates the identity matrix */
81  static Matrix identity (size_t size);
82 
83  /** Creates a Toeplitz Matrix from a vector with a given squared size */
84  static Matrix toeplitz (const Matrix& vector, size_t size);
85 
86  /** Creates a squared size x size Hankel Matrix from a vector with an optional offset.
87 
88  @param vector The vector from which the Hankel matrix should be generated.
89  Its number of rows should be at least 2 * (size - 1) + 1
90  @param size The size of resulting square matrix.
91  @param offset An optional offset into the given vector.
92  */
93  static Matrix hankel (const Matrix& vector, size_t size, size_t offset = 0);
94 
95  //==============================================================================
96  /** Returns the number of rows in the matrix. */
97  size_t getNumRows() const noexcept { return rows; }
98 
99  /** Returns the number of columns in the matrix. */
100  size_t getNumColumns() const noexcept { return columns; }
101 
102  /** Returns an Array of 2 integers with the number of rows and columns in the
103  matrix.
104  */
105  Array<size_t> getSize() const noexcept { return { rows, columns }; }
106 
107  /** Fills the contents of the matrix with zeroes. */
108  void clear() noexcept { zeromem (data.begin(), (size_t) data.size() * sizeof (ElementType)); }
109 
110  //==============================================================================
111  /** Swaps the contents of two rows in the matrix and returns a reference to itself. */
112  Matrix& swapRows (size_t rowOne, size_t rowTwo) noexcept;
113 
114  /** Swaps the contents of two columns in the matrix and returns a reference to itself. */
115  Matrix& swapColumns (size_t columnOne, size_t columnTwo) noexcept;
116 
117  //==============================================================================
118  /** Returns the value of the matrix at a given row and column (for reading). */
119  inline ElementType operator() (size_t row, size_t column) const noexcept
120  {
121  jassert (row < rows && column < columns);
122  return data.getReference (static_cast<int> (dataAcceleration.getReference (static_cast<int> (row))) + static_cast<int> (column));
123  }
124 
125  /** Returns the value of the matrix at a given row and column (for modifying). */
126  inline ElementType& operator() (size_t row, size_t column) noexcept
127  {
128  jassert (row < rows && column < columns);
129  return data.getReference (static_cast<int> (dataAcceleration.getReference (static_cast<int> (row))) + static_cast<int> (column));
130  }
131 
132  /** Returns a pointer to the raw data of the matrix object, ordered in row-major
133  order (for modifying).
134  */
135  inline ElementType* getRawDataPointer() noexcept { return data.getRawDataPointer(); }
136 
137  /** Returns a pointer to the raw data of the matrix object, ordered in row-major
138  order (for reading).
139  */
140  inline const ElementType* getRawDataPointer() const noexcept { return data.begin(); }
141 
142  //==============================================================================
143  /** Addition of two matrices */
144  inline Matrix& operator+= (const Matrix& other) noexcept { return apply (other, [] (ElementType a, ElementType b) { return a + b; } ); }
145 
146  /** Subtraction of two matrices */
147  inline Matrix& operator-= (const Matrix& other) noexcept { return apply (other, [] (ElementType a, ElementType b) { return a - b; } ); }
148 
149  /** Scalar multiplication */
150  inline Matrix& operator*= (ElementType scalar) noexcept
151  {
152  std::for_each (begin(), end(), [scalar] (ElementType& x) { x *= scalar; });
153  return *this;
154  }
155 
156  /** Addition of two matrices */
157  inline Matrix operator+ (const Matrix& other) const { Matrix result (*this); result += other; return result; }
158 
159  /** Addition of two matrices */
160  inline Matrix operator- (const Matrix& other) const { Matrix result (*this); result -= other; return result; }
161 
162  /** Scalar multiplication */
163  inline Matrix operator* (ElementType scalar) const { Matrix result (*this); result *= scalar; return result; }
164 
165  /** Matrix multiplication */
166  Matrix operator* (const Matrix& other) const;
167 
168  /** Does a hadarmard product with the receiver and other and stores the result in the receiver */
169  inline Matrix& hadarmard (const Matrix& other) noexcept { return apply (other, [] (ElementType a, ElementType b) { return a * b; } ); }
170 
171  /** Does a hadarmard product with a and b returns the result. */
172  static inline Matrix hadarmard (const Matrix& a, const Matrix& b) { Matrix result (a); result.hadarmard (b); return result; }
173 
174  //==============================================================================
175  /** Compare to matrices with a given tolerance */
176  static bool compare (const Matrix& a, const Matrix& b, ElementType tolerance = 0) noexcept;
177 
178  /* Comparison operator */
179  inline bool operator== (const Matrix& other) const noexcept { return compare (*this, other); }
180 
181  //==============================================================================
182  /** Tells if the matrix is a square matrix */
183  bool isSquare() const noexcept { return rows == columns; }
184 
185  /** Tells if the matrix is a vector */
186  bool isVector() const noexcept { return isOneColumnVector() || isOneRowVector(); }
187 
188  /** Tells if the matrix is a one column vector */
189  bool isOneColumnVector() const noexcept { return columns == 1; }
190 
191  /** Tells if the matrix is a one row vector */
192  bool isOneRowVector() const noexcept { return rows == 1; }
193 
194  /** Tells if the matrix is a null matrix */
195  bool isNullMatrix() const noexcept { return rows == 0 || columns == 0; }
196 
197  //==============================================================================
198  /** Solves a linear system of equations represented by this object and the argument b,
199  using various algorithms depending on the size of the arguments.
200 
201  The matrix must be a square matrix N times N, and b must be a vector N times 1,
202  with the coefficients of b. After the execution of the algorithm,
203  the vector b will contain the solution.
204 
205  Returns true if the linear system of equations was successfully solved.
206  */
207  bool solve (Matrix& b) const noexcept;
208 
209  //==============================================================================
210  /** Returns a String displaying in a convenient way the matrix contents. */
211  String toString() const;
212 
213  //==============================================================================
214  ElementType* begin() noexcept { return data.begin(); }
215  ElementType* end() noexcept { return data.end(); }
216 
217  const ElementType* begin() const noexcept { return &data.getReference (0); }
218  const ElementType* end() const noexcept { return begin() + data.size(); }
219 
220 private:
221  //==============================================================================
222  /** Resizes the matrix. */
223  void resize()
224  {
225  data.resize (static_cast<int> (columns * rows));
226  dataAcceleration.resize (static_cast<int> (rows));
227 
228  for (size_t i = 0; i < rows; ++i)
229  dataAcceleration.setUnchecked (static_cast<int> (i), i * columns);
230  }
231 
232  template <typename BinaryOperation>
233  Matrix& apply (const Matrix& other, BinaryOperation binaryOp)
234  {
235  jassert (rows == other.rows && columns == other.columns);
236 
237  auto* dst = getRawDataPointer();
238 
239  for (auto src : other)
240  {
241  *dst = binaryOp (*dst, src);
242  ++dst;
243  }
244 
245  return *this;
246  }
247 
248  //==============================================================================
249  Array<ElementType> data;
250  Array<size_t> dataAcceleration;
251 
252  size_t rows, columns;
253 
254  //==============================================================================
255  JUCE_LEAK_DETECTOR (Matrix)
256 };
257 
258 } // namespace dsp
259 } // namespace juce
260 
261 /** @}*/
void setUnchecked(int indexToChange, ParameterType newValue)
Replaces an element with a new value without doing any bounds-checking.
Definition: juce_Array.h:572
ElementType & getReference(int index) noexcept
Returns a direct reference to one of the elements in the array, without checking the index passed in.
Definition: juce_Array.h:271
void resize(int targetNumItems)
This will enlarge or shrink the array to the given number of elements, by adding or removing items fr...
Definition: juce_Array.h:674
The JUCE String class!
Definition: juce_String.h:43
General matrix and vectors class, meant for classic math manipulation such as additions,...
Definition: juce_Matrix.h:46
Matrix operator-(const Matrix &other) const
Addition of two matrices.
Definition: juce_Matrix.h:160
Matrix & hadarmard(const Matrix &other) noexcept
Does a hadarmard product with the receiver and other and stores the result in the receiver.
Definition: juce_Matrix.h:169
Matrix & swapRows(size_t rowOne, size_t rowTwo) noexcept
Swaps the contents of two rows in the matrix and returns a reference to itself.
Definition: juce_Matrix.cpp:97
Matrix & operator+=(const Matrix &other) noexcept
Addition of two matrices.
Definition: juce_Matrix.h:144
size_t getNumRows() const noexcept
Returns the number of rows in the matrix.
Definition: juce_Matrix.h:97
Matrix(Matrix &&) noexcept=default
Moves a copy of another matrix.
static Matrix hadarmard(const Matrix &a, const Matrix &b)
Does a hadarmard product with a and b returns the result.
Definition: juce_Matrix.h:172
static bool compare(const Matrix &a, const Matrix &b, ElementType tolerance=0) noexcept
Compare to matrices with a given tolerance.
ElementType * getRawDataPointer() noexcept
Returns a pointer to the raw data of the matrix object, ordered in row-major order (for modifying).
Definition: juce_Matrix.h:135
Matrix(const Matrix &)=default
Creates a copy of another matrix.
bool isOneColumnVector() const noexcept
Tells if the matrix is a one column vector.
Definition: juce_Matrix.h:189
bool isVector() const noexcept
Tells if the matrix is a vector.
Definition: juce_Matrix.h:186
bool isNullMatrix() const noexcept
Tells if the matrix is a null matrix.
Definition: juce_Matrix.h:195
Matrix & swapColumns(size_t columnOne, size_t columnTwo) noexcept
Swaps the contents of two columns in the matrix and returns a reference to itself.
Definition: juce_Matrix.cpp:81
Matrix(size_t numRows, size_t numColumns)
Creates a new matrix with a given number of rows and columns.
Definition: juce_Matrix.h:50
static Matrix hankel(const Matrix &vector, size_t size, size_t offset=0)
Creates a squared size x size Hankel Matrix from a vector with an optional offset.
Definition: juce_Matrix.cpp:62
Array< size_t > getSize() const noexcept
Returns an Array of 2 integers with the number of rows and columns in the matrix.
Definition: juce_Matrix.h:105
Matrix operator*(ElementType scalar) const
Scalar multiplication.
Definition: juce_Matrix.h:163
ElementType operator()(size_t row, size_t column) const noexcept
Returns the value of the matrix at a given row and column (for reading).
Definition: juce_Matrix.h:119
Matrix & operator-=(const Matrix &other) noexcept
Subtraction of two matrices.
Definition: juce_Matrix.h:147
Matrix operator+(const Matrix &other) const
Addition of two matrices.
Definition: juce_Matrix.h:157
static Matrix identity(size_t size)
Creates the identity matrix.
Definition: juce_Matrix.cpp:33
bool solve(Matrix &b) const noexcept
Solves a linear system of equations represented by this object and the argument b,...
static Matrix toeplitz(const Matrix &vector, size_t size)
Creates a Toeplitz Matrix from a vector with a given squared size.
Definition: juce_Matrix.cpp:44
Matrix(size_t numRows, size_t numColumns, const ElementType *dataPointer)
Creates a new matrix with a given number of rows and columns, with initial data coming from an array,...
Definition: juce_Matrix.h:60
Matrix & operator*=(ElementType scalar) noexcept
Scalar multiplication.
Definition: juce_Matrix.h:150
size_t getNumColumns() const noexcept
Returns the number of columns in the matrix.
Definition: juce_Matrix.h:100
bool isSquare() const noexcept
Tells if the matrix is a square matrix.
Definition: juce_Matrix.h:183
bool isOneRowVector() const noexcept
Tells if the matrix is a one row vector.
Definition: juce_Matrix.h:192
void clear() noexcept
Fills the contents of the matrix with zeroes.
Definition: juce_Matrix.h:108
const ElementType * getRawDataPointer() const noexcept
Returns a pointer to the raw data of the matrix object, ordered in row-major order (for reading).
Definition: juce_Matrix.h:140
String toString() const
Returns a String displaying in a convenient way the matrix contents.