OpenShot Library | OpenShotAudio  0.2.1
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 /** @}*/
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) const
Addition of two matrices.
Definition: juce_Matrix.h:157
Matrix operator*(ElementType scalar) const
Scalar multiplication.
Definition: juce_Matrix.h:163
size_t getNumColumns() const noexcept
Returns the number of columns in the matrix.
Definition: juce_Matrix.h:100
ElementType * end() noexcept
Returns a pointer to the element which follows the last element in the array.
Definition: juce_Array.h:348
bool isOneColumnVector() const noexcept
Tells if the matrix is a one column vector.
Definition: juce_Matrix.h:189
static Matrix identity(size_t size)
Creates the identity matrix.
Definition: juce_Matrix.cpp:33
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 & 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
The JUCE String class!
Definition: juce_String.h:42
bool isOneRowVector() const noexcept
Tells if the matrix is a one row vector.
Definition: juce_Matrix.h:192
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
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
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
String toString() const
Returns a String displaying in a convenient way the matrix contents.
Matrix(size_t numRows, size_t numColumns)
Creates a new matrix with a given number of rows and columns.
Definition: juce_Matrix.h:50
ElementType * begin() noexcept
Returns a pointer to the first element in the array.
Definition: juce_Array.h:332
size_t getNumRows() const noexcept
Returns the number of rows in the matrix.
Definition: juce_Matrix.h:97
Matrix operator-(const Matrix &other) const
Addition of two matrices.
Definition: juce_Matrix.h:160
void setUnchecked(int indexToChange, ParameterType newValue)
Replaces an element with a new value without doing any bounds-checking.
Definition: juce_Array.h:572
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
bool solve(Matrix &b) const noexcept
Solves a linear system of equations represented by this object and the argument b, using various algorithms depending on the size of the arguments.
bool isSquare() const noexcept
Tells if the matrix is a square matrix.
Definition: juce_Matrix.h:183
Matrix & operator=(const Matrix &)=default
Creates a copy of another matrix.
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
int size() const noexcept
Returns the current number of elements in the array.
Definition: juce_Array.h:219
Matrix & operator+=(const Matrix &other) noexcept
Addition of two matrices.
Definition: juce_Matrix.h:144
ElementType * getRawDataPointer() noexcept
Returns a pointer to the actual array data.
Definition: juce_Array.h:314
Matrix & operator*=(ElementType scalar) noexcept
Scalar multiplication.
Definition: juce_Matrix.h:150
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
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
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
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
General matrix and vectors class, meant for classic math manipulation such as additions, multiplications, and linear systems of equations solving.
Definition: juce_Matrix.h:45
static bool compare(const Matrix &a, const Matrix &b, ElementType tolerance=0) noexcept
Compare to matrices with a given tolerance.
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
bool isNullMatrix() const noexcept
Tells if the matrix is a null matrix.
Definition: juce_Matrix.h:195
bool isVector() const noexcept
Tells if the matrix is a vector.
Definition: juce_Matrix.h:186
Matrix & operator-=(const Matrix &other) noexcept
Subtraction of two matrices.
Definition: juce_Matrix.h:147