45#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_MATRIX_INL
46#define LASS_GUARDIAN_OF_INCLUSION_NUM_MATRIX_INL
55#define LASS_NUM_MATRIX_ENFORCE_EQUAL_DIMENSION(a, b)\
56 *LASS_UTIL_IMPL_MAKE_ENFORCER(\
57 ::lass::util::impl::TruePredicate,\
58 ::lass::util::impl::DefaultRaiser,\
59 (a).rows() == (b).rows() && (a).columns() == (b).columns(),\
61 "Matrices '" LASS_STRINGIFY(a) "' and '" LASS_STRINGIFY(b) "' have different dimensions in '" LASS_HERE "'.")
63#define LASS_NUM_MATRIX_ENFORCE_ADJACENT_DIMENSION(a, b)\
64 *LASS_UTIL_IMPL_MAKE_ENFORCER(\
65 ::lass::util::impl::EqualPredicate,\
66 ::lass::util::impl::DefaultRaiser,\
69 "Matrices '" LASS_STRINGIFY(a) "' and '" LASS_STRINGIFY(b) "' have no matching dimensions for operation at '" LASS_HERE "'.")
83template <
typename T,
typename S>
105template <
typename T,
typename S>
113template <
typename T,
typename S>
131template <
typename T,
typename S>
132template <
typename T2,
typename S2>
138 const S2& b = other.storage();
139 const TSize m =
rows();
141 for (TSize i = 0; i < m; ++i)
143 for (TSize j = 0; j < n; ++j)
145 storage_(i, j) = b(i, j);
162template <
typename T,
typename S>
163template <
typename T2,
typename S2>
168 const S2& b = other.storage();
171 storage_.resize(m, n);
172 for (TSize i = 0; i < m; ++i)
174 for (TSize j = 0; j < n; ++j)
176 storage_(i, j) = b(i, j);
194template <
typename T,
typename S>
inline
195const typename Matrix<T, S>::TSize
198 return storage_.rows();
213template <
typename T,
typename S>
inline
214const typename Matrix<T, S>::TSize
217 return storage_.columns();
227template <
typename T,
typename S>
inline
228const typename Matrix<T, S>::TValue
244template <
typename T,
typename S>
inline
245typename Matrix<T, S>::TReference
250 return storage_(iRow, iColumn);
259template <
typename T,
typename S>
inline
260const typename Matrix<T, S>::TValue
274template <
typename T,
typename S>
inline
275typename Matrix<T, S>::TReference
287template <
typename T,
typename S>
inline
288typename Matrix<T, S>::ConstRow
291 return ConstRow(*
this, mod(index,
rows()));
300template <
typename T,
typename S>
inline
301typename Matrix<T, S>::Row
304 return Row(*
this, mod(index,
rows()));
312template <
typename T,
typename S>
inline
313typename Matrix<T, S>::ConstColumn
316 return ConstColumn(*
this, mod(index,
columns()));
325template <
typename T,
typename S>
inline
326typename Matrix<T, S>::Column
329 return Column(*
this, mod(index,
columns()));
342template <
typename T,
typename S>
inline
359template <
typename T,
typename S>
363 typedef impl::MNeg<T, S> TExpression;
386template <
typename T,
typename S>
387template <
typename S2>
391 LASS_NUM_MATRIX_ENFORCE_EQUAL_DIMENSION(*
this, other);
392 const S2& b = other.storage();
393 const TSize m =
rows();
395 for (TSize i = 0; i < m; ++i)
397 for (TSize j = 0; j < n; ++j)
399 storage_(i, j) += b(i, j);
419template <
typename T,
typename S>
420template <
typename S2>
424 LASS_NUM_MATRIX_ENFORCE_EQUAL_DIMENSION(*
this, other);
425 const S2& b = other.storage();
426 const TSize m =
rows();
428 for (TSize i = 0; i < m; ++i)
430 for (TSize j = 0; j < n; ++j)
432 storage_(i, j) -= b(i, j);
447template <
typename T,
typename S>
451 const TSize m =
rows();
453 for (TSize i = 0; i < m; ++i)
455 for (TSize j = 0; j < n; ++j)
457 storage_(i, j) *= scalar;
469template <
typename T,
typename S>
473 const TSize m =
rows();
475 for (TSize i = 0; i < m; ++i)
477 for (TSize j = 0; j < n; ++j)
479 storage_(i, j) /= scalar;
495template <
typename T,
typename S>
500 for (TSize i = 0; i <
rows; ++i)
502 for (TSize j = 0; j <
columns; ++j)
504 storage_(i, j) = TNumTraits::zero;
519template <
typename T,
typename S>
523 storage_.resize(iSize, iSize);
524 for (TSize i = 0; i < iSize; ++i)
526 for (TSize j = 0; j < iSize; ++j)
528 storage_(i, j) = i == j ? TNumTraits::one : TNumTraits::zero;
543template <
typename T,
typename S>
546 return storage_.rows() == 0 || storage_.columns() == 0;
562template <
typename T,
typename S>
565 const TSize m =
rows();
567 for (TSize i = 0; i < m; ++i)
569 for (TSize j = 0; j < n; ++j)
571 if (storage_(i, j) != TNumTraits::zero)
597template <
typename T,
typename S>
604 const TSize m =
rows();
606 for (TSize i = 0; i < m; ++i)
608 for (TSize j = 0; j < n; ++j)
610 if (storage_(i, j) != ((i == j) ? TNumTraits::one : TNumTraits::zero))
633template <
typename T,
typename S>
640 const TSize m =
rows();
642 for (TSize i = 0; i < m; ++i)
644 for (TSize j = 0; j < n; ++j)
646 if (i != j && storage_(i, j) != TNumTraits::zero)
662template <
typename T,
typename S>
665 return storage_.rows() == storage_.columns();
675template <
typename T,
typename S>
679 typedef impl::MTrans<T, S> TExpression;
695template <
typename T,
typename S>
701 const TSize size =
rows();
703 std::vector<std::ptrdiff_t> index(size);
704 const std::ptrdiff_t n =
static_cast<std::ptrdiff_t
>(size);
709 LASS_THROW_EX(util::SingularityError,
"failed to invert matrix");
713 for (std::ptrdiff_t i = 0; i < n; ++i)
721template <
typename T,
typename S>
inline
722const typename Matrix<T, S>::TStorage&
723Matrix<T, S>::storage()
const
730template <
typename T,
typename S>
inline
731typename Matrix<T, S>::TStorage&
732Matrix<T, S>::storage()
749template <
typename T,
typename S>
inline
753 storage_.swap(other.storage_);
773template <
typename T,
typename S1,
typename S2>
780 typedef typename Matrix<T, S1>::TSize TSize;
781 const TSize m = a.
rows();
783 for (TSize i = 0; i < m; ++i)
785 for (TSize j = 0; j < n; ++j)
787 if (a(i, j) != b(i, j))
803template <
typename T,
typename S1,
typename S2>
817template <
typename T,
typename S1,
typename S2>
821 LASS_NUM_MATRIX_ENFORCE_EQUAL_DIMENSION(a, b);
822 typedef impl::MAdd<T, S1, S2> TExpression;
834template <
typename T,
typename S1,
typename S2>
838 LASS_NUM_MATRIX_ENFORCE_EQUAL_DIMENSION(a, b);
839 typedef impl::MSub<T, S1, S2> TExpression;
862template <
typename T,
typename S1,
typename S2>
866 LASS_NUM_MATRIX_ENFORCE_ADJACENT_DIMENSION(a, b);
867 typedef impl::MProd<T, S1, S2> TExpression;
879template <
typename T,
typename S>
883 typedef impl::MAdd<T, impl::MScalar<T>, S> TExpression;
885 impl::MScalar<T>(a, b.
rows(), b.cols()), b.storage()));
896template <
typename T,
typename S>
900 typedef impl::MSub<T, impl::MScalar<T>, S> TExpression;
902 impl::MScalar<T>(a, b.
rows(), b.cols()), b.storage()));
913template <
typename T,
typename S>
917 typedef impl::MMul<T, impl::MScalar<T>, S> TExpression;
919 impl::MScalar<T>(a, b.
rows(), b.
columns()), b.storage()));
930template <
typename T,
typename S>
934 typedef impl::MAdd<T, S, impl::MScalar<T> > TExpression;
936 a.storage(), impl::MScalar<T>(b, a.
rows(), a.cols())));
947template <
typename T,
typename S>
951 typedef impl::MSub<T, S, impl::MScalar<T> > TExpression;
953 a.storage(), impl::MScalar<T>(-b, a.
rows(), a.cols())));
964template <
typename T,
typename S>
968 typedef impl::MMul<T, S, impl::MScalar<T> > TExpression;
970 a.storage(), impl::MScalar<T>(b, a.
rows(), a.
columns())));
981template <
typename T,
typename S>
985 typedef impl::MMul<T, S, impl::MScalar<T> > TExpression;
1005template <
typename T,
typename S,
typename S2>
1010 LASS_NUM_MATRIX_ENFORCE_ADJACENT_DIMENSION(a, bx);
1012 const size_t n = a.
rows();
1014 std::vector<std::ptrdiff_t> pivot(n);
1018 std::vector<T> bcol;
1025 if (!
impl::ludecomp<T>(lu.storage().rowMajor(), pivot.begin(),
static_cast<std::ptrdiff_t
>(n), d))
1027 LASS_THROW_EX(util::SingularityError,
"failed to solve matrix equation");
1030 for (
size_t i = 0; i < bx.
columns(); ++i)
1032 LASS_ASSERT(
static_cast<int>(i) >= 0);
1033 typename Matrix<T, S2>::Column xcol = bx.
column(
static_cast<int>(i));
1036 for (
size_t j = 0; j < n; ++j)
1041 impl::lusolve<T>(lu.storage().rowMajor(), pivot.begin(), xcol.begin(),
static_cast<std::ptrdiff_t
>(n));
1044 impl::lumprove<T>(aa.storage().rowMajor(), lu.storage().rowMajor(), pivot.begin(), bcol.begin(), xcol.begin(),
static_cast<std::ptrdiff_t
>(n));
1053template <
typename T,
typename S,
typename Char,
typename Traits>
1054std::basic_ostream<Char, Traits>&
1055operator<<(std::basic_ostream<Char, Traits>& stream,
const Matrix<T, S>& matrix)
1057 typedef typename Matrix<T, S>::TSize TSize;
1058 const TSize m = matrix.
rows();
1059 const TSize n = matrix.
columns();
1061 LASS_ENFORCE_STREAM(stream) <<
"(";
1062 for (TSize i = 0; i < m; ++i)
1066 LASS_ENFORCE_STREAM(stream) <<
", ";
1068 LASS_ENFORCE_STREAM(stream) <<
"(";
1071 LASS_ENFORCE_STREAM(stream) << matrix(i, 0);
1073 for (TSize j = 1; j < n; ++j)
1075 LASS_ENFORCE_STREAM(stream) <<
", " << matrix(i, j);
1077 LASS_ENFORCE_STREAM(stream) <<
")";
1079 LASS_ENFORCE_STREAM(stream) <<
")";
a dynamic sized n-dimensional matrix with expression templates
bool isDiagonal() const
test if this matrix is an diagonal matrix
const Matrix< T, impl::MMul< T, impl::MScalar< T >, S > > operator*(const T &a, const Matrix< T, S > &b)
multiply a with all components of b
const Matrix< T, impl::MMul< T, S, impl::MScalar< T > > > operator/(const Matrix< T, S > &a, typename Matrix< T, S >::TParam b)
divide all components of a by b.
const Matrix< T, impl::MAdd< T, S, impl::MScalar< T > > > operator-(const Matrix< T, S > &a, typename Matrix< T, S >::TParam b)
subtract b from all components of a
void solve(const Matrix< T, S > &a, Matrix< T, S2 > &bx, bool improve)
solve equation A * X = B
Matrix< T, S > & operator=(const Matrix< T2, S2 > &other)
assign storage/expression matrix to this (this should be a storage matrix).
const Matrix< T, impl::MAdd< T, S, impl::MScalar< T > > > operator+(const Matrix< T, S > &a, typename Matrix< T, S >::TParam b)
add b to all components of a
Matrix< T, S > & operator/=(TParam scalar)
scalar multiplication assignment of matrix
void setIdentity(TSize size)
set matrix to an identity matrix.
const Matrix< T, impl::MAdd< T, S1, S2 > > operator+(const Matrix< T, S1 > &a, const Matrix< T, S2 > &b)
componentwise addition
bool isIdentity() const
test if this matrix equals a identity matrix
Matrix< T, S > & operator*=(TParam scalar)
scalar multiplication assignment of matrix
Matrix< T, S > & operator-=(const Matrix< T, S2 > &other)
componentswise subtraction assignment of two matrices This method is equivalent to this+=(-iB) .
bool isSquare() const
return true if matrix has as many rows as columns
void invert()
replace matrix by its inverse.
const TValue at(TSigned row, TSigned column) const
return the component value at position (row, column) (row, column) will be wrapped to range [0,...
const Matrix< T, impl::MNeg< T, S > > operator-() const
return a vector with all components negated (-a)(i, j) == -(a(i, j)).
Matrix()
constructs an empty matrix
const TSize columns() const
return number of columns in matrix.
const Matrix< T, impl::MSub< T, impl::MScalar< T >, S > > operator-(const T &a, const Matrix< T, S > &b)
add a to all negated components of b
void setZero(TSize rows, TSize columns)
set this to a zero matrix of rows rows and columns columns.
const Matrix< T, S > & operator+() const
A weird way to get back the same object.
const Matrix< T, impl::MMul< T, S, impl::MScalar< T > > > operator*(const Matrix< T, S > &a, typename Matrix< T, S >::TParam b)
multiply all components of a with b.
const Matrix< T, impl::MProd< T, S1, S2 > > operator*(const Matrix< T, S1 > &a, const Matrix< T, S2 > &b)
Matrix multiplication.
const TSize rows() const
return number of rows in matrix.
const Matrix< T, impl::MAdd< T, impl::MScalar< T >, S > > operator+(const T &a, const Matrix< T, S > &b)
add a to all components of b
bool operator!=(const Matrix< T, S1 > &a, const Matrix< T, S2 > &b)
ConstRow row(TSigned index) const
return a row of matrix.
const Matrix< T, impl::MSub< T, S1, S2 > > operator-(const Matrix< T, S1 > &a, const Matrix< T, S2 > &b)
componentwise addition
const Matrix< T, impl::MTrans< T, S > > transposed() const
return transposed matrix
void swap(Matrix< T, S > &other)
swap two matrices
bool isEmpty() const
return true if this is a (0�0) matrix
ConstColumn column(TSigned index) const
return a column of matrix.
Matrix< T, S > & operator+=(const Matrix< T, S2 > &other)
componentswise addition assignment of two matrices
const TValue operator()(TSize row, TSize column) const
return the component value at position (row, column)
bool operator==(const Matrix< T, S1 > &a, const Matrix< T, S2 > &b)
bool isZero() const
test if this matrix equals a zero matrix.
T inv(const T &x)
return x ^ -1
void lusolve(RandomIterator1 iMatrix, RandomIterator2 iIndex, RandomIterator3 ioColumn, std::ptrdiff_t iSize)
Solves the set of linear eqautions A X = B.
void lumprove(RandomIterator1 iMatrix, RandomIterator2 iMatrixLU, RandomIterator3 iIndex, RandomIterator4 iColumn, RandomIterator5 ioX, std::ptrdiff_t iSize)
Improves a solution vector X of the linear set of equations A X = B.
bool ludecomp(RandomIterator1 ioMatrix, RandomIterator2 oIndex, std::ptrdiff_t iSize, int &iD)
Given a complex matrix iA, this routine replaces it by the LU decomposition of a rowwise permutation ...
numeric types and traits.
Library for Assembled Shared Sources.