Many fixes and tests of the initial release of Polymath.
This commit is contained in:
parent
03ff1f639a
commit
d5638d0f65
@ -55,6 +55,27 @@ std::string to_string(std::complex<T> value)
|
|||||||
return sstr.str();
|
return sstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Poly::Matrix<T,M> real(const Poly::Matrix<std::complex<T>,M>& mat)
|
||||||
|
{
|
||||||
|
Poly::Matrix<T,M> result(mat.rows(),mat.columns());
|
||||||
|
std::transform(mat.begin(),mat.end(),result.begin(),[](const std::complex<T>& elem) -> T {return elem.real();});
|
||||||
|
}
|
||||||
|
template <typename T, int M>
|
||||||
|
Poly::Matrix<T,M> imag(const Poly::Matrix<std::complex<T>,M>& mat)
|
||||||
|
{
|
||||||
|
Poly::Matrix<T,M> result(mat.rows(),mat.columns());
|
||||||
|
std::transform(mat.begin(),mat.end(),result.begin(),[](const std::complex<T>& elem) -> T {return elem.imag();});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
void swap(Poly::Matrix<T,M>&__a, Poly::Matrix<T,M>&__b)
|
||||||
|
{
|
||||||
|
std::swap(__a._rows,__b._rows);
|
||||||
|
std::swap(__a._columns,__b._columns);
|
||||||
|
std::swap(__a._matEls,__b._matEls);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Poly
|
namespace Poly
|
||||||
@ -129,6 +150,8 @@ public:
|
|||||||
typedef const T& const_reference;
|
typedef const T& const_reference;
|
||||||
typedef long size_type;
|
typedef long size_type;
|
||||||
typedef size_type difference_type;
|
typedef size_type difference_type;
|
||||||
|
typedef typename std::vector<T>::iterator iterator;
|
||||||
|
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<T> _matEls;
|
std::vector<T> _matEls;
|
||||||
@ -140,21 +163,21 @@ private:
|
|||||||
inline size_type SizeToReserve(const size_type &rows, const size_type &columns) const;
|
inline size_type SizeToReserve(const size_type &rows, const size_type &columns) const;
|
||||||
void invert_manual();
|
void invert_manual();
|
||||||
|
|
||||||
void _check_square_matrix();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void _check_square_matrix() const;
|
||||||
|
|
||||||
Matrix<T, M>();
|
Matrix<T, M>();
|
||||||
Matrix<T, M>(const size_type& rows, const size_type& columns, const T& initialValue = T());
|
Matrix<T, M>(const size_type& rows, const size_type& columns, const T& initialValue = T());
|
||||||
Matrix<T, M>(const size_type& rows, const size_type& columns, const std::initializer_list<T>& init_list);
|
Matrix<T, M>(const size_type& rows, const size_type& columns, const std::initializer_list<T>& init_list);
|
||||||
Matrix<T, M>(const Matrix<T, M>& src) = default;
|
Matrix<T, M>(const Matrix<T, M>& src) = default;
|
||||||
Matrix<T, M>(Matrix&&) = default;
|
Matrix<T, M>(Matrix<T, M>&&) = default;
|
||||||
|
~Matrix() = default;
|
||||||
|
|
||||||
//copy constructor from real to complex
|
//copy constructor from real to complex
|
||||||
template <typename U, typename = typename std::enable_if<std::is_same<T, std::complex<U>>::value>::type>
|
template <typename U, typename = typename std::enable_if<std::is_same<T, std::complex<U>>::value>::type>
|
||||||
Matrix(const Matrix<U, M> & src);
|
Matrix(const Matrix<U, M> & src);
|
||||||
|
|
||||||
~Matrix() = default;
|
|
||||||
|
|
||||||
Matrix<T, M> &operator=(const Matrix<T,M>& rhs) = default;
|
Matrix<T, M> &operator=(const Matrix<T,M>& rhs) = default;
|
||||||
|
|
||||||
@ -178,14 +201,22 @@ public:
|
|||||||
friend Matrix<_T,_M> operator+(const Matrix<_T,_M>& lhs, const Matrix<_T,_M>& rhs);
|
friend Matrix<_T,_M> operator+(const Matrix<_T,_M>& lhs, const Matrix<_T,_M>& rhs);
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend Matrix<_T,_M> operator-(const Matrix<_T,_M>& lhs, const Matrix<_T,_M>& rhs);
|
friend Matrix<_T,_M> operator-(const Matrix<_T,_M>& lhs, const Matrix<_T,_M>& rhs);
|
||||||
|
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend Matrix<_T,_M> operator*(const _T& lhs, const Matrix<_T,_M>& rhs);
|
friend Matrix<_T,_M> operator*(const _T& lhs, const Matrix<_T,_M>& rhs);
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend Matrix<_T,_M> operator*(const Matrix<_T,_M>& lhs, const _T& rhs);
|
friend Matrix<_T,_M> operator*(const Matrix<_T,_M>& lhs, const _T& rhs);
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend Matrix<_T,_M> operator/(const Matrix<_T,_M>& lhs, const _T& rhs);
|
friend Matrix<_T,_M> operator/(const Matrix<_T,_M>& lhs, const _T& rhs);
|
||||||
|
template <typename _T, int _M>
|
||||||
|
friend void std::swap(Poly::Matrix<_T,_M>&__a, Poly::Matrix<_T,_M>&__b);
|
||||||
|
|
||||||
|
|
||||||
|
template <typename _T, int _M>
|
||||||
|
friend Matrix<std::complex<_T>,_M> operator*(const Matrix<std::complex<_T>,_M>& lhs, const _T& rhs);
|
||||||
|
template <typename _T, int _M>
|
||||||
|
friend Matrix<std::complex<_T>,_M> operator*(const _T& lhs, const Matrix<std::complex<_T>,_M>& rhs);
|
||||||
|
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend Matrix<std::complex<_T>,_M> operator*(const std::complex<_T>& lhs, const Matrix<_T,_M>& rhs);
|
friend Matrix<std::complex<_T>,_M> operator*(const std::complex<_T>& lhs, const Matrix<_T,_M>& rhs);
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
@ -201,19 +232,24 @@ public:
|
|||||||
|
|
||||||
inline T& operator[](const size_type& index);
|
inline T& operator[](const size_type& index);
|
||||||
inline const T& operator[](const size_type& index) const;
|
inline const T& operator[](const size_type& index) const;
|
||||||
|
inline T& operator()(const size_type& index);
|
||||||
|
inline const T& operator()(const size_type& index) const;
|
||||||
|
|
||||||
inline typename std::vector<T>::iterator begin() noexcept;
|
inline iterator begin() noexcept;
|
||||||
inline typename std::vector<T>::const_iterator begin() const noexcept;
|
inline const_iterator begin() const noexcept;
|
||||||
inline typename std::vector<T>::iterator end() noexcept;
|
inline iterator end() noexcept;
|
||||||
inline typename std::vector<T>::const_iterator end() const noexcept;
|
inline const_iterator end() const noexcept;
|
||||||
|
|
||||||
Matrix<T,M>& operator+=(const Matrix<T,M>& rhs);
|
Matrix<T,M>& operator+=(const Matrix<T,M>& rhs);
|
||||||
Matrix<T,M>& operator-=(const Matrix<T,M>& rhs);
|
Matrix<T,M>& operator-=(const Matrix<T,M>& rhs);
|
||||||
Matrix<T,M>& operator*=(const Matrix<T,M>& rhs);
|
Matrix<T,M>& operator*=(const Matrix<T,M>& rhs);
|
||||||
Matrix<T,M>& operator/=(const Matrix<T,M>& rhs);
|
Matrix<T,M>& operator*=(const T& rhs);
|
||||||
|
Matrix<T,M>& operator/=(const T& rhs);
|
||||||
void elementWiseProduct_inplace(const Matrix<T,M>& rhs);
|
void elementWiseProduct_inplace(const Matrix<T,M>& rhs);
|
||||||
Matrix<T,M> elementWiseProduct(const Matrix<T,M>& rhs);
|
Matrix<T,M> elementWiseProduct(const Matrix<T,M>& rhs);
|
||||||
T trace();
|
T trace();
|
||||||
|
template <typename _T, int _M>
|
||||||
|
friend _T Trace(const Matrix<_T,_M> &rhs);
|
||||||
void zeros();
|
void zeros();
|
||||||
void ones();
|
void ones();
|
||||||
void inverse_inplace();
|
void inverse_inplace();
|
||||||
@ -221,29 +257,36 @@ public:
|
|||||||
Matrix<T,M> getExp();
|
Matrix<T,M> getExp();
|
||||||
void conjugate_inplace();
|
void conjugate_inplace();
|
||||||
void conjugateTranspose_inplace();
|
void conjugateTranspose_inplace();
|
||||||
std::vector<T> vectorize(const VECTORIZATION_MODE& mode = VECMODE_FULL) const;
|
Matrix<T,M> vectorize(const VECTORIZATION_MODE& mode = VECMODE_FULL) const;
|
||||||
|
Matrix<T,M> diagonal() const;
|
||||||
const T& at(size_type row, size_type column) const;
|
const T& at(size_type row, size_type column) const;
|
||||||
T& at(size_type row, size_type column);
|
T& at(size_type row, size_type column);
|
||||||
|
T& operator()(size_type row, size_type column);
|
||||||
|
const T& operator()(size_type row, size_type column) const;
|
||||||
|
|
||||||
T& front();
|
T& front();
|
||||||
const T& front() const;
|
const T& front() const;
|
||||||
void resize(size_type rows, size_type columns, const T &initialValue = T());
|
void resize(size_type rows, size_type columns, const T &initialValue = T());
|
||||||
const size_type& rows();
|
const size_type& rows();
|
||||||
const size_type& columns();
|
const size_type& columns();
|
||||||
|
typename Matrix<T,M>::size_type size();
|
||||||
const size_type& rows() const;
|
const size_type& rows() const;
|
||||||
const size_type& columns() const;
|
const size_type& columns() const;
|
||||||
|
typename Matrix<T,M>::size_type size() const;
|
||||||
void clear();
|
void clear();
|
||||||
void transpose_inplace();
|
void transpose_inplace();
|
||||||
T getDeterminant();
|
T determinant();
|
||||||
Matrix<T,M> getSVD();
|
Matrix<T,M> SVD();
|
||||||
std::string asString(int precision = 7, char open = '[', char close = ']', char sep = ',');
|
std::string asString(int precision = 7, char open = '[', char close = ']', char sep = ',');
|
||||||
template <typename _T, int _M>
|
template <typename _T, int _M>
|
||||||
friend std::ostream& operator<<(std::ostream &os, const Matrix<_T,_M> &src);
|
friend std::ostream& operator<<(std::ostream &os, const Matrix<_T,_M> &src);
|
||||||
|
void print(std::ostream &os = std::cout, std::string header = "") const;
|
||||||
|
void raw_print(std::ostream &os = std::cout, std::string header = "") const;
|
||||||
//converts elements to type _targetType and puts them in a new Matrix
|
//converts elements to type _targetType and puts them in a new Matrix
|
||||||
template <typename _targetType>
|
template <typename _targetType>
|
||||||
Matrix<_targetType,M> convertElements();
|
Matrix<_targetType,M> convertElements();
|
||||||
template <typename _targetType>
|
template <typename _targetType>
|
||||||
Matrix<_targetType,M> convertElements(std::function<_targetType(T)> conversion_rule);
|
Matrix<_targetType,M> convertElements(const std::function<_targetType(T)> &conversion_rule);
|
||||||
|
|
||||||
//puts all the elements in a new container
|
//puts all the elements in a new container
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
@ -261,7 +304,7 @@ Matrix<_targetType, M> Matrix<T,M>::convertElements()
|
|||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
template <typename _targetType>
|
template <typename _targetType>
|
||||||
Matrix<_targetType, M> Matrix<T,M>::convertElements(std::function<_targetType(T)> conversion_rule)
|
Matrix<_targetType, M> Matrix<T,M>::convertElements(const std::function<_targetType(T)> &conversion_rule)
|
||||||
{
|
{
|
||||||
Matrix<_targetType, M> ret(this->rows(),this->columns());
|
Matrix<_targetType, M> ret(this->rows(),this->columns());
|
||||||
std::transform(this->begin(), this->end(), ret.begin(),conversion_rule);
|
std::transform(this->begin(), this->end(), ret.begin(),conversion_rule);
|
||||||
@ -400,6 +443,18 @@ const typename Matrix<T,M>::size_type& Matrix<T,M>::rows() const
|
|||||||
return _rows;
|
return _rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
typename Matrix<T,M>::size_type Matrix<T,M>::size()
|
||||||
|
{
|
||||||
|
return this->_matEls.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
typename Matrix<T,M>::size_type Matrix<T,M>::size() const
|
||||||
|
{
|
||||||
|
return this->_matEls.size();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::clear()
|
void Matrix<T,M>::clear()
|
||||||
{
|
{
|
||||||
@ -430,13 +485,40 @@ bool Matrix<T,M>::operator!=(const Matrix<T,M>& rhs)
|
|||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::transpose_inplace()
|
void Matrix<T,M>::transpose_inplace()
|
||||||
{
|
{
|
||||||
*this = Transpose(*this);
|
if(this->rows() == 1 || this->columns() == 1)
|
||||||
|
{
|
||||||
|
std::swap(this->_rows,this->_columns);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(typename Poly::Matrix<T,M>::size_type i = 0; i < this->rows(); i++)
|
||||||
|
{
|
||||||
|
for(typename Poly::Matrix<T,M>::size_type j = i+1; j < this->columns(); j++)
|
||||||
|
{
|
||||||
|
std::swap(this->at(j,i),this->at(i,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::conjugateTranspose_inplace()
|
void Matrix<T,M>::conjugateTranspose_inplace()
|
||||||
{
|
{
|
||||||
*this = ConjugateTranspose(*this);
|
if(this->rows() == 1 || this->columns() == 1)
|
||||||
|
{
|
||||||
|
std::swap(this->_rows,this->_columns);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(typename Poly::Matrix<T,M>::size_type i = 0; i < this->rows(); i++)
|
||||||
|
{
|
||||||
|
for(typename Poly::Matrix<T,M>::size_type j = i+1; j < this->columns(); j++)
|
||||||
|
{
|
||||||
|
std::swap(this->at(j,i),this->at(i,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->conjugate_inplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
@ -444,7 +526,7 @@ std::ostream& operator<<(std::ostream &os, const Matrix<T,M> &src)
|
|||||||
{
|
{
|
||||||
for (typename Matrix<T,M>::size_type i = 0; i < src._rows; i++)
|
for (typename Matrix<T,M>::size_type i = 0; i < src._rows; i++)
|
||||||
{
|
{
|
||||||
for (typename Matrix<T,M>::size_type j = 0; j < src._rows; j++)
|
for (typename Matrix<T,M>::size_type j = 0; j < src._columns; j++)
|
||||||
{
|
{
|
||||||
os << src.at(i,j) << "\t";
|
os << src.at(i,j) << "\t";
|
||||||
}
|
}
|
||||||
@ -452,6 +534,30 @@ std::ostream& operator<<(std::ostream &os, const Matrix<T,M> &src)
|
|||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Matrix<std::complex<T>,M> operator*(const Matrix<std::complex<T>,M>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
Matrix<std::complex<T>,M> result = lhs;
|
||||||
|
for(typename Matrix<T,M>::size_type i = 0; i < static_cast<typename Matrix<T,M>::size_type>(lhs._matEls.size()); i++)
|
||||||
|
{
|
||||||
|
result._matEls[i] *= rhs;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Matrix<std::complex<T>,M> operator*(const T& lhs, const Matrix<std::complex<T>,M>& rhs)
|
||||||
|
{
|
||||||
|
Matrix<std::complex<T>,M> result = rhs;
|
||||||
|
for(typename Matrix<T,M>::size_type i = 0; i < static_cast<typename Matrix<T,M>::size_type>(rhs._matEls.size()); i++)
|
||||||
|
{
|
||||||
|
result._matEls[i] *= lhs;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
Matrix<T,M> operator*(const Matrix<T,M>& lhs, const Matrix<T,M>& rhs)
|
Matrix<T,M> operator*(const Matrix<T,M>& lhs, const Matrix<T,M>& rhs)
|
||||||
{
|
{
|
||||||
@ -601,6 +707,20 @@ Matrix<T,M>& Matrix<T,M>::operator*=(const Matrix<T,M>& rhs)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Matrix<T,M>& Matrix<T,M>::operator*=(const T& rhs)
|
||||||
|
{
|
||||||
|
(*this) = (*this) * rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Matrix<T,M>& Matrix<T,M>::operator/=(const T& rhs)
|
||||||
|
{
|
||||||
|
(*this) = (*this) / rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::elementWiseProduct_inplace(const Matrix<T,M> &rhs)
|
void Matrix<T,M>::elementWiseProduct_inplace(const Matrix<T,M> &rhs)
|
||||||
{
|
{
|
||||||
@ -632,6 +752,18 @@ T Matrix<T,M>::trace()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
T Trace(const Matrix<T,M> &rhs)
|
||||||
|
{
|
||||||
|
rhs._check_square_matrix();
|
||||||
|
T result = T(0);
|
||||||
|
for(typename Matrix<T,M>::size_type i = 0; i < rhs.rows(); i++)
|
||||||
|
{
|
||||||
|
result += rhs.at(i,i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::zeros()
|
void Matrix<T,M>::zeros()
|
||||||
{
|
{
|
||||||
@ -647,11 +779,7 @@ void Matrix<T,M>::ones()
|
|||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::inverse_inplace()
|
void Matrix<T,M>::inverse_inplace()
|
||||||
{
|
{
|
||||||
//FIXME: Make size error functions all in one place
|
this->_check_square_matrix();
|
||||||
if(rows() != columns())
|
|
||||||
{
|
|
||||||
throw std::length_error("Matrix inverse is only for square matrices.");
|
|
||||||
}
|
|
||||||
if(std::is_same<float,T>::value)
|
if(std::is_same<float,T>::value)
|
||||||
{
|
{
|
||||||
Xgetri(float,s, tmp_workspace_size)
|
Xgetri(float,s, tmp_workspace_size)
|
||||||
@ -737,7 +865,7 @@ void Matrix<T,M>::invert_manual()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
void Matrix<T,M>::_check_square_matrix()
|
void Matrix<T,M>::_check_square_matrix() const
|
||||||
{
|
{
|
||||||
#ifdef POLYMATH_DEBUG
|
#ifdef POLYMATH_DEBUG
|
||||||
if(this->columns() != this->rows())
|
if(this->columns() != this->rows())
|
||||||
@ -829,20 +957,34 @@ void Matrix<T,M>::conjugate_inplace()
|
|||||||
|
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
Matrix<T, M> Matrix<T,M>::diagonal() const
|
||||||
{
|
{
|
||||||
std::vector<T> output;
|
_check_square_matrix();
|
||||||
|
Matrix<T, M> output(this->columns(),1);
|
||||||
|
for(long i = 0; i < this->rows(); i++)
|
||||||
|
{
|
||||||
|
output._matEls[i] = this->at(i,i);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Matrix<T, M> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
||||||
|
{
|
||||||
|
Matrix<T, M> output;
|
||||||
if(M == ColMaj)
|
if(M == ColMaj)
|
||||||
{
|
{
|
||||||
if(mode == Poly::VECMODE_FULL)
|
if(mode == Poly::VECMODE_FULL)
|
||||||
{
|
{
|
||||||
return _matEls;
|
Matrix<T, M> output(this->rows()*this->columns(),1);
|
||||||
|
std::copy(this->begin(),this->end(),output.begin());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_NO_DIAGONAL)
|
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_NO_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()-1))/2);
|
output.resize((this->columns()*(this->columns()-1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin() + this->columns(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin() + this->columns(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = 1; i < this->columns(); i++) //Starts with 1 to skip the diagonal
|
for(int i = 1; i < this->columns(); i++) //Starts with 1 to skip the diagonal
|
||||||
{
|
{
|
||||||
@ -854,8 +996,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_WITH_DIAGONAL)
|
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_WITH_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()+1))/2);
|
output.resize((this->columns()*(this->columns()+1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin();
|
typename Matrix<T,M>::const_iterator it = _matEls.begin();
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = 0; i < this->columns(); i++)
|
for(int i = 0; i < this->columns(); i++)
|
||||||
{
|
{
|
||||||
@ -867,8 +1009,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_NO_DIAGONAL)
|
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_NO_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()-1))/2);
|
output.resize((this->columns()*(this->columns()-1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
it += 1;
|
it += 1;
|
||||||
for(int i = this->columns() - 1; i > 0 ; i--) //Starts with 1 to skip the diagonal
|
for(int i = this->columns() - 1; i > 0 ; i--) //Starts with 1 to skip the diagonal
|
||||||
@ -881,8 +1023,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_WITH_DIAGONAL)
|
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_WITH_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()+1))/2);
|
output.resize((this->columns()*(this->columns()+1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = this->columns() - 1; i >= 0 ; i--) //Starts with 1 to skip the diagonal
|
for(int i = this->columns() - 1; i >= 0 ; i--) //Starts with 1 to skip the diagonal
|
||||||
{
|
{
|
||||||
@ -900,13 +1042,15 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
{
|
{
|
||||||
if(mode == Poly::VECMODE_FULL)
|
if(mode == Poly::VECMODE_FULL)
|
||||||
{
|
{
|
||||||
return _matEls;
|
Matrix<T, M> output(this->rows()*this->columns(),1);
|
||||||
|
std::copy(this->begin(),this->end(),output.begin());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_NO_DIAGONAL)
|
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_NO_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()-1))/2);
|
output.resize((this->columns()*(this->columns()-1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin() + this->columns(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin() + this->columns(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = 1; i < this->columns(); i++) //Starts with 1 to skip the diagonal
|
for(int i = 1; i < this->columns(); i++) //Starts with 1 to skip the diagonal
|
||||||
{
|
{
|
||||||
@ -918,8 +1062,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_WITH_DIAGONAL)
|
else if(mode == Poly::VECMODE_LOWER_TRIANGULAR_WITH_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()+1))/2);
|
output.resize((this->columns()*(this->columns()+1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin();
|
typename Matrix<T,M>::const_iterator it = _matEls.begin();
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = 0; i < this->columns(); i++)
|
for(int i = 0; i < this->columns(); i++)
|
||||||
{
|
{
|
||||||
@ -931,8 +1075,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_NO_DIAGONAL)
|
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_NO_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()-1))/2);
|
output.resize((this->columns()*(this->columns()-1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
it += 1;
|
it += 1;
|
||||||
for(int i = this->columns() - 1; i > 0 ; i--) //Starts with 1 to skip the diagonal
|
for(int i = this->columns() - 1; i > 0 ; i--) //Starts with 1 to skip the diagonal
|
||||||
@ -945,8 +1089,8 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_WITH_DIAGONAL)
|
else if(mode == Poly::VECMODE_UPPER_TRIANGULAR_WITH_DIAGONAL)
|
||||||
{
|
{
|
||||||
_check_square_matrix();
|
_check_square_matrix();
|
||||||
output.resize((this->columns()*(this->columns()+1))/2);
|
output.resize((this->columns()*(this->columns()+1))/2,1);
|
||||||
typename std::vector<T>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
typename Matrix<T,M>::const_iterator it = _matEls.begin(); //iterator at rows to skip in every step, starts at second column
|
||||||
long size_to_copy = 0;
|
long size_to_copy = 0;
|
||||||
for(int i = this->columns() - 1; i >= 0 ; i--) //Starts with 1 to skip the diagonal
|
for(int i = this->columns() - 1; i >= 0 ; i--) //Starts with 1 to skip the diagonal
|
||||||
{
|
{
|
||||||
@ -963,6 +1107,18 @@ std::vector<T> Matrix<T, M>::vectorize(const VECTORIZATION_MODE &mode) const
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
T& Matrix<T,M>::operator()(size_type row, size_type column)
|
||||||
|
{
|
||||||
|
return this->at(row,column);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
const T& Matrix<T,M>::operator()(size_type row, size_type column) const
|
||||||
|
{
|
||||||
|
return this->at(row,column);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
T &Matrix<T,M>::at(size_type row, size_type column)
|
T &Matrix<T,M>::at(size_type row, size_type column)
|
||||||
{
|
{
|
||||||
@ -1014,40 +1170,47 @@ const T& Matrix<T,M>::operator[](const size_type& index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
typename std::vector<T>::iterator Matrix<T,M>::begin() noexcept
|
T& Matrix<T,M>::operator()(const size_type& index)
|
||||||
|
{
|
||||||
|
return _matEls[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
const T& Matrix<T,M>::operator()(const size_type& index) const
|
||||||
|
{
|
||||||
|
return _matEls[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
typename Matrix<T,M>::iterator Matrix<T,M>::begin() noexcept
|
||||||
{
|
{
|
||||||
return this->_matEls.begin();
|
return this->_matEls.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
typename std::vector<T>::const_iterator Matrix<T,M>::begin() const noexcept
|
typename Matrix<T,M>::const_iterator Matrix<T,M>::begin() const noexcept
|
||||||
{
|
{
|
||||||
return this->_matEls.begin();
|
return this->_matEls.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
typename std::vector<T>::iterator Matrix<T,M>::end() noexcept
|
typename Matrix<T,M>::iterator Matrix<T,M>::end() noexcept
|
||||||
{
|
{
|
||||||
return this->_matEls.end();
|
return this->_matEls.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
typename std::vector<T>::const_iterator Matrix<T,M>::end() const noexcept
|
typename Matrix<T,M>::const_iterator Matrix<T,M>::end() const noexcept
|
||||||
{
|
{
|
||||||
return this->_matEls.end();
|
return this->_matEls.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
T Matrix<T,M>::getDeterminant()
|
T Matrix<T,M>::determinant()
|
||||||
{
|
{
|
||||||
|
this->_check_square_matrix();
|
||||||
T det = static_cast<T>(1);
|
T det = static_cast<T>(1);
|
||||||
T val;
|
T val;
|
||||||
#ifdef POLYMATH_DEBUG
|
|
||||||
if(this->rows() != this->columns())
|
|
||||||
{
|
|
||||||
throw std::length_error("Determinant is for square matrices only.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
size_type sideLength = this->rows();
|
size_type sideLength = this->rows();
|
||||||
for (size_type i = 0; i < sideLength; i++)
|
for (size_type i = 0; i < sideLength; i++)
|
||||||
{
|
{
|
||||||
@ -1056,11 +1219,11 @@ T Matrix<T,M>::getDeterminant()
|
|||||||
// cout<<(*this)<<endl;
|
// cout<<(*this)<<endl;
|
||||||
val = static_cast<T>(1)/((*this)[i][i]);
|
val = static_cast<T>(1)/((*this)[i][i]);
|
||||||
det *= static_cast<T>(1)/val;
|
det *= static_cast<T>(1)/val;
|
||||||
this->doMultiplyRowWith(val,i);
|
MultiplyRowWith(*this,val,i);
|
||||||
for (int j = i + 1; j < sideLength; j++)
|
for (int j = i + 1; j < sideLength; j++)
|
||||||
{
|
{
|
||||||
val = -((*this)[j][i]);
|
val = -((*this)[j][i]);
|
||||||
this->doMultiplyAndAddToRow(val,i,j);
|
MultiplyAndAddToRow(*this,val,i,j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1082,28 +1245,25 @@ T Matrix<T,M>::getDeterminant()
|
|||||||
return det;
|
return det;
|
||||||
}
|
}
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
Matrix<T,M> Matrix<T,M>::getSVD()
|
Matrix<T,M> Matrix<T,M>::SVD()
|
||||||
{
|
{
|
||||||
Matrix<T,M> U, S, V;
|
Matrix<T,M> U, S, V;
|
||||||
S = (*this);
|
S = (*this);
|
||||||
std::cout<<S.rows()<<"\t"<<S.columns()<<std::endl;
|
// std::cout<<S.rows()<<"\t"<<S.columns()<<std::endl;
|
||||||
std::vector<T> ret;
|
std::vector<T> ret;
|
||||||
U = Matrix<T,M>::identity(S.rows());
|
U = IdentityMatrix<T,M>(S.rows());
|
||||||
V = Matrix<T,M>::identity(S.columns());
|
V = IdentityMatrix<T,M>(S.columns());
|
||||||
T val;
|
T val;
|
||||||
for (size_type i = 0; i < S.rows(); i++)
|
for (size_type i = 0; i < S.rows(); i++)
|
||||||
{
|
{
|
||||||
if(S[i][i] != static_cast<T>(0))
|
if(S[i][i] != static_cast<T>(0))
|
||||||
{
|
{
|
||||||
std::cout<<"Int S: "<<std::endl<<S<<std::endl<<U<<std::endl<<U*S<<std::endl;
|
// std::cout<<"Int S: "<<std::endl<<S<<std::endl<<U<<std::endl<<U*S<<std::endl;
|
||||||
//val = 1.0/((S)[i][i]);
|
|
||||||
//S.doMultiplyRowWith(val,i);
|
|
||||||
//sideMat.doMultiplyRowWith(1/val,i);
|
|
||||||
for (size_type j = i + 1; j < S.rows(); j++)
|
for (size_type j = i + 1; j < S.rows(); j++)
|
||||||
{
|
{
|
||||||
val = -S[j][i]/S[i][i];
|
val = -S[j][i]/S[i][i];
|
||||||
S.doMultiplyAndAddToRow(val,i,j);
|
MultiplyAndAddToRow(S,val,i,j);
|
||||||
U.doMultiplyAndAddToRow(-val,i,j);
|
MultiplyAndAddToRow(U,-val,i,j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1123,10 +1283,10 @@ Matrix<T,M> Matrix<T,M>::getSVD()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout<<"U: "<<std::endl<<U<<std::endl;
|
// std::cout<<"U: "<<std::endl<<U<<std::endl;
|
||||||
std::cout<<"S: "<<std::endl<<S<<std::endl;
|
// std::cout<<"S: "<<std::endl<<S<<std::endl;
|
||||||
std::cout<<"Start Res: "<<std::endl<<*this<<std::endl;
|
// std::cout<<"Start Res: "<<std::endl<<*this<<std::endl;
|
||||||
std::cout<<"Res: "<<std::endl<<U*S<<std::endl;
|
// std::cout<<"Res: "<<std::endl<<U*S<<std::endl;
|
||||||
ret.push_back(U);
|
ret.push_back(U);
|
||||||
ret.push_back(S);
|
ret.push_back(S);
|
||||||
ret.push_back(V);
|
ret.push_back(V);
|
||||||
@ -1156,6 +1316,22 @@ std::string Matrix<T,M>::asString(int precision, char open, char close, char sep
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
void Matrix<T,M>::print(std::ostream &os, std::string header) const
|
||||||
|
{
|
||||||
|
if(!header.empty())
|
||||||
|
std::cout<<header<<std::endl;
|
||||||
|
std::cout << *this << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
void Matrix<T,M>::raw_print(std::ostream &os, std::string header) const
|
||||||
|
{
|
||||||
|
if(!header.empty())
|
||||||
|
std::cout<<header<<std::endl;
|
||||||
|
std::cout << *this << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
Matrix<T,M> IdentityMatrix(const typename Poly::Matrix<T,M>::size_type& size)
|
Matrix<T,M> IdentityMatrix(const typename Poly::Matrix<T,M>::size_type& size)
|
||||||
{
|
{
|
||||||
@ -1186,28 +1362,16 @@ void ResetMatrix(Matrix<T,M> &matrix, T value)
|
|||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
Matrix<T,M> Transpose(const Matrix<T,M> &matrix)
|
Matrix<T,M> Transpose(const Matrix<T,M> &matrix)
|
||||||
{
|
{
|
||||||
Matrix<T,M> res(matrix.columns(),matrix.rows());
|
Matrix<T,M> res(matrix);
|
||||||
for(typename Poly::Matrix<T,M>::size_type i = 0; i < matrix.rows(); i++)
|
res.transpose_inplace();
|
||||||
{
|
|
||||||
for(typename Poly::Matrix<T,M>::size_type j = 0; j < matrix.columns(); j++)
|
|
||||||
{
|
|
||||||
res.at(j,i) = matrix.at(i,j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int M>
|
template <typename T, int M>
|
||||||
Matrix<T,M> ConjugateTranspose(const Matrix<T,M> &matrix)
|
Matrix<T,M> ConjugateTranspose(const Matrix<T,M> &matrix)
|
||||||
{
|
{
|
||||||
Matrix<T,M> res(matrix.columns(),matrix.rows());
|
Matrix<T,M> res(matrix);
|
||||||
for(typename Poly::Matrix<T,M>::size_type i = 0; i < matrix.rows(); i++)
|
res.conjugateTranspose_inplace();
|
||||||
{
|
|
||||||
for(typename Poly::Matrix<T,M>::size_type j = 0; j < matrix.columns(); j++)
|
|
||||||
{
|
|
||||||
res.at(j,i) = std::conj(matrix.at(i,j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1759,6 +1923,7 @@ EigenVecsVals(Poly::Matrix<T,M>& eigenValues,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
throw std::logic_error("The type requested is not supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1822,16 +1987,11 @@ template <typename T, int M>
|
|||||||
Poly::Matrix<std::complex<T>, M >
|
Poly::Matrix<std::complex<T>, M >
|
||||||
MatrixExp(const Poly::Matrix<std::complex<T>, M > &input_matrix, const MATRIX_TYPE &type)
|
MatrixExp(const Poly::Matrix<std::complex<T>, M > &input_matrix, const MATRIX_TYPE &type)
|
||||||
{
|
{
|
||||||
#ifdef POLYMATH_DEBUG
|
input_matrix._check_square_matrix();
|
||||||
if(input_matrix.columns() != input_matrix.rows())
|
|
||||||
{
|
|
||||||
throw std::length_error("Matrix exponential can only be taken for square matrices");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(type == Poly::MATRIX_HERMITIAN)
|
if(type == Poly::MATRIX_HERMITIAN)
|
||||||
{
|
{
|
||||||
auto input = input_matrix;
|
auto input = input_matrix;
|
||||||
Poly::Matrix<std::complex<T>, M> matrix_exp(input_matrix.rows(),input_matrix.columns(),T());
|
Poly::Matrix<std::complex<T>, M> matrix_exp(input_matrix.rows(),input_matrix.columns());
|
||||||
Poly::Matrix<T, M> eigenVals;
|
Poly::Matrix<T, M> eigenVals;
|
||||||
Poly::Matrix<std::complex<T>, M> eigenVecs;
|
Poly::Matrix<std::complex<T>, M> eigenVecs;
|
||||||
EigenVecsVals(eigenVals,eigenVecs,input,type);
|
EigenVecsVals(eigenVals,eigenVecs,input,type);
|
||||||
@ -1841,12 +2001,48 @@ MatrixExp(const Poly::Matrix<std::complex<T>, M > &input_matrix, const MATRIX_TY
|
|||||||
}
|
}
|
||||||
return eigenVecs*matrix_exp*Poly::ConjugateTranspose(eigenVecs);
|
return eigenVecs*matrix_exp*Poly::ConjugateTranspose(eigenVecs);
|
||||||
}
|
}
|
||||||
|
else if(type == Poly::MATRIX_ANTIHERMITIAN)
|
||||||
|
{
|
||||||
|
auto input = std::complex<T>(0,1)*input_matrix; //convert the matrix to Hermitian
|
||||||
|
Poly::Matrix<std::complex<T>, M> matrix_exp(input_matrix.rows(),input_matrix.columns());
|
||||||
|
Poly::Matrix<T, M> eigenVals;
|
||||||
|
Poly::Matrix<std::complex<T>, M> eigenVecs;
|
||||||
|
EigenVecsVals(eigenVals,eigenVecs,input,Poly::MATRIX_HERMITIAN);
|
||||||
|
Poly::Matrix<std::complex<T>, M> eigenValsComplex = std::complex<T>(0,-1)*eigenVals; //necessary for anti-hermitian matrices to reverse the multiplication by i in the beginning
|
||||||
|
for(long i = 0; i < matrix_exp.rows(); i++)
|
||||||
|
{
|
||||||
|
matrix_exp.at(i,i) = std::exp(eigenValsComplex[i]);
|
||||||
|
}
|
||||||
|
return eigenVecs*matrix_exp*Poly::ConjugateTranspose(eigenVecs);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::logic_error("The matrix type requested is not supported.");
|
throw std::logic_error("The matrix type requested is not supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int M>
|
||||||
|
Poly::Matrix<T, M>
|
||||||
|
KroneckerProduct(const Poly::Matrix<T, M> &mat1, const Poly::Matrix<T, M> &mat2)
|
||||||
|
{
|
||||||
|
typedef typename Poly::Matrix<T,M>::size_type size_type;
|
||||||
|
Poly::Matrix<T,M> result(mat1.rows()*mat2.rows(),mat1.columns()*mat2.columns());
|
||||||
|
|
||||||
|
for(size_type i = 0; i < mat1.rows(); i++)
|
||||||
|
{
|
||||||
|
for(size_type j = 0; j < mat1.columns(); j++)
|
||||||
|
{
|
||||||
|
for(size_type k = 0; k < mat2.rows(); k++)
|
||||||
|
{
|
||||||
|
for(size_type l = 0; l < mat2.columns(); l++)
|
||||||
|
{
|
||||||
|
result.at(mat2.rows()*i+k,mat2.columns()*j+l) = mat1.at(i,j)*mat2.at(k,l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#endif /* Matrix_H */
|
#endif /* Matrix_H */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define STDADAPTERS_H
|
#define STDADAPTERS_H
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Poly
|
namespace Poly
|
||||||
{
|
{
|
||||||
@ -12,7 +13,7 @@ class Matrix;
|
|||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
#ifndef _CONCAT
|
#ifndef _CONCAT
|
||||||
#define _CONCAT(A, B) A ## B
|
#define _CONCAT(A, B) A ## B
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _UNARY_STD_ADAPTER(func_name) \
|
#define _UNARY_STD_ADAPTER(func_name) \
|
||||||
@ -20,7 +21,7 @@ template <typename T, int M> \
|
|||||||
Poly::Matrix<T,M> func_name(const Poly::Matrix<T,M>& mat) \
|
Poly::Matrix<T,M> func_name(const Poly::Matrix<T,M>& mat) \
|
||||||
{ \
|
{ \
|
||||||
Poly::Matrix<T,M> res(mat.rows(), mat.columns()); \
|
Poly::Matrix<T,M> res(mat.rows(), mat.columns()); \
|
||||||
std::transform(mat.begin(),mat.end(),res.begin(),std::pointer_to_unary_function<T,T>(std::ceil)); \
|
std::transform(mat.begin(),mat.end(),res.begin(),std::pointer_to_unary_function<T,T>(std::func_name)); \
|
||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ Poly::Matrix<T,M> func_name(const Poly::Matrix<T,M>& mat) \
|
|||||||
template <typename T, int M> \
|
template <typename T, int M> \
|
||||||
void _CONCAT(func_name, _inplace)(Poly::Matrix<T,M>& mat) \
|
void _CONCAT(func_name, _inplace)(Poly::Matrix<T,M>& mat) \
|
||||||
{ \
|
{ \
|
||||||
std::transform(mat.begin(),mat.end(),mat.begin(),std::pointer_to_unary_function<T,T>(std::ceil)); \
|
std::transform(mat.begin(),mat.end(),mat.begin(),std::pointer_to_unary_function<T,T>(std::func_name)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _BINARY_STD_ADAPTER(func_name) \
|
#define _BINARY_STD_ADAPTER(func_name) \
|
||||||
@ -158,6 +159,7 @@ _UNARY_STD_ADAPTER(isinf)
|
|||||||
_UNARY_STD_ADAPTER(isnormal)
|
_UNARY_STD_ADAPTER(isnormal)
|
||||||
_UNARY_STD_ADAPTER(signbit)
|
_UNARY_STD_ADAPTER(signbit)
|
||||||
|
|
||||||
|
|
||||||
_UNARY_STD_ADAPTER_INPLACE(abs)
|
_UNARY_STD_ADAPTER_INPLACE(abs)
|
||||||
_UNARY_STD_ADAPTER_INPLACE(acos)
|
_UNARY_STD_ADAPTER_INPLACE(acos)
|
||||||
_UNARY_STD_ADAPTER_INPLACE(acosh)
|
_UNARY_STD_ADAPTER_INPLACE(acosh)
|
||||||
|
@ -1 +1 @@
|
|||||||
#include "StdAdapters.h"
|
#include "internal/StdAdapters.h"
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <locale>
|
#include <locale>
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
|
|
||||||
int RunTests()
|
int RunTests()
|
||||||
{
|
{
|
||||||
// Py_SetProgramName("MatricesTest"); /* optional but recommended */
|
// Py_SetProgramName("MatricesTest"); /* optional but recommended */
|
||||||
@ -44,9 +43,6 @@ int RunTests()
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int len = 3;
|
|
||||||
Poly::Matrix<double> mat_d = Poly::RandomMatrix<double>(len,len,0,10,std::random_device{}());
|
|
||||||
Poly::Matrix<double> mat_e = Poly::RandomMatrix<double>(len,len,0,10,std::random_device{}());
|
|
||||||
RunTests();
|
RunTests();
|
||||||
std::cout<<"Tests program exited with no errors."<<std::endl;
|
std::cout<<"Tests program exited with no errors."<<std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user