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); }
 
  119     bool operator > (
const iterator &i)
 const { 
return (ii >  i.ii); }
 
  120     bool operator >=(
const iterator &i)
 const { 
return (ii >= i.ii); }
 
  122     gen_sub_row_matrix_iterator(
void) {}
 
  123     gen_sub_row_matrix_iterator(
const  
  124              gen_sub_row_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
 
  125       : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
 
  126     gen_sub_row_matrix_iterator(
const ITER &iter, 
const SUBI1 &s1,
 
  128       : it(iter), si1(s1), si2(s2), ii(i) { }
 
  132   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  133   struct linalg_traits<gen_sub_row_matrix<PT, SUBI1, SUBI2> > {
 
  134     typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> this_type;
 
  135     typedef typename std::iterator_traits<PT>::value_type M;
 
  136     typedef typename which_reference<PT>::is_reference is_reference;
 
  137     typedef abstract_matrix linalg_type;
 
  138     typedef typename linalg_traits<M>::origin_type origin_type;
 
  139     typedef typename select_ref<
const origin_type *, origin_type *,
 
  140                                 PT>::ref_type porigin_type;
 
  141     typedef typename linalg_traits<M>::value_type value_type;
 
  142     typedef typename select_ref<value_type,
 
  143             typename linalg_traits<M>::reference, PT>::ref_type reference;
 
  144     typedef abstract_null_type sub_col_type;
 
  145     typedef abstract_null_type col_iterator;
 
  146     typedef abstract_null_type const_sub_col_type;
 
  147     typedef abstract_null_type const_col_iterator;
 
  148     typedef typename sub_vector_type<
const typename org_type<
typename 
  149             linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
 
  151     typedef typename select_ref<abstract_null_type, 
 
  152             typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
 
  153             SUBI2>::vector_type, PT>::ref_type sub_row_type;
 
  154     typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
 
  155             SUBI1, SUBI2> const_row_iterator;
 
  156     typedef typename select_ref<abstract_null_type, 
 
  157             gen_sub_row_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
 
  159     typedef typename linalg_traits<const_sub_row_type>::storage_type
 
  161     typedef row_major sub_orientation;
 
  162     typedef linalg_true index_sorted;
 
  163     static size_type nrows(
const this_type &m) { 
return m.nrows(); }
 
  164     static size_type ncols(
const this_type &m) { 
return m.ncols(); }
 
  165     static const_sub_row_type row(
const const_row_iterator &it)
 
  166     { 
return const_sub_row_type(linalg_traits<M>::row(*it), it.si2); }
 
  167     static sub_row_type row(
const row_iterator &it)
 
  168     { 
return sub_row_type(linalg_traits<M>::row(*it), it.si2); }
 
  169     static const_row_iterator row_begin(
const this_type &m)
 
  170     { 
return const_row_iterator(m.begin_, m.si1, m.si2, 0); }
 
  171     static row_iterator row_begin(this_type &m)
 
  172     { 
return row_iterator(m.begin_, m.si1, m.si2, 0); }
 
  173     static const_row_iterator row_end(
const this_type &m)
 
  174     { 
return const_row_iterator(m.begin_, m.si1, m.si2,  m.nrows()); }
 
  175     static row_iterator row_end(this_type &m)
 
  176     { 
return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); }
 
  177     static origin_type* origin(this_type &v) { 
return v.origin; }
 
  178     static const origin_type* origin(
const this_type &v) { 
return v.origin; }
 
  179     static void do_clear(this_type &m) {
 
  180       row_iterator it = mat_row_begin(m), ite = mat_row_end(m);
 
  181       for (; it != ite; ++it) 
clear(row(it));
 
  183     static value_type access(
const const_row_iterator &itrow, 
size_type i)
 
  184     { 
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
 
  185     static reference access(
const row_iterator &itrow, 
size_type i)
 
  186     { 
return linalg_traits<M>::access(*itrow, itrow.si2.index(i)); }
 
  189   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  190   std::ostream &operator <<(std::ostream &o,
 
  191                             const gen_sub_row_matrix<PT, SUBI1, SUBI2>& m)
 
  192   { gmm::write(o,m); 
return o; }
 
  199   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  200   struct gen_sub_col_matrix {
 
  201     typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
 
  202     typedef typename std::iterator_traits<PT>::value_type M;
 
  204     typedef typename std::iterator_traits<PT>::reference ref_M;
 
  205     typedef typename select_ref<typename linalg_traits<M>
 
  206             ::const_col_iterator, 
typename linalg_traits<M>::col_iterator,
 
  207             PT>::ref_type iterator;
 
  208     typedef typename linalg_traits<this_type>::reference reference;
 
  209     typedef typename linalg_traits<this_type>::porigin_type porigin_type;
 
  217     { 
return linalg_traits<M>::access(begin_ + si2.index(j), si1.index(i)); }
 
  219     size_type nrows(
void)
 const { 
return si1.size(); }
 
  220     size_type ncols(
void)
 const { 
return si2.size(); }
 
  222     gen_sub_col_matrix(ref_M m, 
const SUBI1 &s1, 
const SUBI2 &s2)
 
  223       : si1(s1), si2(s2), begin_(mat_col_begin(m)),
 
  224         origin(linalg_origin(m)) {}
 
  225     gen_sub_col_matrix() {}
 
  226     gen_sub_col_matrix(
const gen_sub_col_matrix<CPT, SUBI1, SUBI2> &cr) :
 
  227       si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {}
 
  230   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  231   struct gen_sub_col_matrix_iterator {
 
  232     typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
 
  233     typedef typename modifiable_pointer<PT>::pointer MPT;
 
  234     typedef typename std::iterator_traits<PT>::value_type M;
 
  235     typedef typename select_ref<typename linalg_traits<M>::const_col_iterator,
 
  236                                 typename linalg_traits<M>::col_iterator,
 
  238     typedef ITER value_type;
 
  239     typedef ITER *pointer;
 
  240     typedef ITER &reference;
 
  241     typedef ptrdiff_t difference_type;
 
  243     typedef std::random_access_iterator_tag  iterator_category;
 
  244     typedef gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2> iterator;
 
  251     iterator operator ++(
int) { iterator tmp = *
this; ii++; 
return tmp; }
 
  252     iterator operator --(
int) { iterator tmp = *
this; ii--; 
return tmp; }
 
  253     iterator &operator ++()   { ii++; 
return *
this; }
 
  254     iterator &operator --()   { ii--; 
return *
this; }
 
  255     iterator &operator +=(difference_type i) { ii += i; 
return *
this; }
 
  256     iterator &operator -=(difference_type i) { ii -= i; 
return *
this; }
 
  258     { iterator itt = *
this; 
return (itt += i); }
 
  260     { iterator itt = *
this; 
return (itt -= i); }
 
  261     difference_type 
operator -(
const iterator &i)
 const { 
return ii - i.ii; }
 
  263     ITER operator *()
 const { 
return it + si2.index(ii); }
 
  264     ITER operator [](
int i) { 
return it + si2.index(ii+i); }
 
  266     bool operator ==(
const iterator &i)
 const { 
return (ii == i.ii); }
 
  267     bool operator !=(
const iterator &i)
 const { 
return !(i == *
this); }
 
  268     bool operator < (
const iterator &i)
 const { 
return (ii <  i.ii); }
 
  269     bool operator > (
const iterator &i)
 const { 
return (ii >  i.ii); }
 
  270     bool operator >=(
const iterator &i)
 const { 
return (ii >= i.ii); }
 
  272     gen_sub_col_matrix_iterator(
void) {}
 
  273     gen_sub_col_matrix_iterator(
const  
  274         gen_sub_col_matrix_iterator<MPT, SUBI1, SUBI2> &itm)
 
  275       : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {}
 
  276     gen_sub_col_matrix_iterator(
const ITER &iter, 
const SUBI1 &s1,
 
  278       : it(iter), si1(s1), si2(s2), ii(i) { }
 
  281   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  282   struct linalg_traits<gen_sub_col_matrix<PT, SUBI1, SUBI2> > {
 
  283     typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> this_type;
 
  284     typedef typename std::iterator_traits<PT>::value_type M;
 
  285     typedef typename linalg_traits<M>::origin_type origin_type;
 
  286     typedef typename select_ref<
const origin_type *, origin_type *,
 
  287                                 PT>::ref_type porigin_type;
 
  288     typedef typename which_reference<PT>::is_reference is_reference;
 
  289     typedef abstract_matrix linalg_type;
 
  290     typedef typename linalg_traits<M>::value_type value_type;
 
  291     typedef typename select_ref<value_type,
 
  292             typename linalg_traits<M>::reference, PT>::ref_type reference;
 
  293     typedef abstract_null_type sub_row_type;
 
  294     typedef abstract_null_type row_iterator;
 
  295     typedef abstract_null_type const_sub_row_type;
 
  296     typedef abstract_null_type const_row_iterator;
 
  297     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;
 
  298     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;
 
  299     typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
 
  300             SUBI1, SUBI2> const_col_iterator;
 
  301     typedef typename select_ref<abstract_null_type, 
 
  302             gen_sub_col_matrix_iterator<PT, SUBI1, SUBI2>, PT>::ref_type
 
  304     typedef col_major sub_orientation;
 
  305     typedef linalg_true index_sorted;
 
  306     typedef typename linalg_traits<const_sub_col_type>::storage_type
 
  308     static size_type nrows(
const this_type &m) { 
return m.nrows(); }
 
  309     static size_type ncols(
const this_type &m) { 
return m.ncols(); }
 
  310     static const_sub_col_type col(
const const_col_iterator &it)
 
  311     { 
return const_sub_col_type(linalg_traits<M>::col(*it), it.si1); }
 
  312     static sub_col_type col(
const col_iterator &it)
 
  313     { 
return sub_col_type(linalg_traits<M>::col(*it), it.si1); }
 
  314     static const_col_iterator col_begin(
const this_type &m)
 
  315     { 
return const_col_iterator(m.begin_, m.si1, m.si2, 0); }
 
  316     static col_iterator col_begin(this_type &m)
 
  317     { 
return col_iterator(m.begin_, m.si1, m.si2, 0); }
 
  318     static const_col_iterator col_end(
const this_type &m)
 
  319     { 
return const_col_iterator(m.begin_, m.si1, m.si2,  m.ncols()); }
 
  320     static col_iterator col_end(this_type &m)
 
  321     { 
return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); } 
 
  322     static origin_type* origin(this_type &v) { 
return v.origin; }
 
  323     static const origin_type* origin(
const this_type &v) { 
return v.origin; }
 
  324     static void do_clear(this_type &m) {
 
  325       col_iterator it = mat_col_begin(m), ite = mat_col_end(m);
 
  326       for (; it != ite; ++it) 
clear(col(it));
 
  328     static value_type access(
const const_col_iterator &itcol, 
size_type i)
 
  329     { 
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
 
  330     static reference access(
const col_iterator &itcol, 
size_type i)
 
  331     { 
return linalg_traits<M>::access(*itcol, itcol.si1.index(i)); }
 
  334   template <
typename PT, 
typename SUBI1, 
typename SUBI2> std::ostream &
operator <<
 
  335   (std::ostream &o, 
const gen_sub_col_matrix<PT, SUBI1, SUBI2>& m)
 
  336   { gmm::write(o,m); 
return o; }
 
  342   template <
typename PT, 
typename SUBI1, 
typename SUBI2, 
typename ST>
 
  343   struct sub_matrix_type_ {
 
  344     typedef abstract_null_type return_type;
 
  346   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  347   struct sub_matrix_type_<PT, SUBI1, SUBI2, col_major>
 
  348   { 
typedef gen_sub_col_matrix<PT, SUBI1, SUBI2> matrix_type; };
 
  349   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  350   struct sub_matrix_type_<PT, SUBI1, SUBI2, row_major>
 
  351   { 
typedef gen_sub_row_matrix<PT, SUBI1, SUBI2> matrix_type; };
 
  352   template <
typename PT, 
typename SUBI1, 
typename SUBI2>
 
  353   struct sub_matrix_type {
 
  354     typedef typename std::iterator_traits<PT>::value_type M;
 
  355     typedef typename sub_matrix_type_<PT, SUBI1, SUBI2,
 
  356         typename principal_orientation_type<
typename 
  357         linalg_traits<M>::sub_orientation>::potype>::matrix_type matrix_type;
 
  360   template <
typename M, 
typename SUBI1, 
typename SUBI2>  
inline 
  361     typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
 
  362     ::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
 
  364   sub_matrix(M &m, 
const SUBI1 &si1, 
const SUBI2 &si2) {
 
  365     GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
 
  366                 "sub matrix too large");
 
  367     return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
 
  368       SUBI2>::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI2>
 
  369       ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2);
 
  372   template <
typename M, 
typename SUBI1, 
typename SUBI2>  
inline 
  373     typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
 
  374     ::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
 
  375     const M *>::return_type
 
  376   sub_matrix(
const M &m, 
const SUBI1 &si1, 
const SUBI2 &si2) {
 
  377     GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m),
 
  378                 "sub matrix too large");
 
  379     return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
 
  380       SUBI2>::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI2>
 
  381       ::matrix_type, 
const M *>::return_type(linalg_cast(m), si1, si2);
 
  384   template <
typename M, 
typename SUBI1>  
inline 
  385     typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
 
  386     ::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
 
  388   sub_matrix(M &m, 
const SUBI1 &si1) {
 
  389     GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
 
  390                 "sub matrix too large");
 
  391     return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
 
  392       SUBI1>::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI1>
 
  393       ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1);
 
  396   template <
typename M, 
typename SUBI1>  
inline 
  397     typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
 
  398     ::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
 
  399     const M *>::return_type
 
  400   sub_matrix(
const M &m, 
const SUBI1 &si1) {
 
  401     GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m),
 
  402                 "sub matrix too large");
 
  403     return typename select_return<
typename sub_matrix_type<
const M *, SUBI1,
 
  404       SUBI1>::matrix_type, 
typename sub_matrix_type<M *, SUBI1, SUBI1>
 
  405       ::matrix_type, 
const M *>::return_type(linalg_cast(m), si1, si1);
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
 
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
 
size_t size_type
used as the common size type in the library