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

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

Generated by: LCOV version 1.15