12 storage(std::move(storage)) {}
22 storage(rows * cols) {}
37 this->
storage = std::move(other.storage);
38 this->
rows_ = other.rows_;
39 this->
cols_ = other.cols_;
40 other.clear_and_deallocate();
47 this->
rows_ = init.size();
49 this->
cols_ = init.begin()->size();
53 [[maybe_unused]]
auto same_number_of_columns =
54 [&](
const std::initializer_list<double> &row) {
55 return row.size() ==
cols();
57 assert(std::all_of(init.begin(), init.end(), same_number_of_columns));
62 for (
const auto &row : init) {
64 for (
double el : row) {
79 assert(newrows * newcols ==
rows() *
cols());
80 this->
rows_ = newrows;
81 this->
cols_ = newcols;
86 result.
reshape(newrows, newcols);
95 #if COL_MAJ_ORDER == 1
103 #if COL_MAJ_ORDER == 1
131 for (
size_t i = 0; i < std::min(
rows(),
cols()); ++i)
135 #ifndef NO_RANDOM_SUPPORT
137 std::default_random_engine::result_type seed) {
138 std::default_random_engine gen(seed);
139 std::uniform_real_distribution<double> dist(min, max);
140 std::generate(
storage.begin(),
storage.end(), [&] { return dist(gen); });
171 #ifndef NO_RANDOM_SUPPORT
173 std::default_random_engine::result_type seed) {
185 for (
size_t r = 0; r <
rows(); ++r)
186 std::swap((*
this)(r, a), (*
this)(r, b));
190 for (
size_t c = 0; c <
cols(); ++c)
191 std::swap((*
this)(a, c), (*
this)(b, c));
201 assert(this->
rows() == other.
rows());
202 assert(this->
cols() == other.
cols());
207 return res.first ==
end();
237 #ifndef NO_IOSTREAM_SUPPORT
242 void Matrix::print(std::ostream &os, uint8_t precision, uint8_t width)
const {
243 int backup_precision = os.precision();
244 precision = precision > 0 ? precision : backup_precision;
245 width = width > 0 ? width : precision + 9;
246 os.precision(precision);
247 for (
size_t r = 0; r <
rows(); ++r) {
248 for (
size_t c = 0; c <
cols(); ++c)
249 os << std::setw(width) << (*this)(r, c);
252 os.precision(backup_precision);
270 :
Matrix(matrix.storage, matrix.num_elems(), 1) {}
273 :
Matrix(std::move(matrix.storage), matrix.num_elems(), 1) {}
277 static_cast<Matrix &
>(*this) = {init};
295 #ifndef NO_RANDOM_SUPPORT
297 std::default_random_engine::result_type seed) {
308 return std::inner_product(a.
begin(), a.
end(), b.
begin(),
double(0));
313 a.clear_and_deallocate();
323 static_cast<const Matrix &
>(b));
324 a.clear_and_deallocate();
325 b.clear_and_deallocate();
352 double a0 = a(1) * b(2) - a(2) * b(1);
353 double a1 = a(2) * b(0) - a(0) * b(2);
354 double a2 = a(0) * b(1) - a(1) * b(0);
363 double a0 = a(2) * b(1) - a(1) * b(2);
364 double a1 = a(0) * b(2) - a(2) * b(0);
365 double a2 = a(1) * b(0) - a(0) * b(1);
377 b.clear_and_deallocate();
385 b.clear_and_deallocate();
418 return std::sqrt(
dot(*
this));
423 return std::sqrt(dot(std::move(*
this)));
434 :
Matrix(matrix.storage, 1, matrix.num_elems()) {}
437 :
Matrix(std::move(matrix.storage), 1, matrix.num_elems()) {}
440 static_cast<Matrix &
>(*this) = {init};
460 #ifndef NO_RANDOM_SUPPORT
462 std::default_random_engine::result_type seed) {
496 b.clear_and_deallocate();
503 b.clear_and_deallocate();
525 return cross(*
this, b);
528 return cross(std::move(*
this), b);
531 return cross(*
this, std::move(b));
534 return cross(std::move(*
this), std::move(b));
553 std::initializer_list<std::initializer_list<double>> init) {
566 std::initializer_list<std::initializer_list<double>> init) {
567 static_cast<Matrix &
>(*this) = init;
577 assert(A.
cols() == A.
rows() &&
"Matrix should be square.");
578 for (
size_t n = 0; n < A.
rows() - 1; ++n)
579 for (
size_t m = n + 1; m < A.
rows(); ++m)
580 std::swap(A(n, m), A(m, n));
602 #ifndef NO_RANDOM_SUPPORT
605 std::default_random_engine::result_type seed) {
623 assert(A.
cols() == B.
rows() &&
"Inner dimensions don't match");
625 for (
size_t j = 0; j < B.
cols(); ++j)
626 for (
size_t k = 0; k < A.
cols(); ++k)
627 for (
size_t i = 0; i < A.
rows(); ++i)
628 C(i, j) += A(i, k) * B(k, j);
635 static_cast<const Matrix &
>(B);
642 static_cast<const Matrix &
>(B);
649 static_cast<const Matrix &
>(B);
651 B.clear_and_deallocate();
657 static_cast<const Matrix &
>(B));
661 static_cast<const Matrix &
>(B));
665 static_cast<Matrix &&
>(B));
669 static_cast<Matrix &&
>(B));
676 return Vector(std::move(A) *
static_cast<const Matrix &
>(b));
682 return Vector(std::move(A) *
static_cast<Matrix &&
>(b));
725 std::plus<double>());
734 std::plus<double>());
750 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
754 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
758 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
763 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
767 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
771 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
776 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
780 static_cast<Matrix &
>(b) +=
static_cast<const Matrix &
>(a);
784 static_cast<Matrix &
>(a) +=
static_cast<const Matrix &
>(b);
790 static_cast<const Matrix &
>(b));
794 static_cast<const Matrix &
>(b));
798 static_cast<const Matrix &
>(b));
815 std::minus<double>());
824 std::minus<double>());
831 std::transform(A.
begin(), A.
end(), B.begin(), B.begin(),
832 std::minus<double>());
841 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
845 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
849 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
854 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
858 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
862 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
867 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
871 static_cast<const Matrix &
>(a) -
static_cast<Matrix &&
>(b);
875 static_cast<Matrix &
>(a) -=
static_cast<const Matrix &
>(b);
881 static_cast<const Matrix &
>(b));
885 static_cast<const Matrix &
>(b));
889 static_cast<const Matrix &
>(b));
905 std::transform(A.
begin(), A.
end(), result.
begin(), std::negate<double>());
911 std::transform(A.begin(), A.end(), A.begin(), std::negate<double>());
915 -
static_cast<Matrix &&
>(a);
919 -
static_cast<Matrix &&
>(a);
923 -
static_cast<Matrix &&
>(a);
948 [s](
double a) { return a * s; });
955 [s](
double a) { return a * s; });
971 static_cast<Matrix &
>(a) *= s;
975 static_cast<Matrix &
>(a) *= s;
979 static_cast<Matrix &
>(a) *= s;
991 return std::move(a) * s;
1006 [s](
double a) { return a / s; });
1013 [s](
double a) { return a / s; });
1017 return std::move(A);
1029 static_cast<Matrix &
>(a) /= s;
1030 return std::move(a);
1033 static_cast<Matrix &
>(a) /= s;
1034 return std::move(a);
1037 static_cast<Matrix &
>(a) /= s;
1038 return std::move(a);
1052 for (
size_t n = 0; n < in.
rows(); ++n)
1053 for (
size_t m = 0; m < in.
cols(); ++m)
1054 out(m, n) = in(n, m);
1065 if (in.
rows() == 1 || in.
cols() == 1) {
1081 if (in.rows() == in.cols())
1083 else if (in.rows() == 1 || in.cols() == 1)
1084 in.reshape(in.cols(), in.rows());
1087 return std::move(in);
1097 in.transpose_inplace();
1098 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)