LCOV - code coverage report
Current view: top level - src/include/linalg - Matrix.hpp (source / functions) Hit Total Coverage
Test: 98c60408be2d766eef282c11e0ebd9afde851352 Lines: 33 33 100.0 %
Date: 2021-02-20 15:44:35 Functions: 32 32 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "Arduino/ArduinoConfig.hpp"
       4             : 
       5             : #include <algorithm>  // std::fill, std::transform
       6             : #include <cassert>    // assert
       7             : #include <cmath>      // std::sqrt
       8             : #include <functional> // std::plus, std::minus
       9             : #include <numeric>    // std::inner_product
      10             : #include <utility>    // std::swap
      11             : #include <vector>     // std::vector
      12             : 
      13             : #ifndef NO_IOSTREAM_SUPPORT
      14             : #include <iosfwd> // std::ostream
      15             : #endif
      16             : 
      17             : #ifndef NO_RANDOM_SUPPORT
      18             : #include <random> // std::uniform_real_distribution
      19             : #endif
      20             : 
      21             : using std::size_t;
      22             : 
      23             : #include "util/MatrixStorage.hpp"
      24             : 
      25             : #ifndef COL_MAJ_ORDER
      26             : #define COL_MAJ_ORDER 1
      27             : #endif
      28             : 
      29             : /// @addtogroup MatVec
      30             : /// @{
      31             : 
      32             : #ifndef NO_ARDUINO_PRINT_SUPPORT
      33             : /// General matrix class.
      34             : class Matrix : public Printable {
      35             : #else
      36          35 : class Matrix {
      37             : #endif
      38             : 
      39             :     /// Container to store the elements of the matrix internally.
      40             :     using storage_t = util::storage_t<double>;
      41             : 
      42             :   protected:
      43             :     /// Convert raw storage to a matrix.
      44             :     explicit Matrix(storage_t &&storage, size_t rows, size_t cols);
      45             :     /// Convert raw storage to a matrix.
      46             :     explicit Matrix(const storage_t &storage, size_t rows, size_t cols);
      47             : 
      48             :   public:
      49             :     /// @name   Constructors and assignment
      50             :     /// @{
      51             : 
      52             :     /// Default constructor.
      53         393 :     Matrix() = default;
      54             : 
      55             :     /// Create a matrix of zeros with the given dimensions.
      56             :     Matrix(size_t rows, size_t cols);
      57             : 
      58             :     /// Create a matrix with the given values.
      59             :     Matrix(std::initializer_list<std::initializer_list<double>> init);
      60             :     /// Assign the given values to the matrix.
      61             :     Matrix &
      62             :     operator=(std::initializer_list<std::initializer_list<double>> init);
      63             : 
      64             :     /// Default copy constructor.
      65          27 :     Matrix(const Matrix &) = default;
      66             :     /// Move constructor.
      67             :     Matrix(Matrix &&);
      68             : 
      69             :     /// Default copy assignment.
      70             :     Matrix &operator=(const Matrix &) = default;
      71             :     /// Move assignment.
      72             :     Matrix &operator=(Matrix &&);
      73             : 
      74             :     /// @}
      75             : 
      76             :   public:
      77             :     /// @name   Matrix size
      78             :     /// @{
      79             : 
      80             :     /// Get the number of rows of the matrix.
      81        5534 :     size_t rows() const { return rows_; }
      82             :     /// Get the number of columns of the matrix.
      83        4596 :     size_t cols() const { return cols_; }
      84             :     /// Get the number of elements in the matrix:
      85         197 :     size_t num_elems() const { return storage.size(); }
      86             : 
      87             :     /// Reshape the matrix. The new size must have the same number of elements,
      88             :     /// and the result depends on the storage order (column major order or
      89             :     /// row major order).
      90             :     void reshape(size_t newrows, size_t newcols);
      91             :     /// Create a reshaped copy of the matrix.
      92             :     /// @see    @ref reshape
      93             :     Matrix reshaped(size_t newrows, size_t newcols) const;
      94             : 
      95             :     /// @}
      96             : 
      97             :   public:
      98             :     /// @name   Element access
      99             :     /// @{
     100             : 
     101             :     /// Get the element at the given position in the matrix.
     102             :     double &operator()(size_t row, size_t col);
     103             :     /// Get the element at the given position in the matrix.
     104             :     const double &operator()(size_t row, size_t col) const;
     105             : 
     106             :     /// Get the element at the given position in the linearized matrix.
     107         298 :     double &operator()(size_t index) { return storage[index]; }
     108             :     /// Get the element at the given position in the linearized matrix.
     109         188 :     const double &operator()(size_t index) const { return storage[index]; }
     110             : 
     111             :     /// @}
     112             : 
     113             :   public:
     114             :     /// @name   Memory management
     115             :     /// @{
     116             : 
     117             :     /// Set the number of rows and columns to zero, and deallocate the storage.
     118             :     void clear_and_deallocate();
     119             : 
     120             :     /// @}
     121             : 
     122             :   public:
     123             :     /// @name   Filling matrices
     124             :     /// @{
     125             : 
     126             :     /// Fill the matrix with a constant value.
     127             :     void fill(double value);
     128             : 
     129             :     /// Fill the matrix as an identity matrix (all zeros except the diagonal
     130             :     /// which is one).
     131             :     void fill_identity();
     132             : 
     133             : #ifndef NO_RANDOM_SUPPORT
     134             :     /// Fill the matrix with uniformly distributed random values.
     135             :     void fill_random(double min = 0, double max = 1,
     136             :                      std::default_random_engine::result_type seed =
     137             :                          std::default_random_engine::default_seed);
     138             : #endif
     139             : 
     140             :     /// @}
     141             : 
     142             :   public:
     143             :     /// @name   Create special matrices
     144             :     /// @{
     145             : 
     146             :     /// Create a matrix filled with ones.
     147             :     static Matrix ones(size_t rows, size_t cols);
     148             : 
     149             :     /// Create a matrix filled with zeros.
     150             :     static Matrix zeros(size_t rows, size_t cols);
     151             : 
     152             :     /// Create a matrix filled with a constant value.
     153             :     static Matrix constant(size_t rows, size_t cols, double value);
     154             : 
     155             :     /// Create an identity matrix.
     156             :     static Matrix identity(size_t rows, size_t cols);
     157             : 
     158             :     /// Create a square identity matrix.
     159             :     static Matrix identity(size_t rows);
     160             : 
     161             : #ifndef NO_RANDOM_SUPPORT
     162             :     /// Create a matrix with uniformly distributed random values.
     163             :     static Matrix random(size_t rows, size_t cols, double min = 0,
     164             :                          double max = 1,
     165             :                          std::default_random_engine::result_type seed =
     166             :                              std::default_random_engine::default_seed);
     167             : #endif
     168             : 
     169             :     /// @}
     170             : 
     171             :   public:
     172             :     /// @name   Swapping rows and columns
     173             :     /// @{
     174             : 
     175             :     /// Swap two rows of the matrix.
     176             :     void swap_rows(size_t a, size_t b);
     177             :     /// Swap two columns of the matrix.
     178             :     void swap_columns(size_t a, size_t b);
     179             : 
     180             :     /// @}
     181             : 
     182             :   public:
     183             :     /// @name   Comparison
     184             :     /// @{
     185             : 
     186             :     /// Check for equality of two matrices.
     187             :     /// @warning    Uses exact comparison, which is often not appropriate for
     188             :     ///             floating point numbers.
     189             :     bool operator==(const Matrix &other) const;
     190             :     /// Check for inequality of two matrices.
     191             :     /// @warning    Uses exact comparison, which is often not appropriate for
     192             :     ///             floating point numbers.
     193             :     bool operator!=(const Matrix &other) const { return !(*this == other); }
     194             : 
     195             :     /// @}
     196             : 
     197             :   public:
     198             :     /// @name   Matrix norms
     199             :     /// @{
     200             : 
     201             :     /// Compute the Frobenius norm of the matrix.
     202             :     double normFro() const &;
     203             :     /// Compute the Frobenius norm of the matrix.
     204             :     double normFro() &&;
     205             : 
     206             :     /// @}
     207             : 
     208             :   public:
     209             :     /// @name   Iterators
     210             :     /// @{
     211             : 
     212             :     /// Get the iterator to the first element of the matrix.
     213         132 :     storage_t::iterator begin() { return storage.begin(); }
     214             :     /// Get the iterator to the first element of the matrix.
     215         428 :     storage_t::const_iterator begin() const { return storage.begin(); }
     216             :     /// Get the iterator to the first element of the matrix.
     217             :     storage_t::const_iterator cbegin() const { return storage.begin(); }
     218             : 
     219             :     /// Get the iterator to the element past the end of the matrix.
     220          52 :     storage_t::iterator end() { return storage.end(); }
     221             :     /// Get the iterator to the element past the end of the matrix.
     222         360 :     storage_t::const_iterator end() const { return storage.end(); }
     223             :     /// Get the iterator to the element past the end of the matrix.
     224             :     storage_t::const_iterator cend() const { return storage.end(); }
     225             : 
     226             :     /// @}
     227             : 
     228             :   public:
     229             :     /// @name   Printing
     230             :     /// @{
     231             : 
     232             : #ifndef NO_IOSTREAM_SUPPORT
     233             :     /// Print a matrix.
     234             :     /// @param  os
     235             :     ///         The stream to print to.
     236             :     /// @param  precision
     237             :     ///         The number of significant figures to print.
     238             :     ///         (0 = auto)
     239             :     /// @param  width
     240             :     ///         The width of each element (number of characters).
     241             :     ///         (0 = auto)
     242             :     void print(std::ostream &os, uint8_t precision = 0,
     243             :                uint8_t width = 0) const;
     244             : #endif
     245             : 
     246             : #ifndef NO_ARDUINO_PRINT_SUPPORT
     247             :     /// Print a matrix
     248             :     /// @param  print
     249             :     ///         The printer to print to.
     250             :     /// @param  precision
     251             :     ///         The number of significant figures to print.
     252             :     ///         (0 = auto)
     253             :     /// @param  width
     254             :     ///         The width of each element (number of characters).
     255             :     ///         (0 = auto)
     256             :     void print(Print &print, uint8_t precision = 0, uint8_t width = 0) const;
     257             : 
     258             :     /// Implements the Arduino Printable interface.
     259             :     size_t printTo(Print &print) const override {
     260             :         this->print(print);
     261             :         return 0;
     262             :     }
     263             : #endif
     264             : 
     265             :     /// @}
     266             : 
     267             :   protected:
     268             :     size_t rows_ = 0, cols_ = 0;
     269             :     storage_t storage;
     270             : 
     271             :     friend class Vector;
     272             :     friend class RowVector;
     273             : };
     274             : 
     275             : // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
     276             : 
     277             : /// A column vector (n×1 matrix).
     278             : class Vector : public Matrix {
     279             :   public:
     280             :     /// @name   Constructors and assignment
     281             :     /// @{
     282             : 
     283             :     /// Default constructor.
     284          12 :     Vector() = default;
     285             : 
     286             :     /// Create a column vector of the given size.
     287             :     Vector(size_t size) : Matrix(size, 1) {}
     288             : 
     289             :     /// Create a column vector from the given list of values.
     290         136 :     Vector(std::initializer_list<double> init) { *this = init; }
     291             : 
     292             :     /// Assign a list of values to the column vector.
     293             :     Vector &operator=(std::initializer_list<double> init);
     294             : 
     295             :     /// Convert an m×n matrix to a mn column vector.
     296             :     explicit Vector(const Matrix &matrix);
     297             :     /// Convert an m×n matrix to a mn column vector.
     298             :     explicit Vector(Matrix &&matrix);
     299             : 
     300             :     /// @}
     301             : 
     302             :   public:
     303             :     /// @name   Vector size
     304             :     /// @{
     305             : 
     306             :     /// Resize the vector.
     307          12 :     void resize(size_t size) { storage.resize(size); }
     308             : 
     309             :     /// Get the number of elements in the vector.
     310          40 :     size_t size() const { return num_elems(); }
     311             : 
     312             :     /// Reshaping a vector to a matrix requires an explicit cast.
     313             :     void reshape(size_t, size_t) = delete;
     314             :     /// Reshaping a vector to a matrix requires an explicit cast.
     315             :     Matrix reshaped(size_t, size_t) = delete;
     316             : 
     317             :     /// @}
     318             : 
     319             :   public:
     320             :     /// @name   Creating special vectors
     321             :     /// @{
     322             : 
     323             :     /// Create a vector filled with ones.
     324             :     static Vector ones(size_t size);
     325             :     /// Create a vector filled with zeros.
     326             :     static Vector zeros(size_t size);
     327             :     /// Create a vector filled with a constant value.
     328             :     static Vector constant(size_t size, double value);
     329             : 
     330             : #ifndef NO_RANDOM_SUPPORT
     331             :     /// Create a vector with uniformly distributed random values.
     332             :     static Vector random(size_t size, double min = 0, double max = 1,
     333             :                          std::default_random_engine::result_type seed =
     334             :                              std::default_random_engine::default_seed);
     335             : #endif
     336             : 
     337             :     /// @}
     338             : 
     339             :   public:
     340             :     /// @name Dot products
     341             :     /// @{
     342             : 
     343             :     /// Compute the dot product of two vectors. Reinterprets matrices as
     344             :     /// vectors.
     345             :     static double dot_unchecked(const Matrix &a, const Matrix &b);
     346             :     /// Compute the dot product of two vectors. Reinterprets matrices as
     347             :     /// vectors.
     348             :     static double dot_unchecked(Matrix &&a, const Matrix &b);
     349             :     /// Compute the dot product of two vectors. Reinterprets matrices as
     350             :     /// vectors.
     351             :     static double dot_unchecked(const Matrix &a, Matrix &&b);
     352             :     /// Compute the dot product of two vectors. Reinterprets matrices as
     353             :     /// vectors.
     354             :     static double dot_unchecked(Matrix &&a, Matrix &&b);
     355             : 
     356             :     /// Compute the dot product of two vectors.
     357             :     static double dot(const Vector &a, const Vector &b);
     358             :     /// Compute the dot product of two vectors.
     359             :     static double dot(Vector &&a, const Vector &b);
     360             :     /// Compute the dot product of two vectors.
     361             :     static double dot(const Vector &a, Vector &&b);
     362             :     /// Compute the dot product of two vectors.
     363             :     static double dot(Vector &&a, Vector &&b);
     364             : 
     365             :     /// Compute the dot product of this vector with another vector.
     366           2 :     double dot(const Vector &b) const & { return dot(*this, b); }
     367             :     /// Compute the dot product of this vector with another vector.
     368           1 :     double dot(const Vector &b) && { return dot(std::move(*this), b); }
     369             :     /// Compute the dot product of this vector with another vector.
     370           2 :     double dot(Vector &&b) const & { return dot(*this, std::move(b)); }
     371             :     /// Compute the dot product of this vector with another vector.
     372           1 :     double dot(Vector &&b) && { return dot(std::move(*this), std::move(b)); }
     373             : 
     374             :     /// @}
     375             : 
     376             :   public:
     377             :     /// @name Cross products
     378             :     /// @{
     379             : 
     380             :     /// Compute the cross product of two 3-vectors, overwriting the first vector
     381             :     /// with the result. Reinterprets matrices as vectors (so it can be used
     382             :     /// with row vectors as well).
     383             :     static void cross_inplace_unchecked(Matrix &a, const Matrix &b);
     384             :     /// Compute the opposite of the cross product of two 3-vectors, overwriting
     385             :     /// the first vector with the result. Reinterprets matrices as vectors
     386             :     /// (so it can be used with row vectors as well).
     387             :     static void cross_inplace_unchecked_neg(Matrix &a, const Matrix &b);
     388             : 
     389             :     /// Compute the cross product of two 3-vectors, overwriting the first vector
     390             :     /// with the result.
     391             :     static void cross_inplace(Vector &a, const Vector &b);
     392             :     /// Compute the cross product of two 3-vectors, overwriting the first vector
     393             :     /// with the result.
     394             :     static void cross_inplace(Vector &a, Vector &&b);
     395             :     /// Compute the opposite of the cross product of two 3-vectors, overwriting
     396             :     /// the first vector with the result.
     397             :     static void cross_inplace_neg(Vector &a, const Vector &b);
     398             :     /// Compute the opposite of the cross product of two 3-vectors, overwriting
     399             :     /// the first vector with the result.
     400             :     static void cross_inplace_neg(Vector &a, Vector &&b);
     401             : 
     402             :     /// Compute the cross product of two 3-vectors.
     403             :     static Vector cross(const Vector &a, const Vector &b);
     404             :     /// Compute the cross product of two 3-vectors.
     405             :     static Vector &&cross(Vector &&a, const Vector &b);
     406             :     /// Compute the cross product of two 3-vectors.
     407             :     static Vector &&cross(const Vector &a, Vector &&b);
     408             :     /// Compute the cross product of two 3-vectors.
     409             :     static Vector &&cross(Vector &&a, Vector &&b);
     410             : 
     411             :     /// Compute the cross product of this 3-vector with another 3-vector.
     412           1 :     Vector cross(const Vector &b) const & { return cross(*this, b); }
     413             :     /// Compute the cross product of this 3-vector with another 3-vector,
     414           1 :     Vector &&cross(const Vector &b) && { return cross(std::move(*this), b); }
     415             :     /// Compute the cross product of this 3-vector with another 3-vector,
     416           1 :     Vector &&cross(Vector &&b) const & { return cross(*this, std::move(b)); }
     417             :     /// Compute the cross product of this 3-vector with another 3-vector,
     418           1 :     Vector &&cross(Vector &&b) && {
     419           1 :         return cross(std::move(*this), std::move(b));
     420             :     }
     421             : 
     422             :     /// @}
     423             : 
     424             :   public:
     425             :     /// @name   Vector norms
     426             :     /// @{
     427             : 
     428             :     /// Compute the 2-norm of the vector.
     429             :     double norm2() const &;
     430             :     /// Compute the 2-norm of the vector.
     431             :     double norm2() &&;
     432             : 
     433             :     /// @}
     434             : };
     435             : 
     436             : /// A row vector (1×n matrix).
     437             : class RowVector : public Matrix {
     438             :   public:
     439             :     /// @name   Constructors and assignment
     440             :     /// @{
     441             : 
     442             :     /// Default constructor.
     443             :     RowVector() = default;
     444             : 
     445             :     /// Create a row vector of the given size.
     446             :     RowVector(size_t size) : Matrix(1, size) {}
     447             : 
     448             :     /// Create a row vector from the given list of values.
     449         120 :     RowVector(std::initializer_list<double> init) { *this = init; }
     450             : 
     451             :     /// Assign a list of values to the column vector.
     452             :     RowVector &operator=(std::initializer_list<double> init);
     453             : 
     454             :     /// Convert an m×n matrix to a mn row vector.
     455             :     explicit RowVector(const Matrix &matrix);
     456             :     /// Convert an m×n matrix to a mn row vector.
     457             :     explicit RowVector(Matrix &&matrix);
     458             : 
     459             :     /// @}
     460             : 
     461             :   public:
     462             :     /// @name   Vector size
     463             :     /// @{
     464             : 
     465             :     /// Resize the vector.
     466             :     void resize(size_t size) { storage.resize(size); }
     467             : 
     468             :     /// Get the number of elements in the vector.
     469             :     size_t size() const { return num_elems(); }
     470             : 
     471             :     /// Reshaping a vector to a matrix requires an explicit cast.
     472             :     void reshape(size_t, size_t) = delete;
     473             :     /// Reshaping a vector to a matrix requires an explicit cast.
     474             :     Matrix reshaped(size_t, size_t) = delete;
     475             : 
     476             :     /// @}
     477             : 
     478             :   public:
     479             :     /// @name   Creating special row vectors
     480             :     /// @{
     481             : 
     482             :     /// Create a row vector filled with ones.
     483             :     static RowVector ones(size_t size);
     484             :     /// Create a row vector filled with zeros.
     485             :     static RowVector zeros(size_t size);
     486             :     /// Create a row vector filled with a constant value.
     487             :     static RowVector constant(size_t size, double value);
     488             : 
     489             : #ifndef NO_RANDOM_SUPPORT
     490             :     /// Create a row vector with uniformly distributed random values.
     491             :     static RowVector random(size_t size, double min = 0, double max = 1,
     492             :                             std::default_random_engine::result_type seed =
     493             :                                 std::default_random_engine::default_seed);
     494             : #endif
     495             : 
     496             :     /// @}
     497             : 
     498             :   public:
     499             :     /// @name   Dot products
     500             :     /// @{
     501             : 
     502             :     /// Compute the dot product of two vectors.
     503             :     static double dot(const RowVector &a, const RowVector &b);
     504             :     /// Compute the dot product of two vectors.
     505             :     static double dot(RowVector &&a, const RowVector &b);
     506             :     /// Compute the dot product of two vectors.
     507             :     static double dot(const RowVector &a, RowVector &&b);
     508             :     /// Compute the dot product of two vectors.
     509             :     static double dot(RowVector &&a, RowVector &&b);
     510             : 
     511             :     /// Compute the dot product of this vector with another vector.
     512           2 :     double dot(const RowVector &b) const & { return dot(*this, b); }
     513             :     /// Compute the dot product of this vector with another vector.
     514           1 :     double dot(const RowVector &b) && { return dot(std::move(*this), b); }
     515             :     /// Compute the dot product of this vector with another vector.
     516           2 :     double dot(RowVector &&b) const & { return dot(*this, std::move(b)); }
     517             :     /// Compute the dot product of this vector with another vector.
     518           1 :     double dot(RowVector &&b) && { return dot(std::move(*this), std::move(b)); }
     519             : 
     520             :     /// @}
     521             : 
     522             :   public:
     523             :     /// @name Cross products
     524             :     /// @{
     525             : 
     526             :     /// Compute the cross product of two 3-vectors, overwriting the first vector
     527             :     /// with the result.
     528             :     static void cross_inplace(RowVector &a, const RowVector &b);
     529             :     /// Compute the cross product of two 3-vectors, overwriting the first vector
     530             :     /// with the result.
     531             :     static void cross_inplace(RowVector &a, RowVector &&b);
     532             :     /// Compute the opposite of the cross product of two 3-vectors, overwriting
     533             :     /// the first vector with the result.
     534             :     static void cross_inplace_neg(RowVector &a, const RowVector &b);
     535             :     /// Compute the opposite of the cross product of two 3-vectors, overwriting
     536             :     /// the first vector with the result.
     537             :     static void cross_inplace_neg(RowVector &a, RowVector &&b);
     538             : 
     539             :     /// Compute the cross product of two 3-vectors.
     540             :     static RowVector cross(const RowVector &a, const RowVector &b);
     541             :     /// Compute the cross product of two 3-vectors.
     542             :     static RowVector &&cross(RowVector &&a, const RowVector &b);
     543             :     /// Compute the cross product of two 3-vectors.
     544             :     static RowVector &&cross(const RowVector &a, RowVector &&b);
     545             :     /// Compute the cross product of two 3-vectors.
     546             :     static RowVector &&cross(RowVector &&a, RowVector &&b);
     547             : 
     548             :     /// Compute the cross product of this 3-vector with another 3-vector.
     549             :     RowVector cross(const RowVector &b) const &;
     550             :     /// Compute the cross product of this 3-vector with another 3-vector,
     551             :     RowVector &&cross(const RowVector &b) &&;
     552             :     /// Compute the cross product of this 3-vector with another 3-vector,
     553             :     RowVector &&cross(RowVector &&b) const &;
     554             :     /// Compute the cross product of this 3-vector with another 3-vector,
     555             :     RowVector &&cross(RowVector &&b) &&;
     556             : 
     557             :     /// @}
     558             : 
     559             :   public:
     560             :     /// @name   Vector norms
     561             :     /// @{
     562             : 
     563             :     /// Compute the 2-norm of the vector.
     564             :     double norm2() const &;
     565             :     /// Compute the 2-norm of the vector.
     566             :     double norm2() &&;
     567             : 
     568             :     /// @}
     569             : };
     570             : 
     571             : /// Square matrix class.
     572             : class SquareMatrix : public Matrix {
     573             :   public:
     574             :     /// @name   Constructors and assignment
     575             :     /// @{
     576             : 
     577             :     /// Default constructor.
     578          26 :     SquareMatrix() = default;
     579             : 
     580             :     /// Create a square matrix of zeros.
     581          13 :     SquareMatrix(size_t size) : Matrix(size, size) {}
     582             : 
     583             :     /// Create a square matrix with the given values.
     584             :     SquareMatrix(std::initializer_list<std::initializer_list<double>> init);
     585             : 
     586             :     /// Convert a general matrix to a square matrix
     587             :     explicit SquareMatrix(Matrix &&matrix);
     588             :     /// Convert a general matrix to a square matrix
     589             :     explicit SquareMatrix(const Matrix &matrix);
     590             : 
     591             :     /// Assign the given values to the square matrix.
     592             :     SquareMatrix &
     593             :     operator=(std::initializer_list<std::initializer_list<double>> init);
     594             : 
     595             :     /// @}
     596             : 
     597             :   public:
     598             :     /// @name   Matrix size
     599             :     /// @{
     600             : 
     601             :     /// Reshaping a square matrix to a general matrix requires an explicit cast.
     602             :     void reshape(size_t, size_t) = delete;
     603             :     /// Reshaping a square matrix to a general matrix requires an explicit cast.
     604             :     Matrix reshaped(size_t, size_t) = delete;
     605             : 
     606             :     /// @}
     607             : 
     608             :   public:
     609             :     /// @name   Transposition
     610             :     /// @{
     611             : 
     612             :     /// Transpose the matrix in-place.
     613             :     static void transpose_inplace(Matrix &A);
     614             :     /// Transpose the matrix in-place.
     615           2 :     void transpose_inplace() { transpose_inplace(*this); }
     616             : 
     617             :     /// @}
     618             : 
     619             :   public:
     620             :     /// @name   Creating special matrices
     621             :     /// @{
     622             : 
     623             :     /// Create a square matrix filled with ones.
     624             :     static SquareMatrix ones(size_t rows);
     625             :     /// Create a square matrix filled with zeros.
     626             :     static SquareMatrix zeros(size_t rows);
     627             :     /// Create a square matrix filled with a constant value.
     628             :     static SquareMatrix constant(size_t rows, double value);
     629             : 
     630             :     /// Create a square identity matrix.
     631             :     static SquareMatrix identity(size_t rows);
     632             : 
     633             : #ifndef NO_RANDOM_SUPPORT
     634             :     /// Create a matrix with uniformly distributed random values.
     635             :     static SquareMatrix random(size_t rows, double min = 0, double max = 1,
     636             :                                std::default_random_engine::result_type seed =
     637             :                                    std::default_random_engine::default_seed);
     638             : #endif
     639             : 
     640             :     /// @}
     641             : };
     642             : 
     643             : /// @}
     644             : 
     645             : #ifndef NO_IOSTREAM_SUPPORT
     646             : /// Print a matrix.
     647             : /// @related    Matrix
     648             : std::ostream &operator<<(std::ostream &os, const Matrix &M);
     649             : #endif
     650             : 
     651             : #ifndef NO_ARDUINO_PRINT_SUPPORT
     652             : /// Print a matrix.
     653             : /// @related    Matrix
     654             : Print &operator<<(Print &p, const Matrix &M);
     655             : #endif
     656             : 
     657             : // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
     658             : 
     659             : /// @addtogroup MatVecOp
     660             : /// @{
     661             : 
     662             : /// @defgroup MatMul    Matrix multiplication
     663             : /// @brief   Matrix-matrix, matrix-vector and vector-vector multiplication.
     664             : /// @{
     665             : 
     666             : /// Matrix multiplication.
     667             : Matrix operator*(const Matrix &A, const Matrix &B);
     668             : /// Matrix multiplication.
     669             : Matrix operator*(Matrix &&A, const Matrix &B);
     670             : /// Matrix multiplication.
     671             : Matrix operator*(const Matrix &A, Matrix &&B);
     672             : /// Matrix multiplication.
     673             : Matrix operator*(Matrix &&A, Matrix &&B);
     674             : 
     675             : /// Square matrix multiplication.
     676             : SquareMatrix operator*(const SquareMatrix &A, const SquareMatrix &B);
     677             : /// Square matrix multiplication.
     678             : SquareMatrix operator*(SquareMatrix &&A, const SquareMatrix &B);
     679             : /// Square matrix multiplication.
     680             : SquareMatrix operator*(const SquareMatrix &A, SquareMatrix &&B);
     681             : /// Square matrix multiplication.
     682             : SquareMatrix operator*(SquareMatrix &&A, SquareMatrix &&B);
     683             : 
     684             : /// Matrix-vector multiplication.
     685             : Vector operator*(const Matrix &A, const Vector &b);
     686             : /// Matrix-vector multiplication.
     687             : Vector operator*(Matrix &&A, const Vector &b);
     688             : /// Matrix-vector multiplication.
     689             : Vector operator*(const Matrix &A, Vector &&b);
     690             : /// Matrix-vector multiplication.
     691             : Vector operator*(Matrix &&A, Vector &&b);
     692             : 
     693             : /// Matrix-vector multiplication.
     694             : RowVector operator*(const RowVector &a, const Matrix &B);
     695             : /// Matrix-vector multiplication.
     696             : RowVector operator*(RowVector &&a, const Matrix &B);
     697             : /// Matrix-vector multiplication.
     698             : RowVector operator*(const RowVector &a, Matrix &&B);
     699             : /// Matrix-vector multiplication.
     700             : RowVector operator*(RowVector &&a, Matrix &&B);
     701             : 
     702             : /// Vector-vector multiplication.
     703             : double operator*(const RowVector &a, const Vector &b);
     704             : /// Vector-vector multiplication.
     705             : double operator*(RowVector &&a, const Vector &b);
     706             : /// Vector-vector multiplication.
     707             : double operator*(const RowVector &a, Vector &&b);
     708             : /// Vector-vector multiplication.
     709             : double operator*(RowVector &&a, Vector &&b);
     710             : 
     711             : /// @}
     712             : 
     713             : // -------------------------------------------------------------------------- //
     714             : 
     715             : /// @defgroup   MatAdd  Addition
     716             : /// @brief  Matrix and vector addition
     717             : /// @{
     718             : 
     719             : /// Matrix addition.
     720             : Matrix operator+(const Matrix &A, const Matrix &B);
     721             : 
     722             : void operator+=(Matrix &A, const Matrix &B);
     723             : Matrix &&operator+(Matrix &&A, const Matrix &B);
     724             : Matrix &&operator+(const Matrix &A, Matrix &&B);
     725             : Matrix &&operator+(Matrix &&A, Matrix &&B);
     726             : Vector &&operator+(Vector &&a, const Vector &b);
     727             : Vector &&operator+(const Vector &a, Vector &&b);
     728             : Vector &&operator+(Vector &&a, Vector &&b);
     729             : RowVector &&operator+(RowVector &&a, const RowVector &b);
     730             : RowVector &&operator+(const RowVector &a, RowVector &&b);
     731             : RowVector &&operator+(RowVector &&a, RowVector &&b);
     732             : SquareMatrix &&operator+(SquareMatrix &&a, const SquareMatrix &b);
     733             : SquareMatrix &&operator+(const SquareMatrix &a, SquareMatrix &&b);
     734             : SquareMatrix &&operator+(SquareMatrix &&a, SquareMatrix &&b);
     735             : Vector operator+(const Vector &a, const Vector &b);
     736             : RowVector operator+(const RowVector &a, const RowVector &b);
     737             : SquareMatrix operator+(const SquareMatrix &a, const SquareMatrix &b);
     738             : 
     739             : /// @}
     740             : 
     741             : // -------------------------------------------------------------------------- //
     742             : 
     743             : /// @defgroup   MatSub  Subtraction
     744             : /// @brief  Matrix and vector subtraction
     745             : /// @{
     746             : 
     747             : /// Matrix subtraction.
     748             : Matrix operator-(const Matrix &A, const Matrix &B);
     749             : void operator-=(Matrix &A, const Matrix &B);
     750             : Matrix &&operator-(Matrix &&A, const Matrix &B);
     751             : Matrix &&operator-(const Matrix &A, Matrix &&B);
     752             : Matrix &&operator-(Matrix &&A, Matrix &&B);
     753             : Vector &&operator-(Vector &&a, const Vector &b);
     754             : Vector &&operator-(const Vector &a, Vector &&b);
     755             : Vector &&operator-(Vector &&a, Vector &&b);
     756             : RowVector &&operator-(RowVector &&a, const RowVector &b);
     757             : RowVector &&operator-(const RowVector &a, RowVector &&b);
     758             : RowVector &&operator-(RowVector &&a, RowVector &&b);
     759             : SquareMatrix &&operator-(SquareMatrix &&a, const SquareMatrix &b);
     760             : SquareMatrix &&operator-(const SquareMatrix &a, SquareMatrix &&b);
     761             : SquareMatrix &&operator-(SquareMatrix &&a, SquareMatrix &&b);
     762             : Vector operator-(const Vector &a, const Vector &b);
     763             : RowVector operator-(const RowVector &a, const RowVector &b);
     764             : SquareMatrix operator-(const SquareMatrix &a, const SquareMatrix &b);
     765             : 
     766             : /// @}
     767             : 
     768             : // -------------------------------------------------------------------------- //
     769             : 
     770             : /// @defgroup   MatNeg  Negation
     771             : /// @brief  Matrix and vector negation
     772             : /// @{
     773             : 
     774             : /// Matrix negation.
     775             : Matrix operator-(const Matrix &A);
     776             : Matrix &&operator-(Matrix &&A);
     777             : Vector &&operator-(Vector &&a);
     778             : RowVector &&operator-(RowVector &&a);
     779             : SquareMatrix &&operator-(SquareMatrix &&a);
     780             : Vector operator-(const Vector &a);
     781             : RowVector operator-(const RowVector &a);
     782             : SquareMatrix operator-(const SquareMatrix &a);
     783             : 
     784             : /// @}
     785             : 
     786             : // -------------------------------------------------------------------------- //
     787             : 
     788             : /// @defgroup   ScalMul Scalar multiplication
     789             : /// @brief  Multiplication by a scalar
     790             : /// @{
     791             : 
     792             : /// Scalar multiplication.
     793             : Matrix operator*(const Matrix &A, double s);
     794             : void operator*=(Matrix &A, double s);
     795             : Matrix &&operator*(Matrix &&A, double s);
     796             : Vector operator*(const Vector &a, double s);
     797             : RowVector operator*(const RowVector &a, double s);
     798             : SquareMatrix operator*(const SquareMatrix &a, double s);
     799             : Vector &&operator*(Vector &&a, double s);
     800             : RowVector &&operator*(RowVector &&a, double s);
     801             : SquareMatrix &&operator*(SquareMatrix &&a, double s);
     802             : 
     803             : Matrix operator*(double s, const Matrix &A);
     804             : Matrix &&operator*(double s, Matrix &&A);
     805             : Vector operator*(double s, const Vector &a);
     806             : RowVector operator*(double s, const RowVector &a);
     807             : SquareMatrix operator*(double s, const SquareMatrix &a);
     808             : Vector &&operator*(double s, Vector &&a);
     809             : RowVector &&operator*(double s, RowVector &&a);
     810             : SquareMatrix &&operator*(double s, SquareMatrix &&a);
     811             : 
     812             : /// @}
     813             : 
     814             : // -------------------------------------------------------------------------- //
     815             : 
     816             : /// @defgroup   ScalDiv Scalar division
     817             : /// @brief  Division by a scalar
     818             : /// @{
     819             : 
     820             : /// Scalar division.
     821             : Matrix operator/(const Matrix &A, double s);
     822             : void operator/=(Matrix &A, double s);
     823             : Matrix &&operator/(Matrix &&A, double s);
     824             : Vector operator/(const Vector &a, double s);
     825             : RowVector operator/(const RowVector &a, double s);
     826             : SquareMatrix operator/(const SquareMatrix &a, double s);
     827             : Vector &&operator/(Vector &&a, double s);
     828             : RowVector &&operator/(RowVector &&a, double s);
     829             : SquareMatrix &&operator/(SquareMatrix &&a, double s);
     830             : 
     831             : /// @}
     832             : 
     833             : /// @}
     834             : 
     835             : // -------------------------------------------------------------------------- //
     836             : 
     837             : /// @addtogroup MatVecOp
     838             : /// @{
     839             : 
     840             : /// @defgroup   MatTrans    Transposition
     841             : /// @brief  Matrix and vector transposition
     842             : /// @{
     843             : 
     844             : /// Matrix transpose for general matrices.
     845             : Matrix explicit_transpose(const Matrix &in);
     846             : 
     847             : /// Matrix transpose for rectangular or square matrices and row or column
     848             : /// vectors.
     849             : Matrix transpose(const Matrix &in);
     850             : /// Matrix transpose for rectangular or square matrices and row or column
     851             : /// vectors.
     852             : Matrix &&transpose(Matrix &&in);
     853             : 
     854             : /// Square matrix transpose.
     855             : SquareMatrix transpose(const SquareMatrix &in);
     856             : /// Square matrix transpose.
     857             : SquareMatrix &&transpose(SquareMatrix &&in);
     858             : 
     859             : /// Vector transpose.
     860             : RowVector transpose(const Vector &in);
     861             : /// Vector transpose.
     862             : RowVector transpose(Vector &&in);
     863             : /// Vector transpose.
     864             : Vector transpose(const RowVector &in);
     865             : /// Vector transpose.
     866             : Vector transpose(RowVector &&in);
     867             : 
     868             : /// @}
     869             : 
     870             : /// @}

Generated by: LCOV version 1.15