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