/** * This is a highly inefficient math library. It was conceived by Martin * Felis while he was compiling code * that uses a highly efficient math library. * * It is intended to be used as a fast compiling substitute for the * blazingly fast Eigen3 library and tries to mimic its API to a certain * extend. * * Feel free to use it wherever you like. However, no guarantees are given * that this code does what it says it would. */ #ifndef SIMPLEMATHBLOCK_H #define SIMPLEMATHBLOCK_H #include #include #include #include #include "compileassert.h" // #include "SimpleMathQR.h" /** \brief Namespace for a highly inefficient math library * */ namespace SimpleMath { /** \brief Namespace for fixed size elements */ // forward declaration template class Matrix; template class Block { public: typedef val_type value_type; Block() : mParentRows(0), mParentCols(0), mParentRowStart(0), mParentColStart(0) { } Block (const matrix_type &matrix, const unsigned int row_start, const unsigned int col_start, const unsigned int row_count, const unsigned int col_count) : mParentRows (matrix.rows()), mParentCols (matrix.cols()), mParentRowStart (row_start), mParentColStart (col_start), mRowCount (row_count), mColCount (col_count), mTransposed (false) { assert (mParentRows >= mParentRowStart + mRowCount); assert (mParentCols >= mParentColStart + mColCount); // without the following line we could not create blocks from const // matrices mParentMatrix = const_cast(&matrix); } // copy data from the other block into this Block& operator=(const Block &other) { if (this != &other) { if (mRowCount != other.rows() || mColCount != other.cols()) { std::cerr << "Error: cannot assign blocks of different size (left is " << mRowCount << "x" << mColCount << " right is " << other.rows() << "x" << other.cols() << ")!" << std::endl; abort(); } value_type* temp_values = new value_type [mRowCount * mColCount]; for (unsigned int i = 0; i < mRowCount; i++) { for (unsigned int j = 0; j < mColCount; j++) { temp_values[i * mColCount + j] = static_cast(other(i,j)); } } for (unsigned int i = 0; i < mRowCount; i++) { for (unsigned int j = 0; j < mColCount; j++) { (*this)(i,j) = temp_values[i * mColCount + j]; } } delete[] temp_values; } return *this; } template // copy data from the other block into this Block& operator=(const other_matrix_type &other) { if (mRowCount != other.rows() || mColCount != other.cols()) { std::cerr << "Error: cannot assign blocks of different size (left is " << mRowCount << "x" << mColCount << " right is " << other.rows() << "x" << other.cols() << ")!" << std::endl; abort(); } value_type *temp_values = new value_type[mRowCount * mColCount]; for (unsigned int i = 0; i < mRowCount; i++) { for (unsigned int j = 0; j < mColCount; j++) { temp_values[i * mColCount + j] = static_cast(other(i,j)); } } for (unsigned int i = 0; i < mRowCount; i++) { for (unsigned int j = 0; j < mColCount; j++) { (*this)(i,j) = temp_values[i * mColCount + j]; } } delete[] temp_values; return *this; } unsigned int rows() const { if (!mTransposed) return mRowCount; return mColCount; } unsigned int cols() const { if (!mTransposed) return mColCount; return mRowCount; } const val_type& operator() (const unsigned int i, const unsigned int j) const { if (!mTransposed) { assert (i < mRowCount); assert (j < mColCount); return (*mParentMatrix) (i + mParentRowStart, j + mParentColStart); } return (*mParentMatrix) (j + mParentRowStart, i + mParentColStart); } val_type& operator() (const unsigned int i, const unsigned int j) { if (!mTransposed) { assert (i < mRowCount); assert (j < mColCount); return (*mParentMatrix) (i + mParentRowStart, j + mParentColStart); } assert (j < mRowCount); assert (i < mColCount); return (*mParentMatrix) (j + mParentRowStart, i + mParentColStart); } Block transpose() const { Block result (*this); result.mTransposed = mTransposed ^ true; return result; } private: matrix_type *mParentMatrix; const unsigned int mParentRows; const unsigned int mParentCols; const unsigned int mParentRowStart; const unsigned int mParentColStart; const unsigned int mRowCount; const unsigned int mColCount; bool mTransposed; }; template inline std::ostream& operator<<(std::ostream& output, const Block &block) { unsigned int i,j; for (i = 0; i < block.rows(); i++) { output << "[ "; for (j = 0; j < block.cols(); j++) { output << block(i,j); if (j < block.cols() - 1) output << ", "; } output << " ]"; if (block.rows() > 1 && i < block.rows() - 1) output << std::endl; } return output; } } #endif /* SIMPLEMATHBLOCK_H */