/* * Classes for handling matrices and vectors: * * Class mat: dense matrices/vectors * Class sparse_mat: sparse matrices * Class geometry: data for dynamic calculation of the measurement matrix * */ #ifndef CONTAINER_H_ #define CONTAINER_H_ #include #include #include #include // enumerations... enum T_alloc {allocated_in_constructor, preallocated_buffer}; enum T_mat_format {mat_col_major, mat_row_major}; enum T_sparse_mat_format {sparse_mat_csc, sparse_mat_csr}; // exceptions... class illegal_mat_assignment: public std::exception { virtual const char* what() const throw() { return "Illegale Zuweisung von mat-Objekten."; } }; class illegal_sparse_mat_assignment: public std::exception { virtual const char* what() const throw() { return "Illegale Zuweisung von sparse_mat-Objekten."; } }; //--------------------------------------- // class mat... //--------------------------------------- template class mat { private: Type *pbuf; T_alloc alloc_info; public: const int dim_y; const int dim_x; const int dim_z; const int len; const T_mat_format format; mat(int l_y, int l_x, int l_z, bool init=true, T_mat_format storage=mat_row_major); mat(int num_elements, bool init=true); mat(int l_y, int l_x, int l_z, Type *buffer, T_mat_format storage=mat_row_major); mat(int num_elements, Type *buffer); mat(const mat &m); ~mat() { if(pbuf && (alloc_info == allocated_in_constructor)) delete[] pbuf; }; Type *data() { return pbuf; } const Type *data() const { return pbuf; } Type &operator[](int i) { return pbuf[i]; } const Type &operator[](int i) const { return pbuf[i]; } mat &operator=(const mat &m) throw(illegal_mat_assignment); void randomFill(Type scl); }; //--------------------------------------- // class sparse_mat... //--------------------------------------- template class sparse_mat { private: int *p_ptr; int *p_ind; Type *p_val; T_alloc alloc_info; public: const int dim_y; const int dim_x; const int nnz; const T_sparse_mat_format format; sparse_mat(int l_y, int l_x, int n_nonzero, T_sparse_mat_format storage_format=sparse_mat_csc, bool init=true); sparse_mat(int l_y, int l_x, int n_nonzero, Type *buff_val, int *buff_ptr, int *buff_ind, T_sparse_mat_format storage_format=sparse_mat_csc); sparse_mat(const sparse_mat &m); ~sparse_mat(); Type *val() { return p_val; } const Type *val() const { return p_val; } int *ptr() { return p_ptr; } const int *ptr() const { return p_ptr; } int *ind() { return p_ind; } const int *ind() const { return p_ind; } sparse_mat &operator=(const mat &m) throw(illegal_sparse_mat_assignment); }; //--------------------------------------- // Struct geomety //--------------------------------------- struct geometry { int *x_emitters; int *y_emitters; int *z_emitters; int *x_receivers; int *y_receivers; int *z_receivers; int num_emitters; int num_receivers; int rv_x; int rv_y; int rv_z; float scale_factor; }; // ------------------------------------------------------------------------ // member functions, etc. class mat // ------------------------------------------------------------------------ template mat::mat(int l_y, int l_x, int l_z, bool init, T_mat_format storage): pbuf(NULL), alloc_info(allocated_in_constructor), dim_y(l_y), dim_x(l_x), dim_z(l_z), len(l_y*l_x*l_z), format(storage) { if(len > 0) { pbuf = new Type[len]; if(init) memset(pbuf, 0, len*sizeof(Type)); } }; template mat::mat(int num_elements, bool init): pbuf(NULL), alloc_info(allocated_in_constructor), dim_y(num_elements), dim_x(1), dim_z(1), len(num_elements), format(mat_row_major) { if(len > 0) { pbuf = new Type[len]; if(init) memset(pbuf, 0, len*sizeof(Type)); } }; template mat::mat(int l_y, int l_x, int l_z, Type *buffer, T_mat_format storage): pbuf(buffer), dim_y(l_y), dim_x(l_x), dim_z(l_z), len(l_y*l_x*l_z), alloc_info(preallocated_buffer), format(storage) {}; template mat::mat(int num_elements, Type *buffer): pbuf(buffer), dim_y(num_elements), dim_x(1), dim_z(1), len(num_elements), alloc_info(preallocated_buffer), format(mat_row_major) {}; template mat::mat(const mat &m): pbuf(NULL), alloc_info(allocated_in_constructor), dim_y(m.dim_y), dim_x(m.dim_x), dim_z(m.dim_z), len(m.len), format(m.format) { if(len > 0) { pbuf = new Type[len]; memcpy(pbuf, m.pbuf, len*sizeof(Type)); } }; template mat &mat::operator=(const mat &m) throw(illegal_mat_assignment) { if(m.len == len) memcpy(pbuf, m.pbuf, len*sizeof(Type)); else throw illegal_mat_assignment(); return *this; } template void mat::randomFill(Type scl) { for(int i=0; i std::ostream &operator<<(std::ostream &stream, const mat &m) { for(int z=0; z < m.dim_z; z++) { stream << "\nz=" << z+1 << ":\n\n"; for(int i=0; i sparse_mat::sparse_mat(int l_y, int l_x, int n_nonzero, T_sparse_mat_format storage_format, bool init): p_val(NULL), p_ptr(NULL), p_ind(NULL), dim_y(l_y), dim_x(l_x), nnz(n_nonzero), format(storage_format), alloc_info(allocated_in_constructor) { if(nnz > 0) { int len_ptr = (format == sparse_mat_csc) ? dim_x + 1 : dim_y + 1; p_val = new Type[nnz]; p_ptr = new int[len_ptr]; p_ind = new int[nnz]; if(init) { memset(p_val, 0, nnz*sizeof(Type)); memset(p_ptr, 0, (len_ptr)*sizeof(int)); memset(p_ind, 0, nnz*sizeof(int)); } } }; template sparse_mat::sparse_mat(int l_y, int l_x, int n_nonzero, Type *buff_val, int *buff_ptr, int *buff_ind, T_sparse_mat_format storage_format): p_val(buff_val), p_ptr(buff_ptr), p_ind(buff_ind), dim_y(l_y), dim_x(l_x), nnz(n_nonzero), format(storage_format), alloc_info(preallocated_buffer) {} template sparse_mat::sparse_mat(const sparse_mat &m): p_val(NULL), p_ptr(NULL), p_ind(NULL), dim_y(m.dim_y), dim_x(m.dim_x), nnz(m.nnz), format(m.format), alloc_info(allocated_in_constructor) { if(nnz > 0) { int len_ptr = (format == sparse_mat_csc) ? dim_x + 1 : dim_y + 1; p_val = new Type[nnz]; memcpy(p_val, m.p_val, nnz*sizeof(Type)); p_ptr = new int[len_ptr]; memcpy(p_ptr, m.p_ptr, (len_ptr)*sizeof(int)); p_ind = new int[nnz]; memcpy(p_ind, m.p_ind, nnz*sizeof(int)); } }; template sparse_mat::~sparse_mat() { if(alloc_info == allocated_in_constructor) { if(p_val) delete[] p_val; if(p_ptr) delete[] p_ptr; if(p_ind) delete[] p_ind; } } template sparse_mat &sparse_mat::operator=(const mat &m) throw(illegal_sparse_mat_assignment){ if(m.nnz == nnz && m.dim_y == dim_y && m.dim_x == dim_x && m.format == format) { int len_ptr = (format == sparse_mat_csc) ? dim_x + 1 : dim_y + 1; memcpy(p_val, m.p_val, nnz*sizeof(Type)); memcpy(p_ptr, m.p_ptr, (len_ptr)*sizeof(int)); memcpy(p_ind, m.p_ind, nnz*sizeof(int)); } else { throw illegal_sparse_mat_assignment(); } return *this; } // output operator ... template std::ostream &operator<<(std::ostream &stream, const sparse_mat &m) { mat tmp(m.dim_y, m.dim_x); if(m.format == sparse_mat_csc) { for(int c=0; c < m.dim_x; c++) for(int i = m.ptr()[c]; i < m.ptr()[c+1]; i++) tmp[c*m.dim_y + m.ind()[i]] = m.val()[i]; } else { for(int r=0; r < m.dim_y; r++) for(int i = m.ptr()[r]; i < m.ptr()[r+1]; i++) tmp[m.ind()[i]*m.dim_y + r] = m.val()[i]; } stream << tmp; return stream; } #endif /* CONTAINER_H_ */