28 #ifndef REMORA_CPU_MATRIX_HPP 29 #define REMORA_CPU_MATRIX_HPP 31 #include "../detail/matrix_proxy_classes.hpp" 32 #include <initializer_list> 33 #include <boost/serialization/collection_size_type.hpp> 34 #include <boost/serialization/array.hpp> 35 #include <boost/serialization/nvp.hpp> 36 #include <boost/serialization/vector.hpp> 52 template<
class T,
class L>
53 class matrix<T,L,cpu_tag>:
public matrix_container<matrix<T, L, cpu_tag>, cpu_tag > {
54 typedef matrix<T, L> self_type;
55 typedef std::vector<T> array_type;
57 typedef typename array_type::value_type value_type;
58 typedef typename array_type::const_reference const_reference;
59 typedef typename array_type::reference reference;
60 typedef typename array_type::size_type size_type;
62 typedef matrix_reference<self_type const> const_closure_type;
63 typedef matrix_reference<self_type> closure_type;
64 typedef dense_matrix_storage<T, continuous_dense_tag> storage_type;
65 typedef dense_matrix_storage<T const, continuous_dense_tag> const_storage_type;
66 typedef elementwise<dense_tag> evaluation_category;
67 typedef L orientation;
72 matrix():m_size1(0), m_size2(0){}
78 matrix(std::initializer_list<std::initializer_list<T> > list)
79 : m_size1(list.size())
80 , m_size2(list.begin()->size())
81 , m_data(m_size1*m_size2){
82 auto pos = list.begin();
83 for(std::size_t i = 0; i != list.size(); ++i,++pos){
84 REMORA_SIZE_CHECK(pos->size() == m_size2);
85 std::copy(pos->begin(),pos->end(),row_begin(i));
92 matrix(size_type size1, size_type size2)
95 , m_data(size1 * size2) {}
101 matrix(size_type size1, size_type size2, value_type
const& init)
104 , m_data(size1 * size2, init) {}
108 matrix(matrix
const& m) =
default;
113 matrix(matrix&& m):m_size1(m.m_size1), m_size2(m.m_size2), m_data(
std::move(m.m_data)){}
122 matrix(matrix_expression<E, cpu_tag>
const& e)
123 : m_size1(e().size1())
124 , m_size2(e().size2())
125 , m_data(m_size1 * m_size2) {
132 matrix& operator = (matrix
const& m) =
default;
136 matrix& operator = (matrix&& m) {
139 m_data = std::move(m.m_data);
152 matrix& operator = (matrix_container<C, cpu_tag>
const& m) {
153 resize(m().size1(), m().size2());
165 matrix& operator = (matrix_expression<E, cpu_tag>
const& e) {
166 self_type temporary(e);
172 size_type size1()
const {
176 size_type size2()
const {
181 storage_type raw_storage(){
182 return {m_data.data(), orientation::index_m(m_size1,m_size2)};
186 const_storage_type raw_storage()
const{
187 return {m_data.data(), orientation::index_m(m_size1,m_size2)};
189 typename device_traits<cpu_tag>::queue_type& queue(){
190 return device_traits<cpu_tag>::default_queue();
201 void resize(size_type size1, size_type size2) {
202 m_data.resize(size1* size2);
208 std::fill(m_data.begin(), m_data.end(), value_type());
212 const_reference operator()(size_type i, size_type j)
const {
213 REMORA_SIZE_CHECK(i < size1());
214 REMORA_SIZE_CHECK(j < size2());
215 return m_data[orientation::element(i, m_size1, j, m_size2)];
217 reference operator()(size_type i, size_type j) {
218 REMORA_SIZE_CHECK(i < size1());
219 REMORA_SIZE_CHECK(j < size2());
220 return m_data[orientation::element(i, m_size1, j, m_size2)];
223 void set_element(size_type i, size_type j,value_type t){
224 REMORA_SIZE_CHECK(i < size1());
225 REMORA_SIZE_CHECK(j < size2());
226 m_data[orientation::element(i, m_size1, j, m_size2)] = t;
230 void swap(matrix& m) {
233 m_data.swap(m.m_data);
235 friend void swap(matrix& m1, matrix& m2) {
239 friend void swap_rows(matrix& a, size_type i, matrix& b, size_type j){
240 REMORA_SIZE_CHECK(i < a.size1());
241 REMORA_SIZE_CHECK(j < b.size1());
242 REMORA_SIZE_CHECK(a.size2() == b.size2());
243 for(std::size_t k = 0; k != a.size2(); ++k){
248 void swap_rows(size_type i, size_type j) {
250 for(std::size_t k = 0; k != size2(); ++k){
256 friend void swap_columns(matrix& a, size_type i, matrix& b, size_type j){
257 REMORA_SIZE_CHECK(i < a.size2());
258 REMORA_SIZE_CHECK(j < b.size2());
259 REMORA_SIZE_CHECK(a.size1() == b.size1());
260 for(std::size_t k = 0; k != a.size1(); ++k){
265 void swap_columns(size_type i, size_type j) {
267 for(std::size_t k = 0; k != size1(); ++k){
273 typedef iterators::dense_storage_iterator<value_type> row_iterator;
274 typedef iterators::dense_storage_iterator<value_type> column_iterator;
275 typedef iterators::dense_storage_iterator<value_type const> const_row_iterator;
276 typedef iterators::dense_storage_iterator<value_type const> const_column_iterator;
278 const_row_iterator row_begin(size_type i)
const {
279 return const_row_iterator(m_data.data() + i*stride1(),0,stride2());
281 const_row_iterator row_end(size_type i)
const {
282 return const_row_iterator(m_data.data() + i*stride1()+stride2()*size2(),size2(),stride2());
284 row_iterator row_begin(size_type i){
285 return row_iterator(m_data.data() + i*stride1(),0,stride2());
287 row_iterator row_end(size_type i){
288 return row_iterator(m_data.data() + i*stride1()+stride2()*size2(),size2(),stride2());
291 const_row_iterator column_begin(std::size_t j)
const {
292 return const_column_iterator(m_data.data() + j*stride2(),0,stride1());
294 const_column_iterator column_end(std::size_t j)
const {
295 return const_column_iterator(m_data.data() + j*stride2()+ stride1()*size1(),size1(),stride1());
297 column_iterator column_begin(std::size_t j){
298 return column_iterator(m_data.data() + j*stride2(),0,stride1());
300 column_iterator column_end(std::size_t j){
301 return column_iterator(m_data.data() + j * stride2()+ stride1() * size1(), size1(), stride1());
304 typedef typename major_iterator<self_type>::type major_iterator;
307 major_iterator set_element(major_iterator pos, size_type index, value_type value) {
308 REMORA_RANGE_CHECK(pos.index() == index);
313 major_iterator clear_element(major_iterator elem) {
314 *elem = value_type();
318 major_iterator clear_range(major_iterator start, major_iterator end) {
319 std::fill(start,end,value_type());
323 void reserve(size_type non_zeros) {}
324 void reserve_row(std::size_t, std::size_t){}
325 void reserve_column(std::size_t, std::size_t){}
328 template<
class Archive>
329 void serialize(Archive& ar,
const unsigned int ) {
333 boost::serialization::collection_size_type s1(m_size1);
334 boost::serialization::collection_size_type s2(m_size2);
337 ar& boost::serialization::make_nvp(
"size1",s1)
338 & boost::serialization::make_nvp(
"size2",s2);
341 if (Archive::is_loading::value) {
345 ar& boost::serialization::make_nvp(
"data",m_data);
349 size_type stride1()
const {
350 return orientation::stride1(m_size1, m_size2);
352 size_type stride2()
const {
353 return orientation::stride2(m_size1, m_size2);
360 template<
class T,
class L>
361 struct matrix_temporary_type<T,L,dense_tag, cpu_tag>{
362 typedef matrix<T,L> type;
366 struct matrix_temporary_type<T,unknown_orientation,dense_tag, cpu_tag>{
367 typedef matrix<T,row_major> type;