28 #ifndef REMORA_TRIANGULAR_MATRIX_HPP 29 #define REMORA_TRIANGULAR_MATRIX_HPP 33 #include "detail/matrix_proxy_classes.hpp" 35 #include <boost/serialization/collection_size_type.hpp> 36 #include <boost/serialization/array.hpp> 37 #include <boost/serialization/nvp.hpp> 38 #include <boost/serialization/vector.hpp> 42 template<
class T,
class Orientation,
class TriangularType>
43 class triangular_matrix:
public matrix_container<triangular_matrix<T,Orientation,TriangularType>, cpu_tag > {
44 typedef triangular_matrix<T, Orientation,TriangularType> self_type;
45 typedef std::vector<T> array_type;
47 typedef typename array_type::value_type value_type;
48 typedef value_type const_reference;
49 typedef value_type reference;
50 typedef std::size_t size_type;
52 typedef const matrix_reference<const self_type> const_closure_type;
53 typedef matrix_reference<self_type> closure_type;
54 typedef packed_matrix_storage<T> storage_type;
55 typedef packed_matrix_storage<T const> const_storage_type;
56 typedef elementwise<packed_tag> evaluation_category;
57 typedef triangular<Orientation,TriangularType> orientation;
62 triangular_matrix():m_size(0){}
67 triangular_matrix(size_type size):m_size(size),m_data(size * (size+1)/2) {}
73 triangular_matrix(size_type size, value_type init):m_size(size),m_data(size * (size+1)/2,init) {}
78 triangular_matrix(triangular_matrix
const& m):m_size(m.m_size), m_data(m.m_data) {}
84 triangular_matrix(matrix_expression<E, cpu_tag>
const& e)
85 :m_size(e().size1()), m_data(m_size * (m_size+1)/2)
91 size_type size1()
const {
95 size_type size2()
const {
99 storage_type raw_storage(){
100 return {m_data.data(), m_data.size()};
103 const_storage_type raw_storage()
const{
104 return {m_data.data(), m_data.size()};
107 typename device_traits<cpu_tag>::queue_type& queue(){
108 return device_traits<cpu_tag>::default_queue();
116 void resize(size_type size) {
117 m_data.resize(size*(size+1)/2);
121 void resize(size_type size1, size_type size2) {
122 REMORA_SIZE_CHECK(size1 == size2);
128 std::fill(m_data.begin(), m_data.end(), value_type());
132 const_reference operator()(size_type i, size_type j)
const {
133 REMORA_SIZE_CHECK(i < size1());
134 REMORA_SIZE_CHECK(j < size2());
135 if(!orientation::non_zero(i,j))
137 REMORA_SIZE_CHECK(orientation::element(i,j,size1(),packed_tag())<m_data.size());
138 return m_data [orientation::element(i,j,size1(),packed_tag())];
142 void set_element(size_type i,size_type j, value_type t){
143 REMORA_SIZE_CHECK(i < size1());
144 REMORA_SIZE_CHECK(j < size2());
145 REMORA_SIZE_CHECK(orientation::non_zero(i,j));
146 m_data [orientation::element(i,j,size1(),packed_tag())] = t;
149 bool non_zero(size_type i,size_type j)
const{
150 REMORA_SIZE_CHECK(i < size1());
151 REMORA_SIZE_CHECK(j < size2());
152 return orientation::non_zero(i,j);
156 triangular_matrix& operator = (triangular_matrix m) {
161 triangular_matrix& operator = (matrix_container<C, cpu_tag>
const& m) {
162 REMORA_SIZE_CHECK(m().size1()==m().size2());
168 triangular_matrix& operator = (matrix_expression<E, cpu_tag>
const& e) {
169 self_type temporary(e);
175 void swap(triangular_matrix& m) {
177 m_data.swap(m.m_data);
179 friend void swap(triangular_matrix& m1, triangular_matrix& m2) {
184 template<
class TIter>
185 class major1_iterator:
186 public iterators::random_access_iterator_base<
187 major1_iterator<TIter>,
188 typename std::remove_const<T>::type,
189 iterators::packed_random_access_iterator_tag
192 std::ptrdiff_t offset(std::ptrdiff_t n)
const{
193 size_type k = m_index;
195 return (n*(2*k+n+1))/2;
199 return -(n*(2*k+n+1))/2;
203 typedef typename std::remove_const<TIter>::type value_type;
204 typedef TIter& reference;
205 typedef TIter* pointer;
209 major1_iterator(pointer arrayBegin, size_type index, size_type )
210 :m_pos(arrayBegin), m_index(index){}
213 major1_iterator(major1_iterator<U>
const& iter)
214 :m_pos(iter.m_pos), m_index(iter.m_index){}
217 major1_iterator& operator=(major1_iterator<U>
const& iter){
219 m_index = iter.m_index;
224 major1_iterator& operator ++ () {
229 major1_iterator& operator -- () {
234 major1_iterator& operator += (size_type n) {
239 major1_iterator& operator -= (size_type n) {
240 m_pos += offset(-(std::ptrdiff_t)n);
245 size_type operator - (major1_iterator<U>
const& it)
const {
246 return m_index - it.m_index;
250 reference operator*()
const {
253 reference operator [](size_type n)
const {
254 return m_pos[offset(n)];
258 size_type index()
const {
264 bool operator == (major1_iterator<U>
const& it)
const {
265 return m_index == it.m_index;
268 bool operator < (major1_iterator<U>
const& it)
const {
269 return m_index < it.m_index;
275 template<
class>
friend class major1_iterator;
278 template<
class TIter>
279 class major2_iterator:
280 public iterators::random_access_iterator_base<
281 major2_iterator<TIter>,
282 typename std::remove_const<T>::type,
283 iterators::packed_random_access_iterator_tag
286 std::ptrdiff_t offset(std::ptrdiff_t n)
const{
287 size_type k = m_size-m_index-1;
289 return (2*k*n-n*n+n)/2;
293 return -(2*k*n-n*n+n)/2;
297 typedef typename std::remove_const<TIter>::type value_type;
298 typedef TIter& reference;
299 typedef TIter* pointer;
303 major2_iterator(pointer arrayBegin, size_type index, size_type size)
304 :m_pos(arrayBegin), m_index(index), m_size(size){}
307 major2_iterator(major2_iterator<U>
const& iter)
308 :m_pos(iter.m_pos), m_index(iter.m_index), m_size(iter.m_size){}
311 major2_iterator& operator=(major2_iterator<U>
const& iter){
313 m_index = iter.m_index;
314 m_size = iter.m_size;
319 major2_iterator& operator ++ () {
321 m_pos += m_size-m_index;
324 major2_iterator& operator -- () {
325 m_pos -= m_size-m_index;
329 major2_iterator& operator += (size_type n) {
334 major2_iterator& operator -= (size_type n) {
335 m_pos += offset(-(std::ptrdiff_t)n);
340 std::ptrdiff_t operator - (major2_iterator<U>
const& it)
const {
341 return static_cast<std::ptrdiff_t
>(m_index) - static_cast<std::ptrdiff_t>(it.m_index);
345 reference operator*()
const {
348 reference operator [](size_type n)
const {
349 return m_pos[offset(n)];
353 size_type index()
const {
359 bool operator == (major2_iterator<U>
const& it)
const {
360 return m_index == it.m_index;
363 bool operator < (major2_iterator<U>
const& it)
const {
364 return m_index < it.m_index;
371 template<
class>
friend class major2_iterator;
374 typedef typename std::conditional<
375 std::is_same<Orientation,row_major>::value,
376 iterators::dense_storage_iterator<value_type,iterators::packed_random_access_iterator_tag>,
377 typename std::conditional<
378 TriangularType::is_upper,
379 major1_iterator<value_type>,
380 major2_iterator<value_type>
382 >::type row_iterator;
383 typedef typename std::conditional<
384 std::is_same<Orientation,row_major>::value,
385 typename std::conditional<
386 TriangularType::is_upper,
387 major2_iterator<value_type>,
388 major1_iterator<value_type>
390 iterators::dense_storage_iterator<value_type,iterators::packed_random_access_iterator_tag>
391 >::type column_iterator;
393 typedef typename std::conditional<
394 std::is_same<Orientation,row_major>::value,
395 iterators::dense_storage_iterator<value_type const,iterators::packed_random_access_iterator_tag>,
396 typename std::conditional<
397 TriangularType::is_upper,
398 major1_iterator<value_type const>,
399 major2_iterator<value_type const>
401 >::type const_row_iterator;
402 typedef typename std::conditional<
403 std::is_same<Orientation,row_major>::value,
404 typename std::conditional<
405 TriangularType::is_upper,
406 major2_iterator<value_type const>,
407 major1_iterator<value_type const>
409 iterators::dense_storage_iterator<value_type const,iterators::packed_random_access_iterator_tag>
410 >::type const_column_iterator;
414 const_row_iterator row_begin(size_type i)
const {
415 size_type index = TriangularType::is_upper?i:0;
416 return const_row_iterator(
417 m_data.data()+orientation::element(i,index,size1(),packed_tag())
419 ,orientation::orientation::stride2(size1(),size2())
422 const_row_iterator row_end(size_type i)
const {
423 size_type index = TriangularType::is_upper?size2():i+1;
424 return const_row_iterator(
425 m_data.data() + orientation::element(i, index, size1(),packed_tag())
427 ,orientation::orientation::stride2(size1(),size2())
430 row_iterator row_begin(size_type i){
431 size_type index = TriangularType::is_upper?i:0;
433 m_data.data() + orientation::element(i, index, size1(),packed_tag())
435 ,orientation::orientation::stride2(size1(),size2())
438 row_iterator row_end(size_type i){
439 size_type index = TriangularType::is_upper?size2():i+1;
441 m_data.data() + orientation::element(i, index, size1(),packed_tag())
443 ,orientation::orientation::stride2(size1(),size2())
447 const_column_iterator column_begin(size_type i)
const {
448 size_type index = TriangularType::is_upper?0:i;
449 return const_column_iterator(
450 m_data.data() + orientation::element(index, i, size1(),packed_tag())
452 ,orientation::orientation::stride1(size1(),size2())
455 const_column_iterator column_end(size_type i)
const {
456 size_type index = TriangularType::is_upper?i+1:size2();
457 return const_column_iterator(
458 m_data.data() + orientation::element(index, i, size1(),packed_tag())
460 ,orientation::orientation::stride1(size1(),size2())
463 column_iterator column_begin(size_type i){
464 size_type index = TriangularType::is_upper?0:i;
465 return column_iterator(
466 m_data.data() + orientation::element(index, i, size1(),packed_tag())
468 ,orientation::orientation::stride1(size1(),size2())
471 column_iterator column_end(size_type i){
472 size_type index = TriangularType::is_upper?i+1:size2();
473 return column_iterator(
474 m_data.data() + orientation::element(index, i, size1(),packed_tag())
476 ,orientation::orientation::stride1(size1(),size2())
481 template<
class Archive>
482 void serialize(Archive& ar,
const unsigned int ) {
483 boost::serialization::collection_size_type s(m_size);
486 ar & boost::serialization::make_nvp(
"size",s);
489 if (Archive::is_loading::value) {
492 ar & boost::serialization::make_nvp(
"data",m_data);
500 template<
class T,
class Orientation,
class TriangularType>
501 struct const_expression<triangular_matrix<T,Orientation, TriangularType> >{
502 typedef triangular_matrix<T,Orientation, TriangularType>
const type;
504 template<
class T,
class Orientation,
class TriangularType>
505 struct const_expression<triangular_matrix<T,Orientation, TriangularType> const>{
506 typedef triangular_matrix<T,Orientation, TriangularType>
const type;
509 template<
class T,
class Orientation,
class TriangularType>
510 struct matrix_temporary_type<T,triangular<Orientation, TriangularType >,packed_tag, cpu_tag> {
511 typedef triangular_matrix<T,Orientation, TriangularType> type;