38 #ifndef GMM_SUB_MATRIX_H__
39 #define GMM_SUB_MATRIX_H__
49 template <
typename PT,
typename SUBI1,
typename SUBI2>
50 struct gen_sub_row_matrix {
51 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
52 typedef typename std::iterator_traits<PT>::value_type M;
54 typedef typename std::iterator_traits<PT>::reference ref_M;
55 typedef typename select_ref<typename linalg_traits<M>
56 ::const_row_iterator,
typename linalg_traits<M>::row_iterator,
57 PT>::ref_type iterator;
58 typedef typename linalg_traits<this_type>::reference reference;
59 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
67 {
return linalg_traits<M>::access(begin_ + si1.index(i), si2.index(j)); }
69 size_type nrows(
void)
const {
return si1.size(); }
70 size_type ncols(
void)
const {
return si2.size(); }
72 gen_sub_row_matrix(ref_M m,
const SUBI1 &s1,
const SUBI2 &s2)
73 : si1(s1), si2(s2), begin_(mat_row_begin(m)),
74 origin(linalg_origin(m)) {}
75 gen_sub_row_matrix() {}
76 gen_sub_row_matrix(
const gen_sub_row_matrix<CPT, SUBI1, SUBI2> &cr) :
77 si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
80 template <
typename PT,
typename SUBI1,
typename SUBI2>
81 struct gen_sub_row_matrix_iterator {
82 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
83 typedef typename modifiable_pointer<PT>::pointer MPT;
84 typedef typename std::iterator_traits<PT>::value_type M;
85 typedef typename select_ref<typename linalg_traits<M>
86 ::const_row_iterator,
typename linalg_traits<M>::row_iterator,
88 typedef ITER value_type;
89 typedef ITER *pointer;
90 typedef ITER &reference;
91 typedef ptrdiff_t difference_type;
93 typedef std::random_access_iterator_tag iterator_category;
94 typedef gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2> iterator;
101 iterator operator ++(
int) { iterator tmp = *
this; ii++;
return tmp; }
102 iterator operator --(
int) { iterator tmp = *
this; ii--;
return tmp; }
103 iterator &operator ++() { ii++;
return *
this; }
104 iterator &operator --() { ii--;
return *
this; }
105 iterator &operator +=(difference_type i) { ii += i;
return *
this; }
106 iterator &operator -=(difference_type i) { ii -= i;
return *
this; }
108 { iterator itt = *
this;
return (itt += i); }
110 { iterator itt = *
this;
return (itt -= i); }
111 difference_type
operator -(
const iterator &i)
const {
return ii - i.ii; }
113 ITER operator *()
const {
return it + si1.index(ii); }
114 ITER operator [](
int i) {
return it + si1.index(ii+i); }
116 bool operator ==(
const iterator &i)
const {
return (ii == i.ii); }
117 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
118 bool operator < (
const iterator &i)
const {
return (ii < i.ii); }
120 gen_sub_row_matrix_iterator(
void) {}
121 gen_sub_row_matrix_iterator(
const
122 gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
123 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
124 gen_sub_row_matrix_iterator(
const ITER &iter,
const SUBI1 &s1,
126 : it(iter), si1(s1), si2(s2), ii(i) { }
130 template <
typename PT,
typename SUBI1,
typename SUBI2>
131 struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
132 typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
133 typedef typename std::iterator_traits<PT>::value_type M;
134 typedef typename which_reference<PT>::is_reference is_reference;
135 typedef abstract_matrix linalg_type;
136 typedef typename linalg_traits<M>::origin_type origin_type;
137 typedef typename select_ref<
const origin_type *, origin_type *,
138 PT>::ref_type porigin_type;
139 typedef typename linalg_traits<M>::value_type value_type;
140 typedef typename select_ref<value_type,
141 typename linalg_traits<M>::reference, PT>::ref_type reference;
142 typedef abstract_null_type sub_col_type;
143 typedef abstract_null_type col_iterator;
144 typedef abstract_null_type const_sub_col_type;
145 typedef abstract_null_type const_col_iterator;
146 typedef typename sub_vector_type<
const typename org_type<
typename
147 linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
149 typedef typename select_ref<abstract_null_type,
150 typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
151 SUBI2>::vector_type, PT>::ref_type sub_row_type;
152 typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
153 SUBI1, SUBI2> const_row_iterator;
154 typedef typename select_ref<abstract_null_type,
155 gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
157 typedef typename linalg_traits<const_sub_row_type>::storage_type
159 typedef row_major sub_orientation;
160 typedef linalg_true index_sorted;
161 static size_type nrows(
const this_type &m) {
return m.nrows(); }
162 static size_type ncols(
const this_type &m) {
return m.ncols(); }
163 static const_sub_row_type row(
const const_row_iterator &it)
164 {
return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
165 static sub_row_type row(
const row_iterator &it)
166 {
return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
167 static const_row_iterator row_begin(
const this_type &m)
168 {
return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
169 static row_iterator row_begin(this_type &m)
170 {
return row_iterator(m.begin_, m.si1, m.si2, 0); }
171 static const_row_iterator row_end(
const this_type &m)
172 {
return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
173 static row_iterator row_end(this_type &m)
174 {
return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
175 static origin_type* origin(this_type &v) {
return v.origin; }
176 static const origin_type* origin(
const this_type &v) {
return v.origin; }
177 static void do_clear(this_type &m) {
178 row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
179 for (; it != ite; ++it)
clear(row(it));
181 static value_type access(
const const_row_iterator &itrow,
size_type i)
182 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
183 static reference access(
const row_iterator &itrow,
size_type i)
184 {
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
187 template <
typename PT,
typename SUBI1,
typename SUBI2>
188 std::ostream &operator <<(std::ostream &o,
189 const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
190 { gmm::write(o,m);
return o; }
197 template <
typename PT,
typename SUBI1,
typename SUBI2>
198 struct gen_sub_col_matrix {
199 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
200 typedef typename std::iterator_traits<PT>::value_type M;
202 typedef typename std::iterator_traits<PT>::reference ref_M;
203 typedef typename select_ref<typename linalg_traits<M>
204 ::const_col_iterator,
typename linalg_traits<M>::col_iterator,
205 PT>::ref_type iterator;
206 typedef typename linalg_traits<this_type>::reference reference;
207 typedef typename linalg_traits<this_type>::porigin_type porigin_type;
215 {
return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
217 size_type nrows(
void)
const {
return si1.size(); }
218 size_type ncols(
void)
const {
return si2.size(); }
220 gen_sub_col_matrix(ref_M m,
const SUBI1 &s1,
const SUBI2 &s2)
221 : si1(s1), si2(s2), begin_(mat_col_begin(m)),
222 origin(linalg_origin(m)) {}
223 gen_sub_col_matrix() {}
224 gen_sub_col_matrix(
const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
225 si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
228 template <
typename PT,
typename SUBI1,
typename SUBI2>
229 struct gen_sub_col_matrix_iterator {
230 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
231 typedef typename modifiable_pointer<PT>::pointer MPT;
232 typedef typename std::iterator_traits<PT>::value_type M;
233 typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
234 typename linalg_traits<M>::col_iterator,
236 typedef ITER value_type;
237 typedef ITER *pointer;
238 typedef ITER &reference;
239 typedef ptrdiff_t difference_type;
241 typedef std::random_access_iterator_tag iterator_category;
242 typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
249 iterator operator ++(
int) { iterator tmp = *
this; ii++;
return tmp; }
250 iterator operator --(
int) { iterator tmp = *
this; ii--;
return tmp; }
251 iterator &operator ++() { ii++;
return *
this; }
252 iterator &operator --() { ii--;
return *
this; }
253 iterator &operator +=(difference_type i) { ii += i;
return *
this; }
254 iterator &operator -=(difference_type i) { ii -= i;
return *
this; }
256 { iterator itt = *
this;
return (itt += i); }
258 { iterator itt = *
this;
return (itt -= i); }
259 difference_type
operator -(
const iterator &i)
const {
return ii - i.ii; }
261 ITER operator *()
const {
return it + si2.index(ii); }
262 ITER operator [](
int i) {
return it + si2.index(ii+i); }
264 bool operator ==(
const iterator &i)
const {
return (ii == i.ii); }
265 bool operator !=(
const iterator &i)
const {
return !(i == *
this); }
266 bool operator < (
const iterator &i)
const {
return (ii < i.ii); }
268 gen_sub_col_matrix_iterator(
void) {}
269 gen_sub_col_matrix_iterator(
const
270 gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
271 : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
272 gen_sub_col_matrix_iterator(
const ITER &iter,
const SUBI1 &s1,
274 : it(iter), si1(s1), si2(s2), ii(i) { }
277 template <
typename PT,
typename SUBI1,
typename SUBI2>
278 struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
279 typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
280 typedef typename std::iterator_traits<PT>::value_type M;
281 typedef typename linalg_traits<M>::origin_type origin_type;
282 typedef typename select_ref<
const origin_type *, origin_type *,
283 PT>::ref_type porigin_type;
284 typedef typename which_reference<PT>::is_reference is_reference;
285 typedef abstract_matrix linalg_type;
286 typedef typename linalg_traits<M>::value_type value_type;
287 typedef typename select_ref<value_type,
288 typename linalg_traits<M>::reference, PT>::ref_type reference;
289 typedef abstract_null_type sub_row_type;
290 typedef abstract_null_type row_iterator;
291 typedef abstract_null_type const_sub_row_type;
292 typedef abstract_null_type const_row_iterator;
293 typedef typename sub_vector_type<const typename org_type<typename linalg_traits<M>::const_sub_col_type>::t *, SUBI1>::vector_type const_sub_col_type;
294 typedef typename select_ref<abstract_null_type, typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_col_type>::t *, SUBI1>::vector_type, PT>::ref_type sub_col_type;
295 typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
296 SUBI1, SUBI2> const_col_iterator;
297 typedef typename select_ref<abstract_null_type,
298 gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
300 typedef col_major sub_orientation;
301 typedef linalg_true index_sorted;
302 typedef typename linalg_traits<const_sub_col_type>::storage_type
304 static size_type nrows(
const this_type &m) {
return m.nrows(); }
305 static size_type ncols(
const this_type &m) {
return m.ncols(); }
306 static const_sub_col_type col(
const const_col_iterator &it)
307 {
return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
308 static sub_col_type col(
const col_iterator &it)
309 {
return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
310 static const_col_iterator col_begin(
const this_type &m)
311 {
return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
312 static col_iterator col_begin(this_type &m)
313 {
return col_iterator(m.begin_, m.si1, m.si2, 0); }
314 static const_col_iterator col_end(
const this_type &m)
315 {
return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
316 static col_iterator col_end(this_type &m)
317 {
return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); }
318 static origin_type* origin(this_type &v) {
return v.origin; }
319 static const origin_type* origin(
const this_type &v) {
return v.origin; }
320 static void do_clear(this_type &m) {
321 col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
322 for (; it != ite; ++it)
clear(col(it));
324 static value_type access(
const const_col_iterator &itcol,
size_type i)
325 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
326 static reference access(
const col_iterator &itcol,
size_type i)
327 {
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
330 template <
typename PT,
typename SUBI1,
typename SUBI2> std::ostream &
operator <<
331 (std::ostream &o,
const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
332 { gmm::write(o,m);
return o; }
338 template <
typename PT,
typename SUBI1,
typename SUBI2,
typename ST>
339 struct sub_matrix_type_ {
340 typedef abstract_null_type return_type;
342 template <
typename PT,
typename SUBI1,
typename SUBI2>
343 struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
344 {
typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
345 template <
typename PT,
typename SUBI1,
typename SUBI2>
346 struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
347 {
typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
348 template <
typename PT,
typename SUBI1,
typename SUBI2>
349 struct sub_matrix_type {
350 typedef typename std::iterator_traits<PT>::value_type M;
351 typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
352 typename principal_orientation_type<
typename
353 linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
356 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
357 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
358 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
360 sub_matrix(M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
361 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
362 "sub matrix too large");
363 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
364 SUBI2>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>
365 ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2);
368 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
369 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
370 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
371 const M *>::return_type
372 sub_matrix(
const M &m,
const SUBI1 &si1,
const SUBI2 &si2) {
373 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
374 "sub matrix too large");
375 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
376 SUBI2>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>
377 ::matrix_type,
const M *>::return_type(linalg_cast(m), si1, si2);
380 template <
typename M,
typename SUBI1>
inline
381 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
382 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
384 sub_matrix(M &m,
const SUBI1 &si1) {
385 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
386 "sub matrix too large");
387 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
388 SUBI1>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>
389 ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1);
392 template <
typename M,
typename SUBI1>
inline
393 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
394 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
395 const M *>::return_type
396 sub_matrix(
const M &m,
const SUBI1 &si1) {
397 GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
398 "sub matrix too large");
399 return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
400 SUBI1>::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>
401 ::matrix_type,
const M *>::return_type(linalg_cast(m), si1, si1);
406 #endif // GMM_SUB_MATRIX_H__