8 storage(std::move(storage)) {}
18 storage(rows * cols) {}
33 this->
storage = std::move(other.storage);
34 this->
rows_ = other.rows_;
35 this->
cols_ = other.cols_;
36 other.clear_and_deallocate();
43 this->
rows_ = init.size();
45 this->
cols_ = init.begin()->size();
49 [[maybe_unused]]
auto same_number_of_columns =
50 [&](
const std::initializer_list<double> &row) {
51 return row.size() ==
cols();
53 assert(std::all_of(init.begin(), init.end(), same_number_of_columns));
58 for (
const auto &row : init) {
60 for (
double el : row) {
75 assert(newrows * newcols ==
rows() *
cols());
76 this->
rows_ = newrows;
77 this->
cols_ = newcols;
82 result.
reshape(newrows, newcols);
91 #if COL_MAJ_ORDER == 1
99 #if COL_MAJ_ORDER == 1
127 for (
size_t i = 0; i < std::min(
rows(),
cols()); ++i)
132 std::default_random_engine::result_type seed) {
133 std::default_random_engine gen(seed);
134 std::uniform_real_distribution<double> dist(min, max);
135 std::generate(
storage.begin(),
storage.end(), [&] { return dist(gen); });
166 std::default_random_engine::result_type seed) {
177 for (
size_t r = 0; r <
rows(); ++r)
178 std::swap((*
this)(r, a), (*
this)(r, b));
182 for (
size_t c = 0; c <
cols(); ++c)
183 std::swap((*
this)(a, c), (*
this)(b, c));
193 assert(this->
rows() == other.
rows());
194 assert(this->
cols() == other.
cols());
199 return res.first ==
end();
232 void Matrix::print(std::ostream &os, uint8_t precision, uint8_t width)
const {
233 int backup_precision = os.precision();
234 precision = precision > 0 ? precision : backup_precision;
235 width = width > 0 ? width : precision + 9;
236 os.precision(precision);
237 for (
size_t r = 0; r <
rows(); ++r) {
238 for (
size_t c = 0; c <
cols(); ++c)
239 os << std::setw(width) << (*this)(r, c);
242 os.precision(backup_precision);
258 :
Matrix(matrix.storage, matrix.num_elems(), 1) {}
261 :
Matrix(std::move(matrix.storage), matrix.num_elems(), 1) {}
265 static_cast<Matrix &
>(*this) = {init};
284 std::default_random_engine::result_type seed) {
294 return std::inner_product(a.
begin(), a.
end(), b.
begin(),
double(0));
299 a.clear_and_deallocate();
309 static_cast<const Matrix &
>(b));
310 a.clear_and_deallocate();
311 b.clear_and_deallocate();
338 double a0 = a(1) * b(2) - a(2) * b(1);
339 double a1 = a(2) * b(0) - a(0) * b(2);
340 double a2 = a(0) * b(1) - a(1) * b(0);
349 double a0 = a(2) * b(1) - a(1) * b(2);
350 double a1 = a(0) * b(2) - a(2) * b(0);
351 double a2 = a(1) * b(0) - a(0) * b(1);
363 b.clear_and_deallocate();
371 b.clear_and_deallocate();
404 return std::sqrt(
dot(*
this));
409 return std::sqrt(dot(std::move(*
this)));
420 :
Matrix(matrix.storage, 1, matrix.num_elems()) {}
423 :
Matrix(std::move(matrix.storage), 1, matrix.num_elems()) {}
426 static_cast<Matrix &
>(*this) = {init};
447 std::default_random_engine::result_type seed) {
480 b.clear_and_deallocate();
487 b.clear_and_deallocate();
509 return cross(*
this, b);
512 return cross(std::move(*
this), b);
515 return cross(*
this, std::move(b));
518 return cross(std::move(*
this), std::move(b));
537 std::initializer_list<std::initializer_list<double>> init) {
550 std::initializer_list<std::initializer_list<double>> init) {
551 static_cast<Matrix &
>(*this) = init;
561 assert(A.
cols() == A.
rows() &&
"Matrix should be square.");
562 for (
size_t n = 0; n < A.
rows() - 1; ++n)
563 for (
size_t m = n + 1; m < A.
rows(); ++m)
564 std::swap(A(n, m), A(m, n));
587 std::default_random_engine::result_type seed) {
604 assert(A.
cols() == B.
rows() &&
"Inner dimensions don't match");
606 for (
size_t j = 0; j < B.
cols(); ++j)
607 for (
size_t k = 0; k < A.
cols(); ++k)
608 for (
size_t i = 0; i < A.
rows(); ++i)
609 C(i, j) += A(i, k) * B(k, j);
616 static_cast<const Matrix &
>(B);
623 static_cast<const Matrix &
>(B);
630 static_cast<const Matrix &
>(B);
632 B.clear_and_deallocate();
638 static_cast<const Matrix &
>(B));
642 static_cast<const Matrix &
>(B));
646 static_cast<Matrix &&
>(B));
650 static_cast<Matrix &&
>(B));
657 return Vector(std::move(A) *
static_cast<const Matrix &
>(b));
663 return Vector(std::move(A) *
static_cast<Matrix &&
>(b));
706 std::plus<double>());
715 std::plus<double>());
731 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
735 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
739 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
744 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
748 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
752 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
757 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
761 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
765 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
771 static_cast<const Matrix &
>(b));
775 static_cast<const Matrix &
>(b));
779 static_cast<const Matrix &
>(b));
796 std::minus<double>());
805 std::minus<double>());
812 std::transform(A.
begin(), A.
end(), B.begin(), B.begin(),
813 std::minus<double>());
822 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
826 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
830 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
835 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
839 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
843 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
848 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
852 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
856 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
862 static_cast<const Matrix &
>(b));
866 static_cast<const Matrix &
>(b));
870 static_cast<const Matrix &
>(b));
886 std::transform(A.
begin(), A.
end(), result.
begin(), std::negate<double>());
892 std::transform(A.begin(), A.end(), A.begin(), std::negate<double>());
896 -
static_cast<Matrix &&
>(a);
900 -
static_cast<Matrix &&
>(a);
904 -
static_cast<Matrix &&
>(a);
929 [s](
double a) { return a * s; });
936 [s](
double a) { return a * s; });
952 static_cast<Matrix &
>(a) *= s;
956 static_cast<Matrix &
>(a) *= s;
960 static_cast<Matrix &
>(a) *= s;
972 return std::move(a) * s;
987 [s](
double a) { return a / s; });
994 [s](
double a) { return a / s; });
1010 static_cast<Matrix &
>(a) /= s;
1011 return std::move(a);
1014 static_cast<Matrix &
>(a) /= s;
1015 return std::move(a);
1018 static_cast<Matrix &
>(a) /= s;
1019 return std::move(a);
1033 for (
size_t n = 0; n < in.
rows(); ++n)
1034 for (
size_t m = 0; m < in.
cols(); ++m)
1035 out(m, n) = in(n, m);
1046 if (in.
rows() == 1 || in.
cols() == 1) {
1062 if (in.rows() == in.cols())
1064 else if (in.rows() == 1 || in.cols() == 1)
1065 in.reshape(in.cols(), in.rows());
1068 return std::move(in);
1078 in.transpose_inplace();
1079 return std::move(in);
std::ostream & operator<<(std::ostream &os, const HouseholderQR &qr)
Print the Q and R matrices of a HouseholderQR object.
static Matrix constant(size_t rows, size_t cols, double value)
Create a matrix filled with a constant value.
static Matrix identity(size_t rows, size_t cols)
Create an identity matrix.
static Matrix random(size_t rows, size_t cols, double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Create a matrix with uniformly distributed random values.
storage_t::iterator end()
Get the iterator to the element past the end of the matrix.
static Matrix zeros(size_t rows, size_t cols)
Create a matrix filled with zeros.
void fill_random(double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Fill the matrix with uniformly distributed random values.
void swap_columns(size_t a, size_t b)
Swap two columns of the matrix.
Matrix reshaped(size_t newrows, size_t newcols) const
Create a reshaped copy of the matrix.
bool operator==(const Matrix &other) const
Check for equality of two matrices.
double & operator()(size_t row, size_t col)
Get the element at the given position in the matrix.
size_t num_elems() const
Get the number of elements in the matrix:
static Matrix ones(size_t rows, size_t cols)
Create a matrix filled with ones.
void swap_rows(size_t a, size_t b)
Swap two rows of the matrix.
Matrix()=default
Default constructor.
size_t rows() const
Get the number of rows of the matrix.
util::storage_t< double > storage_t
Container to store the elements of the matrix internally.
void clear_and_deallocate()
Set the number of rows and columns to zero, and deallocate the storage.
void reshape(size_t newrows, size_t newcols)
Reshape the matrix.
Matrix & operator=(std::initializer_list< std::initializer_list< double >> init)
Assign the given values to the matrix.
void fill_identity()
Fill the matrix as an identity matrix (all zeros except the diagonal which is one).
double normFro() const &
Compute the Frobenius norm of the matrix.
size_t cols() const
Get the number of columns of the matrix.
storage_t::iterator begin()
Get the iterator to the first element of the matrix.
void fill(double value)
Fill the matrix with a constant value.
void print(std::ostream &os, uint8_t precision=0, uint8_t width=0) const
Print a matrix.
A row vector (1×n matrix).
static RowVector ones(size_t size)
Create a row vector filled with ones.
size_t size() const
Get the number of elements in the vector.
static void cross_inplace_neg(RowVector &a, const RowVector &b)
Compute the opposite of the cross product of two 3-vectors, overwriting the first vector with the res...
static RowVector constant(size_t size, double value)
Create a row vector filled with a constant value.
static void cross_inplace(RowVector &a, const RowVector &b)
Compute the cross product of two 3-vectors, overwriting the first vector with the result.
static RowVector zeros(size_t size)
Create a row vector filled with zeros.
RowVector & operator=(std::initializer_list< double > init)
Assign a list of values to the column vector.
static RowVector random(size_t size, double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Create a row vector with uniformly distributed random values.
double norm2() const &
Compute the 2-norm of the vector.
static RowVector cross(const RowVector &a, const RowVector &b)
Compute the cross product of two 3-vectors.
RowVector()=default
Default constructor.
static double dot(const RowVector &a, const RowVector &b)
Compute the dot product of two vectors.
static SquareMatrix constant(size_t rows, double value)
Create a square matrix filled with a constant value.
SquareMatrix & operator=(std::initializer_list< std::initializer_list< double >> init)
Assign the given values to the square matrix.
static SquareMatrix random(size_t rows, double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Create a matrix with uniformly distributed random values.
SquareMatrix()=default
Default constructor.
void transpose_inplace()
Transpose the matrix in-place.
static SquareMatrix zeros(size_t rows)
Create a square matrix filled with zeros.
static void transpose_inplace(Matrix &A)
Transpose the matrix in-place.
static SquareMatrix ones(size_t rows)
Create a square matrix filled with ones.
static SquareMatrix identity(size_t rows)
Create a square identity matrix.
A column vector (n×1 matrix).
static void cross_inplace_unchecked(Matrix &a, const Matrix &b)
Compute the cross product of two 3-vectors, overwriting the first vector with the result.
static void cross_inplace(Vector &a, const Vector &b)
Compute the cross product of two 3-vectors, overwriting the first vector with the result.
size_t size() const
Get the number of elements in the vector.
static void cross_inplace_unchecked_neg(Matrix &a, const Matrix &b)
Compute the opposite of the cross product of two 3-vectors, overwriting the first vector with the res...
static Vector random(size_t size, double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Create a vector with uniformly distributed random values.
static Vector constant(size_t size, double value)
Create a vector filled with a constant value.
static Vector zeros(size_t size)
Create a vector filled with zeros.
static double dot(const Vector &a, const Vector &b)
Compute the dot product of two vectors.
static Vector cross(const Vector &a, const Vector &b)
Compute the cross product of two 3-vectors.
Vector()=default
Default constructor.
double norm2() const &
Compute the 2-norm of the vector.
static double dot_unchecked(const Matrix &a, const Matrix &b)
Compute the dot product of two vectors.
static void cross_inplace_neg(Vector &a, const Vector &b)
Compute the opposite of the cross product of two 3-vectors, overwriting the first vector with the res...
static Vector ones(size_t size)
Create a vector filled with ones.
Vector & operator=(std::initializer_list< double > init)
Assign a list of values to the column vector.
Matrix operator+(const Matrix &A, const Matrix &B)
Matrix addition.
void operator+=(Matrix &A, const Matrix &B)
Matrix operator*(const Matrix &A, const Matrix &B)
Matrix multiplication.
void operator-=(Matrix &A, const Matrix &B)
Matrix operator-(const Matrix &A, const Matrix &B)
Matrix subtraction.
Matrix transpose(const Matrix &in)
Matrix transpose for rectangular or square matrices and row or column vectors.
Matrix explicit_transpose(const Matrix &in)
Matrix transpose for general matrices.
void operator/=(Matrix &A, double s)
Matrix operator/(const Matrix &A, double s)
Scalar division.
void operator*=(Matrix &A, double s)