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>
42template<
class T,
class Orientation,
class TriangularType>
43class 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) {
176 std::swap(m_size, m.m_size);
177 m_data.swap(m.m_data);
179 friend void swap(triangular_matrix& m1, triangular_matrix& m2) {
182 typedef iterators::dense_storage_iterator<value_type,iterators::packed_random_access_iterator_tag> major_iterator;
183 typedef iterators::dense_storage_iterator<value_type const,iterators::packed_random_access_iterator_tag> const_major_iterator;
185 const_major_iterator major_begin(size_type i)
const {
186 bool is_row_major = std::is_same<Orientation, row_major>::value;
187 size_typ index = (TriangularType::is_upper == is_row_major)?i:0;
188 return const_major_iterator(m_data.data() + triangular<row_major,TriangularType>::element(i,index,major_size(*
this),packed_tag()),index,1);
190 const_major_iterator major_end(size_type i)
const {
191 bool is_row_major = std::is_same<Orientation, row_major>::value;
192 size_type index = (TriangularType::is_upper == is_row_major)? minor_size(): i + 1;
193 return const_major_iterator(m_data.data() + triangular<row_major,TriangularType>::element(i, index, major_size(*
this),packed_tag()),index,1);
195 major_iterator major_begin(size_type i){
196 bool is_row_major = std::is_same<Orientation, row_major>::value;
197 size_typ index = (TriangularType::is_upper == is_row_major)?i:0;
198 return major_iterator(m_data.data() + triangular<row_major,TriangularType>::element(i, index, major_size(*
this),packed_tag()),index,1);
200 major_iterator major_end(size_type i){
201 bool is_row_major = std::is_same<Orientation, row_major>::value;
202 size_type index = (TriangularType::is_upper == is_row_major)? minor_size(): i + 1;
203 return major_iterator(m_data.data() + triangular<row_major,TriangularType>::element(i, index, major_size(*
this),packed_tag()),index,1);
207 template<
class Archive>
208 void serialize(Archive& ar,
const unsigned int ) {
209 boost::serialization::collection_size_type s(m_size);
212 ar & boost::serialization::make_nvp(
"size",s);
215 if (Archive::is_loading::value) {
218 ar & boost::serialization::make_nvp(
"data",m_data);
226template<
class T,
class Orientation,
class TriangularType>
227struct matrix_temporary_type<T,triangular<Orientation, TriangularType >,packed_tag, cpu_tag> {
228 typedef triangular_matrix<T,Orientation, TriangularType> type;