00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_BASE_SUB_MATRIX_INCLUDE
00013 #define MTL_BASE_SUB_MATRIX_INCLUDE
00014
00015 #include <algorithm>
00016 #include <boost/static_assert.hpp>
00017 #include <boost/numeric/mtl/matrix/dimension.hpp>
00018 #include <boost/numeric/mtl/detail/index.hpp>
00019 #include <boost/numeric/mtl/utility/exception.hpp>
00020
00021 namespace mtl { namespace matrix {
00022
00023
00024
00025
00026 template <class Elt, class Parameters>
00027 struct base_sub_matrix
00028 {
00029 typedef Elt value_type;
00030 typedef typename Parameters::orientation orientation;
00031 typedef typename Parameters::index index_type;
00032 typedef typename Parameters::dimensions dim_type;
00033 static bool const on_stack= Parameters::on_stack;
00034 typedef std::size_t size_type;
00035 typedef base_sub_matrix self;
00036
00037 protected:
00038 size_type my_nnz,
00039 my_begin_row, my_end_row,
00040 my_begin_col, my_end_col;
00041
00042 void constructor_helper(const dim_type& dim)
00043 {
00044 my_begin_row= index::change_to(index_type(), 0);
00045 my_end_row= index::change_to(index_type(), dim.num_rows());
00046 my_begin_col= index::change_to(index_type(), 0);
00047 my_end_col= index::change_to(index_type(), dim.num_cols());
00048 my_nnz= 0;
00049 }
00050
00051 public:
00052
00053
00054 base_sub_matrix()
00055 {
00056
00057 constructor_helper(dim_type());
00058 }
00059
00060 explicit base_sub_matrix(const dim_type& d)
00061
00062 {
00063 constructor_helper(d);
00064 }
00065
00066 friend void swap(self& x, self& y)
00067 {
00068 std::swap(x.my_nnz, y.my_nnz);
00069 std::swap(x.my_begin_row, y.my_begin_row);
00070 std::swap(x.my_end_row, y.my_end_row);
00071 std::swap(x.my_begin_col, y.my_begin_col);
00072 std::swap(x.my_end_col, y.my_end_col);
00073 }
00074
00075
00076 void check_dim(size_type num_rows, size_type num_cols) const
00077 {
00078 MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0
00079 && (this->num_rows() != num_rows || this->num_cols() != num_cols),
00080 incompatible_size());
00081 }
00082
00083 protected:
00084 void change_dim(non_fixed::dimensions d) { constructor_helper(d); }
00085 template <std::size_t Rows, std::size_t Cols>
00086 void change_dim(fixed::dimensions<Rows, Cols> d) { check_dim(d.num_rows(), d.num_cols()); }
00087
00088
00089
00090 void change_dim(size_type r, size_type c) { change_dim(dim_type(r, c)); }
00091
00092 void set_ranges(size_type br, size_type er, size_type bc, size_type ec)
00093 {
00094 MTL_DEBUG_THROW_IF(br > er, range_error("begin row > end row"));
00095 MTL_DEBUG_THROW_IF(bc > ec, range_error("begin column > end column"));
00096 my_begin_row= br; my_end_row= er; my_begin_col= bc; my_end_col= ec;
00097 }
00098
00099 public:
00100 void check_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) const
00101 {
00102 MTL_DEBUG_THROW_IF(begin_r < begin_row(), range_error("begin_row out of range"));
00103
00104 MTL_DEBUG_THROW_IF(end_r > end_row(), range_error("end_row out of range"));
00105
00106 MTL_DEBUG_THROW_IF(begin_c < begin_col(), range_error("begin_col out of range"));
00107 MTL_DEBUG_THROW_IF(end_c > end_col(), range_error("end_col out of range"));
00108 }
00109
00110 explicit base_sub_matrix(size_type br, size_type er, size_type bc, size_type ec) : my_nnz(0)
00111 {
00112 set_ranges(br, er, bc, ec);
00113 }
00114
00115
00116 size_type num_rows() const
00117 {
00118 return my_end_row - my_begin_row;
00119 }
00120
00121
00122 size_type begin_row() const
00123 {
00124 return my_begin_row;
00125 }
00126
00127
00128 size_type end_row() const
00129 {
00130 return my_end_row;
00131 }
00132
00133
00134 size_type num_cols() const
00135 {
00136 return my_end_col - my_begin_col;
00137 }
00138
00139
00140 size_type begin_col() const
00141 {
00142 return my_begin_col;
00143 }
00144
00145
00146 size_type end_col() const
00147 {
00148 return my_end_col;
00149 }
00150
00151
00152 size_type nnz() const
00153 {
00154 return my_nnz;
00155 }
00156
00157 protected:
00158
00159 size_type dim1(row_major) const
00160 {
00161 return num_rows();
00162 }
00163
00164 size_type dim1(col_major) const
00165 {
00166 return num_cols();
00167 }
00168
00169
00170 size_type dim2(row_major) const
00171 {
00172 return num_cols();
00173 }
00174
00175 size_type dim2(col_major) const
00176 {
00177 return num_rows();
00178 }
00179
00180
00181
00182 size_type major_(size_type r, size_type, row_major) const
00183 {
00184 return r;
00185 }
00186
00187 size_type major_(size_type, size_type c, col_major) const
00188 {
00189 return c;
00190 }
00191
00192 public:
00193
00194 size_type dim1() const
00195 {
00196 return dim1(orientation());
00197 }
00198
00199
00200 size_type dim2() const
00201 {
00202 return dim2(orientation());
00203 }
00204
00205
00206
00207 size_type major_(size_type r, size_type c) const
00208 {
00209 return major_(r, c, orientation());
00210 }
00211
00212
00213
00214 size_type minor_(size_type r, size_type c) const
00215 {
00216 return major_(c, r, orientation());
00217 }
00218
00219 dim_type get_dimensions() const
00220 {
00221 return dim_type(num_rows(), num_cols());
00222 }
00223
00224 };
00225
00226
00227 }}
00228
00229 #endif // MTL_BASE_SUB_MATRIX_INCLUDE
00230
00231
00232
00233
00234
00235