You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
6.7 KiB
299 lines
6.7 KiB
/*! @file |
|
|
|
@id $Id$ |
|
*/ |
|
// 1 2 3 4 5 6 7 8 |
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
|
|
#include <iostream> |
|
#include <cstring> |
|
#include <cassert> |
|
#include <type_traits> |
|
|
|
#define LOG std::cout<<__PRETTY_FUNCTION__<<std::endl |
|
|
|
template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix { |
|
|
|
//........................................................const.variables |
|
protected: |
|
|
|
static const size_t SIZE = ROWS*COLUMNS; |
|
static const size_t MEM_SIZE = ROWS*COLUMNS*sizeof(T); |
|
|
|
//...............................................................typedefs |
|
public: |
|
|
|
/// @name Auxiliary Classes |
|
///{ |
|
|
|
/// Return One Row as Vector, internally used for element access |
|
/** Only used to access values: |
|
|
|
@code |
|
Matrix<int,4,4> m; |
|
m[2][2] = 1; |
|
@endcode */ |
|
class RowVector { |
|
public: |
|
T& operator[](size_t column) { |
|
return _v[column]; |
|
} |
|
protected: |
|
friend class Matrix; |
|
RowVector() = delete; // forbidden |
|
RowVector(T c[COLUMNS]): _v(c) {} |
|
T *_v; |
|
}; |
|
|
|
/// Same as RowVector, but in a constant environment. |
|
class ConstRowVector { |
|
public: |
|
const T& operator[](size_t column) const { |
|
return _v[column]; |
|
} |
|
protected: |
|
friend class Matrix; |
|
ConstRowVector() = delete; // forbidden |
|
ConstRowVector(const T c[COLUMNS]): _v(c) {} |
|
const T *_v; |
|
}; |
|
|
|
///} |
|
|
|
//................................................................methods |
|
public: |
|
|
|
/// @name construction |
|
///{ |
|
|
|
Matrix() { |
|
LOG; |
|
memset(_c, 0, MEM_SIZE); |
|
} |
|
|
|
template<typename ...ARGS> |
|
Matrix(ARGS...t): _c{std::forward<T>(t)...} { |
|
LOG; |
|
static_assert(sizeof...(t)==SIZE, "variadic matrix initialisation requires correct array size"); |
|
} |
|
|
|
Matrix(const Matrix& o) { |
|
LOG; |
|
memcpy(_c, o._c, MEM_SIZE); |
|
} |
|
|
|
///} |
|
|
|
/// @name operators |
|
///{ |
|
|
|
Matrix& operator=(T oc[ROWS][COLUMNS]) { |
|
LOG; |
|
memcpy(_c, oc, MEM_SIZE); |
|
return *this; |
|
} |
|
|
|
Matrix& operator=(const Matrix& o) { |
|
LOG; |
|
memcpy(_c, o._c, MEM_SIZE); |
|
return *this; |
|
} |
|
|
|
Matrix& operator+=(const Matrix& o) { |
|
LOG; |
|
T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE); |
|
while (to>(T*)(_c)) *--to += *--from; |
|
return *this; |
|
} |
|
|
|
RowVector operator[](size_t row) { |
|
return RowVector(_c[row]); |
|
} |
|
|
|
const ConstRowVector operator[](size_t row) const { |
|
return ConstRowVector(_c[row]); |
|
} |
|
|
|
///} |
|
|
|
//..............................................................variables |
|
protected: |
|
|
|
T _c[ROWS][COLUMNS]; |
|
|
|
}; |
|
|
|
template<typename T> class Matrix<T, 0, 0> { |
|
|
|
//..............................................................constants |
|
public: |
|
|
|
const size_t ROWS; |
|
const size_t COLUMNS; |
|
const size_t SIZE; |
|
const size_t MEM_SIZE; |
|
|
|
//...............................................................typedefs |
|
public: |
|
|
|
/// @name Auxiliary Classes |
|
///{ |
|
|
|
/// Return One Row as Vector, internally used for element access |
|
/** Only used to access values: |
|
|
|
@code |
|
Matrix<int,4,4> m; |
|
m[2][2] = 1; |
|
@endcode */ |
|
class RowVector { |
|
public: |
|
T& operator[](size_t column) { |
|
assert(column<_m.COLUMNS); |
|
return _v[column]; |
|
} |
|
protected: |
|
friend class Matrix; |
|
RowVector() = delete; // forbidden |
|
RowVector(const Matrix& m, T c[]): _m(m), _v(c) {} |
|
const Matrix& _m; |
|
T *_v; |
|
}; |
|
|
|
/// Same as RowVector, but in a constant environment. |
|
class ConstRowVector { |
|
public: |
|
const T& operator[](size_t column) const { |
|
assert(column<_m.COLUMNS); |
|
return _v[column]; |
|
} |
|
protected: |
|
friend class Matrix; |
|
ConstRowVector() = delete; // forbidden |
|
ConstRowVector(const Matrix& m, const T c[]): _m(m), _v(c) {} |
|
const Matrix& _m; |
|
const T *_v; |
|
}; |
|
|
|
///} |
|
|
|
//................................................................methods |
|
public: |
|
|
|
/// @name construction |
|
///{ |
|
|
|
Matrix(size_t rows, size_t columns): |
|
ROWS(rows), |
|
COLUMNS(columns), |
|
SIZE(rows*columns), |
|
MEM_SIZE(rows*columns*sizeof(T)), |
|
_c(new T[rows*columns]) { |
|
LOG; |
|
memset(_c, 0, MEM_SIZE); |
|
} |
|
|
|
template<typename ...ARGS> |
|
Matrix(size_t rows, size_t columns, ARGS...t): |
|
Matrix(rows, columns) { |
|
LOG; |
|
assert(sizeof...(t)==SIZE); |
|
copy_args(_c, t...); |
|
} |
|
|
|
Matrix(const Matrix& o): Matrix(o.ROWS, o.COLUMNS) { |
|
LOG; |
|
memcpy(_c, o._c, MEM_SIZE); |
|
} |
|
|
|
///} |
|
|
|
/// @name destruction |
|
///{ |
|
|
|
~Matrix() { |
|
delete[] _c; |
|
} |
|
|
|
///} |
|
|
|
/// @name operators |
|
///{ |
|
|
|
Matrix& operator=(T oc[]) { |
|
LOG; |
|
assert(sizeof(oc)==MEM_SIZE); |
|
memcpy(_c, oc, MEM_SIZE); |
|
return *this; |
|
} |
|
|
|
Matrix& operator=(const Matrix& o) { |
|
LOG; |
|
if (o.ROWS!=ROWS&&o.COLUMNS!=COLUMNS) { |
|
delete[] _c; |
|
ROWS = o.ROWS; |
|
COLUMNS = o.COLUMNS; |
|
SIZE = o.SIZE; |
|
MEM_SIZE = o.MEM_SIZE; |
|
_c = new T[SIZE]; |
|
} |
|
memcpy(_c, o._c, MEM_SIZE); |
|
return *this; |
|
} |
|
|
|
Matrix& operator+=(const Matrix& o) { |
|
LOG; |
|
assert(o.ROWS==ROWS); |
|
assert(o.COLUMNS==COLUMNS); |
|
T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE); |
|
while (to>(T*)(_c)) *--to += *--from; |
|
return *this; |
|
} |
|
|
|
RowVector operator[](size_t row) { |
|
assert(row<ROWS); |
|
return RowVector(*this, _c+row*COLUMNS); |
|
} |
|
|
|
const ConstRowVector operator[](size_t row) const { |
|
assert(row<ROWS); |
|
return ConstRowVector(*this, _c+row*COLUMNS); |
|
} |
|
|
|
///} |
|
|
|
//................................................................methods |
|
protected: |
|
|
|
void copy_args(T*) {} |
|
template<typename ...ARGS> |
|
void copy_args(T* to, T t1, ARGS...t) { |
|
*to = t1; |
|
copy_args(++to, t...); |
|
} |
|
|
|
//..............................................................variables |
|
protected: |
|
|
|
T* _c; |
|
|
|
}; |
|
|
|
template<typename T, size_t ROWS, size_t COLUMNS> |
|
Matrix<T, ROWS, COLUMNS> operator+(const Matrix<T, ROWS, COLUMNS>& m1, const Matrix<T, ROWS, COLUMNS>& m2) { |
|
LOG; |
|
Matrix<T, ROWS, COLUMNS> res(m1); |
|
return res+=m2; |
|
} |
|
|
|
template<typename T, size_t ROWS, size_t COLUMNS> |
|
std::ostream& operator<<(std::ostream& s, const Matrix<T, ROWS, COLUMNS>& m) { |
|
LOG; |
|
for (size_t w = 0; w < m.ROWS; ++w) { |
|
for (size_t h = 0; h < m.COLUMNS;++h) { |
|
s<<m[w][h]<<' '; |
|
} |
|
s<<'\n'; |
|
} |
|
} |
|
|
|
|