matrix.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     matrix.hpp -- определение матрицы.
00004 
00005     Этот файл является частью библиотеки Arageli.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005
00009     University of Nizhni Novgorod, Russia
00010 
00011 *****************************************************************************/
00012 
00026 #ifndef _ARAGELI_matrix_hpp_
00027 #define _ARAGELI_matrix_hpp_
00028 
00029 #include "config.hpp"
00030 
00031 #include <cstddef>
00032 #include <iostream>
00033 #include <vector>
00034 #include <utility>
00035 
00036 #include "frwrddecl.hpp"
00037 
00038 #include "type_opers.hpp"
00039 #include "type_traits.hpp"
00040 #include "type_pair_traits.hpp"
00041 #include "exception.hpp"
00042 #include "refcntr.hpp"
00043 #include "factory.hpp"
00044 #include "cmp.hpp"
00045 #include "io.hpp"
00046 #include "vector.hpp"
00047 
00048 #include "std_import.hpp"
00049 
00050 
00051 namespace Arageli
00052 {
00053 
00054 
00056 
00057 struct nonsquare_t {};
00058 
00061 //const nonsquare_t fromsize = nonsquare_t();
00062 
00063 
00065 
00066 struct colwise_t {};
00067 
00069 
00070 const colwise_t colwise = colwise_t();
00071 
00072 
00074 
00075 struct diag_t {};
00076 
00078 
00079 const diag_t diag = diag_t();
00080 
00081 
00083 
00084 struct eye_t {};
00085 
00087 
00088 const eye_t eye = eye_t();
00089 
00090 
00091 struct frommat_t {};
00092 const frommat_t frommat = frommat_t();
00093 
00094 
00095 namespace _Internal
00096 {
00097 
00098 template <typename T>
00099 struct Rep_matrix   // internal representation for matrix template
00100 {
00101     // std::vector -- временно, нужно свой облегчённый вектор
00102     typedef std::vector<T> Mem;
00103     typedef typename Mem::size_type size_type;
00104     size_type rows, cols;
00105     Mem mem;
00106 
00107     Rep_matrix () : rows(0), cols(0) {}
00108 
00109     void assign (size_type rows_a, size_type cols_a, const T& val)
00110     { rows = rows_a; cols = cols_a; mem.assign(rows*cols, val); }
00111 
00112     template <typename In>
00113     void assign (size_type rows_a, size_type cols_a, In b, In e)
00114     {
00115         rows = rows_a; cols = cols_a; mem.assign(b, e);
00116         ARAGELI_ASSERT_1(rows*cols == mem.size());
00117     }
00118 };
00119 
00120 } // namespace _Internal
00121 } // namespace Arageli
00122 
00123 
00124 namespace std
00125 {
00126 
00127 template <typename T>
00128 inline void swap
00129 (
00130     Arageli::_Internal::Rep_matrix<T>& a,
00131     Arageli::_Internal::Rep_matrix<T>& b
00132 )
00133 {
00134     swap(a.mem, b.mem);
00135     swap(a.rows, b.rows);
00136     swap(a.cols, b.cols);
00137 }
00138 
00139 } // namespace std
00140 
00141 
00142 namespace Arageli
00143 {
00144 
00145 
00147 
00151 template
00152 <
00153     typename T,
00154     bool REFCNT
00155 >
00156 class matrix
00157 {
00158     template <typename T1, bool REFCNT1>
00159     friend class matrix;
00160     
00161     //struct Rep    // внутреннее представление
00162     //{
00163     //  // std::vector -- временно, нужно свой облегчённый вектор
00164     //  typedef std::vector<T> Mem;
00165     //  typedef typename Mem::size_type size_type;
00166     //  size_type rows, cols;
00167     //  Mem mem;
00168 
00169     //  Rep () : nrows(0), ncols(0) {}
00170 
00171     //  void assign (size_type rows_a, size_type cols_a, const T& val)
00172     //  { rows = rows_a; cols = cols_a; mem.assign(rows*cols, val); }
00173 
00174     //  template <typename In>
00175     //  void assign (size_type rows_a, size_type cols_a, In b, In e)
00176     //  {
00177     //      rows = rows_a; cols = cols_a; mem.assign(b, e);
00178     //      ARAGELI_ASSERT_1(rows*cols == mem.size());
00179     //  }
00180     //};
00181 
00182     typedef _Internal::Rep_matrix<T> Rep;
00183     typedef typename Rep::Mem Mem;
00184 
00185 public:
00186 
00187 
00188     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00190 
00191 
00193 
00195     typedef typename Mem::value_type value_type;
00196     
00198     typedef typename Mem::value_type element_type;
00199 
00201     typedef typename Mem::reference reference;
00202     
00204     typedef typename Mem::const_reference const_reference;
00205     
00207     typedef typename Mem::pointer pointer;
00208     
00210     typedef typename Mem::const_pointer const_pointer;
00211     
00213 
00214     typedef typename Mem::size_type size_type;
00215     
00217     typedef typename Mem::difference_type difference_type;
00218     
00220     typedef typename Rep::Mem::iterator iterator;
00221 
00223     typedef typename Rep::Mem::const_iterator const_iterator;
00224 
00225     // @}
00226 
00227 
00229     template <typename T1> struct other_element_type
00230     { typedef matrix<T1, REFCNT> type; };
00231 
00233     template <typename T1, bool REFCNT1> struct other_element_type_refcnt
00234     { typedef matrix<T1, REFCNT1> type; };
00235 
00237 
00238     static const bool refcounting = REFCNT;
00239 
00240 
00241     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00243     
00244     
00246 
00247 
00249     matrix () {}
00250 
00251     // BE CAREFUL! There is one more constructor. It is automaticaly generated
00252     // copy-constructor. Worry about its meaning is being belonged to other
00253     // constructors during modifications.
00254 
00255 
00256     // ------------------------------------------------------------------
00257 
00258 
00260     matrix (std::size_t size_a, const fromsize_t& select)
00261     { assign_fromsize(size_a); }
00262 
00263 
00265     matrix (const char* s, const fromstr_t& select)
00266     { assign_fromstr(s); }
00267 
00268 
00270     template <typename Vec>
00271     matrix (const Vec& vec, const fromvec_t& select)
00272     { assign_fromvec(vec); }
00273 
00274 
00276     template <typename Mat>
00277     matrix (const Mat& mat, const frommat_t& select)
00278     { assign_frommat(mat); }
00279 
00280 
00282     template <typename X>
00283     matrix (const X& x)
00284     { assign(x); }
00285 
00286 
00287     // ------------------------------------------------------------------
00288 
00289 
00291 
00294     template <typename Val>
00295     matrix (size_type rowscols_a, const Val& val, const fromval_t& select)
00296     { assign_fromval(rowscols_a, val); }
00297 
00298 
00300 
00304     template <typename Seq>
00305     matrix (size_type rowscols_a, const Seq& seq, const fromseq_t& select)
00306     { assign_fromseq(rowscols_a, seq); }
00307 
00308 
00310 
00312     matrix (size_type rows_a, size_type cols_a, const fromsize_t& select)
00313     { assign_fromsize(rows_a, cols_a); }
00314 
00315 
00317     template <typename Vec>
00318     matrix (size_type rows_a, const Vec& vec, const fromvec_t& select)
00319     { assign_fromvec(rows_a, vec); }
00320 
00321 
00323     template <typename X>
00324     matrix (size_type rowscols_a, const X& x)
00325     { assign(rowscols_a, x); }
00326 
00327 
00328     // ------------------------------------------------------------------
00329 
00330 
00332     template <typename Vec>
00333     matrix (const Vec& vec, const colwise_t& select)
00334     { assign_colwise(vec); }
00335 
00336 
00338     template <typename Vec>
00339     matrix
00340     (
00341         size_type cols_a, const Vec& vec,
00342         const colwise_t& select_1, const fromvec_t& select_2
00343     )
00344     { assign_colwise_fromvec(cols_a, vec); }
00345 
00346 
00348     template <typename Seq>
00349     matrix
00350     (
00351         size_type rowcols_a, const Seq& seq,
00352         const colwise_t& select_1, const fromseq_t& select_2
00353     )
00354     { assign_colwise_fromseq(rowcols_a, seq); }
00355 
00356 
00357     template <typename X>
00358     matrix (size_type rowcols_a, const X& x, const colwise_t& select)
00359     { assign_colwise(rowcols_a, x); }
00360 
00361 
00363     template <typename Seq>
00364     matrix
00365     (
00366         size_type rows_a, size_type cols_a,
00367         const Seq& seq, const colwise_t& select
00368     )
00369     { assign_colwise(rows_a, cols_a, seq); }
00370 
00371 
00372     // ------------------------------------------------------------------
00373 
00374 
00376 
00379     template <typename Val>
00380     matrix
00381     (
00382         size_type rows_a, size_type cols_a,
00383         const Val& val,
00384         const fromval_t& select
00385     )
00386     { assign_fromval(rows_a, cols_a, val); }
00387 
00388 
00390 
00394     template <typename Seq>
00395     matrix
00396     (
00397         size_type rows_a, size_type cols_a,
00398         const Seq& seq,
00399         const fromseq_t& select
00400     )
00401     { assign_fromseq(rows_a, cols_a, seq); }
00402 
00403 
00405 
00416     template <typename X>
00417     matrix (size_type rows_a, size_type cols_a, const X& x)
00418     { assign(rows_a, cols_a, x); }
00419 
00420 
00421     // ------------------------------------------------------------------
00422 
00423 
00425 
00427     template <typename Vec>
00428     matrix (const Vec& vec, const diag_t& select)
00429     { assign_diag(vec); }
00430 
00431 
00433 
00435     template <typename Val>
00436     matrix
00437     (
00438         size_type rowscols_a, const Val& val,
00439         const diag_t& select_1,
00440         const fromval_t& select_2
00441     )
00442     { assign_diag_fromval(rowscols_a, val); }
00443 
00444 
00446 
00448     template <typename Seq>
00449     matrix
00450     (
00451         size_type rowscols_a, const Seq& seq,
00452         const diag_t& select_1,
00453         const fromseq_t& select_2
00454     )
00455     { assign_diag_fromseq(rowscols_a, seq); }
00456 
00457 
00459 
00461     template <typename Vec>
00462     matrix
00463     (
00464         size_type rowscols_a, const Vec& vec,
00465         const diag_t& select_1,
00466         const fromvec_t& select_2
00467     )
00468     { assign_diag_fromvec(rowscols_a, vec); }
00469 
00470 
00472     template <typename X>
00473     matrix
00474     (
00475         size_type rowscols_a, const X& x,
00476         const diag_t& select
00477     )
00478     { assign_diag(rowscols_a, x); }
00479 
00480 
00482 
00485     template <typename Val>
00486     matrix
00487     (
00488         size_type rows_a, size_type cols_a,
00489         const Val& val,
00490         const diag_t& select_1,
00491         const fromval_t& select_2
00492     )
00493     { assign_diag_fromval(rows_a, cols_a, val); }
00494 
00495 
00497 
00500     template <typename Seq>
00501     matrix
00502     (
00503         size_type rows_a, size_type cols_a, const Seq& seq,
00504         const diag_t& select_1,
00505         const fromseq_t& select_2
00506     )
00507     { assign_diag_fromseq(rows_a, cols_a, seq); }
00508 
00509 
00511 
00514     template <typename Vec>
00515     matrix
00516     (
00517         size_type rows_a, size_type cols_a, const Vec& vec,
00518         const diag_t& select_1,
00519         const fromvec_t& select_2
00520     )
00521     { assign_diag_fromvec(rows_a, cols_a, vec); }
00522 
00523 
00525 
00528     template <typename X>
00529     matrix
00530     (
00531         size_type rows_a, size_type cols_a,
00532         const X& x,
00533         const diag_t& select
00534     )
00535     { assign_diag(rows_a, cols_a, x); }
00536 
00537 
00538     // ------------------------------------------------------------------
00539 
00540 
00542 
00545     matrix (size_type rowscols_a, const eye_t& select)
00546     { assign_eye(rowscols_a); }
00547 
00548 
00550 
00553     matrix
00554     (
00555         size_type rows_a, size_type cols_a,
00556         const eye_t& select
00557     )
00558     { assign_eye(rows_a, cols_a); }
00559 
00560     
00561     // @}
00562 
00563 
00565 
00566 
00567     //matrix (size_type rows_a, size_type cols_a, const T& val, const diag_t& select)
00568     //{ assign(rows_a, cols_a, val, diag); }
00569 
00572     //  square_matrix_t parameter if types size_type and T are correlated
00573     //  and overloading is not worked.
00574     //  @param rowscols_a size of a matrix, it is number of rows
00575     //      (or number of columns)
00576     //  @param val value for initialization of each item
00577     //  @param select helper argument for choosing this constructor,
00578     //      use square_matrix  */
00579     //matrix (size_type rowscols_a, T val, const square_matrix_t& select)
00580     //{ rep().assign(rowscols_a, rowscols_a, val); }
00581 
00582 
00585     //  @param cols_a number of columns
00586     //  @param val value for initialization of each items,
00587     //      by default this is TT::null() */
00588     //matrix (size_type rows_a, size_type cols_a, T val = factory<T>::null())
00589     //{ rep().assign(rows_a, cols_a, val); }
00590 
00591 
00594     //  nonsquare_t parameter if types size_type and T are correlated
00595     //  and overloading is not worked.
00596     //  @param rows_a number of rows
00597     //  @param cols_a number of columns
00598     //  @param select helper argument for choosing this constructor,
00599     //      use fromsize  */
00600     //matrix (size_type rows_a, size_type cols_a, const nonsquare_t& select)
00601     //{ rep().assign(rows_a, cols_a, factory<T>::null()); }
00602 
00603 
00606     //      and number of columns
00607     //  @param in   an iterator to begin of the sequence, and elements of matrix
00608     //      will be columnwise constructed from this sequence. */
00609     //template <typename In>
00610     //matrix
00611     //(
00612     //  size_type rowscols_a, const In& in,
00613     //  const colwise_t& select
00614     //)
00615     //{ assign(rowscols_a, in, select); }
00616 
00617 
00620     //  @param cols_a   number of columns
00621     //  @param in   an iterator to begin of the sequence, and elements of matrix
00622     //      will be rowwise constructed from this sequence */
00623     //template <typename In>
00624     //matrix
00625     //(
00626     //  size_type rows_a, size_type cols_a,
00627     //  const In& in,
00628     //  const colwise_t& select
00629     //)
00630     //{ assign(rows_a, cols_a, in, select); }
00631 
00634     //  @param cols_a   number of columns */
00635     //matrix (size_type rows_a, size_type cols_a, const nonsquare_t&)
00636     //{ rep().assign(rows_a, cols_a, factory<T>::null()); }
00637 
00638 
00641     //  you want to call this version of a constructor, you can call more specific
00642     //  form of this: matrix (rows_a, cols_a, nonsquare_t).
00643     //  @param rows_a   number of rows
00644     //  @param cols_a   number of columns */
00645     //matrix (size_type rows_a, size_type cols_a)
00646     //{ rep().assign(rows_a, cols_a, factory<T>::null()); }
00647 
00648 
00649     //#if 0
00650     //
00651     //  /// Initializes matrix by its string notation.
00652     //  /** Input rules are the same as for operator>> with default behaviour. */
00653     //  matrix (const char* s);
00654     //
00655     //
00656     //  /// Copy constructor from matrix with any other type of template parameters.
00657     //  template <typename T1, bool REFCNT1>
00658     //  matrix (const matrix<T1, REFCNT1>& x)
00659     //  {
00660     //      ARAGELI_ASSERT_1
00661     //      (
00662     //          reinterpret_cast<const void*>(this) !=
00663     //          reinterpret_cast<const void*>(&x)
00664     //      );
00665     //
00666     //      rep().assign(x.nrows(), x.ncols(), x.mem().begin(), x.mem().end());
00667     //  }
00668     //
00669     //  /// Creates square matrix, each item is equal to factory<T>::null().
00670     //  /** @param rowscols_a size of a matrix, it is number of rows
00671     //          and number of columns */
00672     //  explicit matrix (size_type rowscols_a)
00673     //  { rep().assign(rowscols_a, rowscols_a, factory<T>::null()); }
00674     //
00675     //#endif
00676 
00677 
00678     
00679     
00681 
00682 
00683 
00685     void assign_fromsize (std::size_t size_a)
00686     { assign_fromsize(size_a, size_a); }
00687 
00688 
00690     void assign_fromstr (const char* s);
00691 
00692 
00694     template <typename Vec>
00695     void assign_fromvec (const Vec& vec)
00696     { assign_fromseq(1u, vec.size(), vec.begin()); }
00697     
00698 
00700     template <typename Mat>
00701     void assign_frommat (const Mat& mat)
00702     { assign_fromseq(mat.nrows(), mat.ncols(), mat.begin()); }
00703 
00704 
00705     // ------------------------------------------------------------------
00706 
00707 
00709 
00712     template <typename Val>
00713     void assign_fromval (size_type rowscols_a, const Val& val)
00714     { assign_fromval(rowscols_a, rowscols_a, val); }
00715 
00716 
00718 
00722     template <typename Seq>
00723     void assign_fromseq (size_type rowscols_a, const Seq& seq)
00724     { assign_fromseq(rowscols_a, rowscols_a, seq); }
00725 
00726 
00728 
00730     void assign_fromsize (size_type rows_a, size_type cols_a)
00731     { assign_fromval(rows_a, cols_a, factory<T>::null()); }
00732 
00733 
00735     template <typename Vec>
00736     void assign_fromvec (size_type rows_a, const Vec& vec); // It isn't implemented yet.
00737 
00738 
00739     // ------------------------------------------------------------------
00740 
00741 
00743     template <typename Vec>
00744     void assign_colwise (const Vec& vec);   // It isn't implemented yet.
00745 
00746 
00748     template <typename Vec>
00749     void assign_colwise_fromvec (size_type cols_a, const Vec& vec); // It isn't implemented yet.
00750 
00751 
00753     template <typename Seq>
00754     void assign_colwise_fromseq (size_type rowcols_a, const Seq& seq);  // It isn't implemented yet.
00755 
00756 
00757     template <typename X>
00758     void assign_colwise (size_type rowcols_a, const X& x);  // It isn't implemented yet.
00759 
00760 
00762     template <typename Seq>
00763     void assign_colwise
00764     (size_type rows_a, size_type cols_a, const Seq& seq);   // It isn't implemented yet.
00765 
00766 
00767     // ------------------------------------------------------------------
00768 
00769 
00771 
00774     template <typename Val>
00775     void assign_fromval
00776     (size_type rows_a, size_type cols_a, const Val& val);
00777 
00778 
00780 
00784     template <typename Seq>
00785     void assign_fromseq
00786     (size_type rows_a, size_type cols_a, Seq seq);
00787 
00788 
00789     // ------------------------------------------------------------------
00790 
00791 
00793 
00795     template <typename Vec>
00796     void assign_diag (const Vec& vec)
00797     { assign_diag_fromseq(vec.size(), vec.begin()); }
00798 
00799 
00801 
00803     template <typename Val>
00804     void assign_diag_fromval (size_type rowscols_a, const Val& val)
00805     { assign_diag_fromval(rowscols_a, rowscols_a, val); }
00806 
00807 
00809 
00811     template <typename Seq>
00812     void assign_diag_fromseq (size_type rowscols_a, const Seq& seq)
00813     { assign_diag_fromseq(rowscols_a, rowscols_a, seq); }
00814 
00815 
00817 
00819     template <typename Vec>
00820     void assign_diag_fromvec (size_type rowscols_a, const Vec& vec)
00821     { assign_diag_fromseq(rowscols_a, vec.begin()); }
00822 
00823 
00825     template <typename X>
00826     void assign_diag (size_type rowscols_a, const X& x)
00827     { assign_diag(rowscols_a, rowscols_a, x); }
00828 
00829 
00831 
00834     template <typename Val>
00835     void assign_diag_fromval
00836     (size_type rows_a, size_type cols_a, const Val& val);
00837 
00838 
00840 
00843     template <typename Seq>
00844     void assign_diag_fromseq
00845     (size_type rows_a, size_type cols_a, Seq seq);
00846 
00847 
00849 
00852     template <typename Vec>
00853     void assign_diag_fromvec
00854     (size_type rows_a, size_type cols_a, const Vec& vec)
00855     { assign_diag_fromseq(rows_a, cols_a, vec.begin()); }
00856 
00857 
00859 
00862     template <typename X>
00863     void assign_diag
00864     (size_type rows_a, size_type cols_a, const X& x)
00865     { _assign_diag_val_seq_vec(rows_a, cols_a, x, type_traits<X>::category_value); }
00866 
00867 private:
00868 
00869     template <typename Val>
00870     void _assign_diag_val_seq_vec
00871     (size_type rows_a, size_type cols_a, const Val& val, const type_category::type&)
00872     { assign_diag_fromval(rows_a, cols_a, val); }
00873 
00874     template <typename Seq>
00875     void _assign_diag_val_seq_vec
00876     (size_type rows_a, size_type cols_a, const Seq& seq, const type_category::iterator&)
00877     { assign_diag_fromseq(rows_a, cols_a, seq); }
00878 
00879     template <typename Vec>
00880     void _assign_diag_val_seq_vec
00881     (size_type rows_a, size_type cols_a, const Vec& vec, const type_category::vector&)
00882     { assign_diag_fromvec(rows_a, cols_a, vec); }
00883 
00884 public:
00885 
00886     // ------------------------------------------------------------------
00887 
00888 
00890 
00893     void assign_eye (size_type rowscols_a)
00894     { assign_eye(rowscols_a, rowscols_a); }
00895 
00896 
00898 
00901     void assign_eye (size_type rows_a, size_type cols_a)
00902     { assign_diag_fromval(rows_a, cols_a, factory<T>::unit()); }
00903     
00904     
00906 
00907 
00908     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00910 
00911 
00912     // @{
00913 
00914 
00916     void assign ()
00917     { resize(0, 0); }
00918 
00919 
00920     // ------------------------------------------------------------------
00921 
00922 
00924     //void assign (std::size_t size_a, const fromsize_t& select)
00925     //{ assign_fromsize(size_a); }
00926 
00927 
00929     //void assign (const char* s, const fromstr_t& select)
00930     //{ assign_fromstr(s); }
00931 
00932 
00934     //template <typename Vec>
00935     //void assign (const Vec& vec, const fromvec_t& select)
00936     //{ assign_fromvec(vec); }
00937     //
00938 
00940     //template <typename Mat>
00941     //void assign (const Mat& mat, const frommat_t& select)
00942     //{ assign_frommat(mat); }
00943 
00944 
00946     template <typename X>
00947     void assign (const X& x)
00948     { _assign_size_str_vec_mat(x, type_traits<X>::category_value); }
00949 
00950 private:
00951 
00952     template <typename Size>
00953     void _assign_size_str_vec_mat
00954     (const Size& size_a, const type_category::integer&)
00955     { assign_fromsize(size_a); }
00956 
00957     template <typename Str>
00958     void _assign_size_str_vec_mat
00959     (const Str& s, const type_category::string&)
00960     { assign_fromstr(s); }
00961 
00962     template <typename Vec>
00963     void _assign_size_str_vec_mat
00964     (const Vec& vec, const type_category::vector&)
00965     { assign_fromvec(vec); }
00966 
00967     template <typename Mat>
00968     void _assign_size_str_vec_mat
00969     (const Mat& mat, const type_category::matrix&)
00970     { assign_frommat(mat); }
00971 
00972 public:
00973 
00974     // ------------------------------------------------------------------
00975 
00976 
00979     //      and number of columns
00980     //  @param val an initial value for each element */
00981     //template <typename Val>
00982     //void assign (size_type rowscols_a, const Val& val, const fromval_t& select)
00983     //{ assign_fromval(rowscols_a, val); }
00984 
00985 
00988     //      and number of columns
00989     //  @param seq  an iterator to begin of the sequence, and elements of matrix
00990     //      will be rowwise constructed from this sequence. */
00991     //template <typename Seq>
00992     //void assign (size_type rowscols_a, const Seq& seq, const fromseq_t& select)
00993     //{ assign_fromseq(rowscols_a, seq); }
00994 
00995 
00998     //  @param cols_a   number of columns */
00999     //void assign (size_type rows_a, size_type cols_a, const fromsize_t& select)
01000     //{ assign_fromsize(rows_a, cols_a); }
01001 
01002 
01004     //template <typename Vec>
01005     //void assign (size_type rows_a, const Vec& vec, const fromvec_t& select)
01006     //{ assign_fromvec(rows_a, vec); }
01007 
01008 
01010     template <typename X>
01011     void assign (size_type rowscols_a, const X& x)
01012     {
01013         _assign_seq_size_vec
01014         (
01015             rowscols_a, x,
01016             type_traits<X>::category_value//,
01017             //bool_type<type_pair_traits<X, T>::is_assignable>::value
01018         );
01019     }
01020 
01021 
01022 private:
01023 
01024     //template <typename Val>
01025     //void _assign_val_seq_size_vec
01026     //(
01027     //  size_type rowscols_a, const Val& val,
01028     //  const type_category::type&, const true_type&
01029     //)
01030     //{ assign_fromval(rowscols_a, val); }
01031 
01032     template <typename Seq>
01033     void _assign_seq_size_vec
01034     (
01035         size_type rowscols_a, const Seq& seq,
01036         const type_category::iterator&//, const false_type&
01037     )
01038     { assign_fromseq(rowscols_a, seq); }
01039 
01040     //template <typename Size>
01041     //void _assign_val_seq_size_vec
01042     //(
01043     //  size_type rows_a, const Size& cols_a,
01044     //  const type_category::integer&//, const true_type&
01045     //)
01046     //{ assign_fromsize(rows_a, cols_a); }
01047 
01048     template <typename Size>
01049     void _assign_seq_size_vec
01050     (
01051         size_type rows_a, const Size& cols_a,
01052         const type_category::integer&//, const false_type&
01053     )
01054     { assign_fromsize(rows_a, cols_a); }
01055 
01056     template <typename Vec>
01057     void _assign_seq_size_vec
01058     (
01059         size_type rows_a, const Vec& vec,
01060         const type_category::vector&//, const false_type&
01061     )
01062     { assign_fromvec(rows_a, vec); }
01063 
01064 public:
01065 
01066     // ------------------------------------------------------------------
01067 
01068 
01070     //template <typename Vec>
01071     //void assign (const Vec& vec, const colwise_t& select)
01072     //{ assign_colwise(vec); }
01073 
01074 
01076     //template <typename Vec>
01077     //void assign
01078     //(
01079     //  size_type cols_a, const Vec& vec,
01080     //  const colwise_t& select_1, const fromvec_t& select_2
01081     //)
01082     //{ assign_colwise_fromvec(cols_a, vec); }
01083 
01084 
01086     //template <typename Seq>
01087     //void assign
01088     //(
01089     //  size_type rowcols_a, const Seq& seq,
01090     //  const colwise_t& select_1, const fromseq_t& select_2
01091     //)
01092     //{ assign_colwise_fromseq(rowcols_a, seq); }
01093 
01094 
01096     //template <typename Seq>
01097     //void assign
01098     //(
01099     //  size_type rows_a, size_type cols_a,
01100     //  const Seq& seq, const colwise_t& select
01101     //)
01102     //{ assign_colwise(rows_a, cols_a, seq); }
01103 
01104 
01105     // ------------------------------------------------------------------
01106 
01107 
01110     //  @param cols_a   number of columns
01111     //  @param val  an initial value for each element */
01112     //template <typename Val>
01113     //void assign
01114     //(
01115     //  size_type rows_a, size_type cols_a,
01116     //  const Val& val,
01117     //  const fromval_t& select
01118     //)
01119     //{ assign_fromval(rows_a, cols_a, val); }
01120 
01121 
01124     //  @param cols_a   number of columns
01125     //  @param in   an iterator to begin of the sequence, and elements of matrix
01126     //      will be rowwise constructed from this sequence */
01127     //template <typename Seq>
01128     //void assign
01129     //(
01130     //  size_type rows_a, size_type cols_a,
01131     //  const Seq& seq,
01132     //  const fromseq_t& select
01133     //)
01134     //{ assign_fromseq(rows_a, cols_a, seq); }
01135 
01136 
01138 
01144     template <typename X>
01145     void assign (size_type rows_a, size_type cols_a, const X& x)
01146     {
01147         _assign_val_seq
01148         (
01149             rows_a, cols_a, x,
01150             bool_type<type_pair_traits<X, T>::is_assignable>::value
01151         );
01152     }
01153 
01154 
01155 private:
01156 
01157     template <typename Val>
01158     void _assign_val_seq
01159     (
01160         size_type rows_a, size_type cols_a, const Val& val,
01161         const true_type&
01162     )
01163     { assign_fromval(rows_a, cols_a, val); }
01164 
01165     template <typename Seq>
01166     void _assign_val_seq
01167     (
01168         size_type rows_a, size_type cols_a, const Seq& seq,
01169         const false_type&
01170     )
01171     { assign_fromseq(rows_a, cols_a, seq); }
01172 
01173 public:
01174 
01175     // ------------------------------------------------------------------
01176 
01177 
01180     //  @param seq sequence of init values */
01181     //template <typename Vec>
01182     //void assign (const Vec& vec, const diag_t& select)
01183     //{ assign_diag(vec); }
01184 
01185 
01188     //  @param val value on the diagonal */
01189     //template <typename Val>
01190     //void assign
01191     //(
01192     //  size_type rowscols_a, const Val& val,
01193     //  const diag_t& select_1,
01194     //  const fromval_t& select_2
01195     //)
01196     //{ assign_diag_fromval(rowscols_a, val); }
01197 
01198 
01201     //  @param seq sequence of init values */
01202     //template <typename Seq>
01203     //void assign
01204     //(
01205     //  size_type rowscols_a, const Seq& seq,
01206     //  const diag_t& select_1,
01207     //  const fromseq_t& select_2
01208     //)
01209     //{ assign_diag_fromseq(rowscols_a, seq); }
01210 
01211 
01214     //  @param seq sequence of init values */
01215     //template <typename Vec>
01216     //void assign
01217     //(
01218     //  size_type rowscols_a, const Vec& vec,
01219     //  const diag_t& select_1,
01220     //  const fromvec_t& select_2
01221     //)
01222     //{ assign_diag_fromvec(rowscols_a, vec); }
01223 
01224 
01226     //template <typename X>
01227     //void assign
01228     //(
01229     //  size_type rowscols_a, const X& x,
01230     //  const diag_t& select
01231     //)
01232     //{ assign_diag(rowscols_a, x); }
01233 
01234 
01237     //  @param cols_a   number of columns
01238     //  @param val value on the diagonal */
01239     //template <typename Val>
01240     //void assign
01241     //(
01242     //  size_type rows_a, size_type cols_a,
01243     //  const Val& val,
01244     //  const diag_t& select_1,
01245     //  const fromval_t& select_2
01246     //)
01247     //{ assign_diag_fromval(rows_a, cols_a, val); }
01248 
01249 
01252     //  @param cols_a   number of columns
01253     //  @param seq sequence of init values */
01254     //template <typename Seq>
01255     //void assign
01256     //(
01257     //  size_type rows_a, size_type cols_a, const Seq& seq,
01258     //  const diag_t& select_1,
01259     //  const fromseq_t& select_2
01260     //)
01261     //{ assign_diag_fromseq(rows_a, cols_a, seq); }
01262 
01263 
01266     //  @param cols_a   number of columns
01267     //  @param vec sequence of init values */
01268     //template <typename Vec>
01269     //void assign
01270     //(
01271     //  size_type rows_a, size_type cols_a, const Vec& vec,
01272     //  const diag_t& select_1,
01273     //  const fromvec_t& select_2
01274     //)
01275     //{ assign_diag_fromvec(rows_a, cols_a, vec); }
01276 
01277 
01280     //  @param cols_a   number of columns
01281     //  @param x    Meaning of this parameter depends on a structure of X. */
01282     //template <typename X>
01283     //void assign
01284     //(
01285     //  size_type rows_a, size_type cols_a,
01286     //  const X& x,
01287     //  const diag_t& select
01288     //)
01289     //{ assign_diag(rows_a, cols_a, x); }
01290 
01291 
01293 
01294 
01297     //  @param select helper argument for choosing this constructor,
01298     //      use eye  */
01299     //void assign (size_type rowscols_a, const eye_t& select)
01300     //{ assign_eye(rowscols_a); }
01301 
01302 
01305     //  @param select helper argument for choosing this constructor,
01306     //      use eye  */
01307     //void assign
01308     //(
01309     //  size_type rows_a, size_type cols_a,
01310     //  const eye_t& select
01311     //)
01312     //{ assign_eye(rows_a, cols_a); }
01313 
01314 
01315     // ------------------------------------------------------------------
01316 
01317     template <typename X>
01318     matrix& operator= (const X& x)
01319     {
01320         _assign_from_val_str_vec_mat
01321         (
01322             x, type_traits<X>::category_value,
01323             bool_type<type_pair_traits<X, T>::is_assignable>::value
01324         );
01325         
01326         return *this;
01327     }
01328 
01329 private:
01330 
01331     template <typename Val>
01332     void _assign_from_val_str_vec_mat
01333     (const Val& val, const type_category::type&, const true_type&)
01334     { fill_fromval(val); }
01335 
01336     template <typename Str>
01337     void _assign_from_val_str_vec_mat
01338     (const Str& str, const type_category::string&, const false_type&)
01339     { assign_fromstr(str); }
01340 
01341     template <typename Vec>
01342     void _assign_from_val_str_vec_mat
01343     (const Vec& vec, const type_category::vector&, const false_type&)
01344     { assign_fromvec(vec); }
01345 
01346     template <typename Mat>
01347     void _assign_from_val_str_vec_mat
01348     (const Mat& mat, const type_category::matrix&, const false_type&)
01349     { assign_frommat(mat); }
01350 
01351 public:
01352 
01354 
01355 #if 0
01356 
01358 
01359     template <typename T1, bool REFCNT1>
01360     matrix& operator= (const matrix<T1, REFCNT1>& x)
01361     {
01362         ARAGELI_ASSERT_1
01363         (
01364             reinterpret_cast<const void*>(this) !=
01365             reinterpret_cast<const void*>(&x)
01366         );
01367 
01368         unique_clear();
01369         rep().assign(x.nrows(), x.ncols(), x.mem().begin(), x.mem().end());
01370         return *this;
01371     }
01372 
01374     template <typename T1>
01375     matrix& operator= (const T1& v)
01376     {
01377         unique_clear();
01378         std::fill(mem().begin(), mem().end(), v);
01379         return *this;
01380     }
01381 
01382     matrix& operator= (const char* s)
01383     { return *this = matrix(s); }
01384 
01385 
01387     void assign ()
01388     {
01389         unique_clear();
01390         mem().clear();
01391         rep().rows = 0;
01392         rep().cols = 0;
01393     }
01394 
01395 
01397 
01399     void assign (size_type rowscols_a)
01400     {
01401         unique_clear();
01402         rep().assign(rowscols_a, rowscols_a, factory<T>::null());
01403     }
01404 
01405 
01407 
01412     void assign (size_type rows_a, size_type cols_a)
01413     {
01414         unique_clear();
01415         rep().assign(rows_a, cols_a, factory<T>::null());
01416     }
01417     
01418 
01420 
01422     void assign
01423     (
01424         size_type rows_a, size_type cols_a,
01425         const nonsquare_t& select
01426     )
01427     {
01428         unique_clear();
01429         rep().assign(rows_a, cols_a, factory<T>::null());
01430     }
01431 
01432 
01433     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01434 
01435 
01437 
01440     template <typename T1>
01441     void assign (size_type rowscols_a, const T1& val, const fromval_t& select)
01442     { assign_fromval(rowscols_a, val); }
01443 
01444 
01446 
01450     template <typename In>
01451     void assign (size_type rowscols_a, const In& in, const fromseq_t& select)
01452     { assign_fromseq(rowscols_a, in); }
01453 
01454 
01456 
01459     template <typename T1>
01460     void assign_fromval (size_type rowscols_a, const T1& val)
01461     {
01462         unique_clear();
01463         rep().assign(rowscols_a, rowscols_a, val);
01464     }
01465 
01466 
01468 
01472     template <typename In>
01473     void assign_fromseq (size_type rowscols_a, const In& in)
01474     {
01475         unique_clear();
01476         In last = in;
01477         std::advance(last, rowscols_a*rowscols_a);  // WARNING! Temporary solution.
01478         rep().assign(rowscols_a, rowscols_a, in, last);
01479     }
01480 
01481 
01483 
01494     template <typename In_or_T1>
01495     void assign (size_type rowscols_a, const In_or_T1& x)
01496     {
01497         assign_from_seq_or_val
01498         (
01499             rowscols_a, x,
01500             bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01501         );
01502     }
01503 
01504 
01505     template <typename In_or_T1>
01506     void assign_from_seq_or_val
01507     (size_type rowscols_a, const In_or_T1& x, const true_type&)
01508     { assign_fromval(rowscols_a, x); }
01509 
01510 
01511     template <typename In_or_T1>
01512     void assign_from_seq_or_val
01513     (size_type rowscols_a, const In_or_T1& x, const false_type&)
01514     { assign_fromseq(rowscols_a, x); }
01515 
01516 
01517     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01518 
01519 
01521 
01524     template <typename T1>
01525     void assign
01526     (
01527         size_type rows_a, size_type cols_a,
01528         const T1& val, const fromval_t& select
01529     )
01530     { assign_fromval(rows_a, cols_a, val); }
01531 
01532 
01534 
01538     template <typename In>
01539     void assign
01540     (
01541         size_type rows_a, size_type cols_a,
01542         const In& in, const fromseq_t& select
01543     )
01544     { assign_fromseq(rows_a, cols_a, in); }
01545 
01546 
01548 
01551     template <typename T1>
01552     void assign_fromval (size_type rows_a, size_type cols_a, const T1& val)
01553     {
01554         unique_clear();
01555         rep().assign(rows_a, cols_a, val);
01556     }
01557 
01558 
01560 
01564     template <typename In>
01565     void assign_fromseq (size_type rows_a, size_type cols_a, const In& in)
01566     {
01567         unique_clear();
01568         In last = in;
01569         std::advance(last, rows_a*cols_a);  // WARNING! Temporary solution.
01570         rep().assign(rows_a, cols_a, in, last);
01571     }
01572 
01573 
01575 
01586     template <typename In_or_T1>
01587     void assign (size_type rows_a, size_type cols_a, const In_or_T1& x)
01588     {
01589         assign_from_seq_or_val
01590         (
01591             rows_a, cols_a, x,
01592             bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01593         );
01594     }
01595 
01596 
01597     template <typename In_or_T1>
01598     void assign_from_seq_or_val
01599     (size_type rows_a, size_type cols_a, const In_or_T1& x, const true_type&)
01600     { assign_fromval(rows_a, cols_a, x); }
01601 
01602 
01603     template <typename In_or_T1>
01604     void assign_from_seq_or_val
01605     (size_type rows_a, size_type cols_a, const In_or_T1& x, const false_type&)
01606     { assign_fromseq(rows_a, cols_a, x); }
01607 
01608     
01609     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01610 
01611 
01613 
01617     template <typename In>
01618     void assign
01619     (
01620         size_type rowscols_a, const In& in,
01621         const colwise_t& select
01622     )
01623     { assign_colwise(rowscols_a, in); }
01624 
01625 
01627 
01631     template <typename In>
01632     void assign
01633     (
01634         size_type rows_a, size_type cols_a,
01635         const In& in,
01636         const colwise_t& select
01637     )
01638     { assign_colwise(rows_a, cols_a, in); }
01639 
01640 
01642 
01646     template <typename In>
01647     void assign_colwise (size_type rowscols_a, const In& in)
01648     { assign_colwise(rowscols_a, rowscols_a, in); }
01649 
01650 
01652 
01656     template <typename In>
01657     void assign_colwise
01658     (size_type rows_a, size_type cols_a, In in);
01659 
01660 
01661     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01662 
01663 
01665 
01668     template <typename T1>
01669     void assign
01670     (
01671         size_type rowscols_a, const T1& val,
01672         const diag_t& select_1,
01673         const fromval_t& select_2
01674     )
01675     { assign_diag_fromval(rowscols_a, val); }
01676 
01677 
01679 
01683     template <typename In>
01684     void assign
01685     (
01686         size_type rowscols_a, const In& in,
01687         const diag_t& select_1,
01688         const fromseq_t& select_2
01689     )
01690     { assign_diag_fromseq(rowscols_a, in); }
01691 
01692 
01694 
01697     template <typename T1>
01698     void assign_diag_fromval (size_type rowscols_a, const T1& val)
01699     { assign_diag_fromval(rowscols_a, rowscols_a, val); }
01700 
01701 
01703 
01707     template <typename In>
01708     void assign_diag_fromseq (size_type rowscols_a, const In& in)
01709     { assign_diag_fromseq(rowscols_a, rowscols_a, in); }
01710 
01711 
01713 
01725     template <typename In_or_T1>
01726     void assign_diag (size_type rowscols_a, const In_or_T1& x)
01727     {
01728         assign_diag_from_seq_or_val
01729         (
01730             rowscols_a, x,
01731             bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01732         );
01733     }
01734 
01735 
01737 
01738     template <typename In_or_T1>
01739     void assign
01740     (
01741         size_type rowscols_a, const In_or_T1& x,
01742         const diag_t& select_1
01743     )
01744     { assign_diag(rowscols_a, x); }
01745 
01746 
01747     template <typename In_or_T1>
01748     void assign_diag_from_seq_or_val
01749     (size_type rowscols_a, const In_or_T1& x, const true_type&)
01750     { assign_diag_fromval(rowscols_a, x); }
01751 
01752 
01753     template <typename In_or_T1>
01754     void assign_diag_from_seq_or_val
01755     (size_type rowscols_a, const In_or_T1& x, const false_type&)
01756     { assign_diag_fromseq(rowscols_a, x); }
01757 
01758 
01759     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01760 
01761 
01763 
01766     template <typename T1>
01767     void assign
01768     (
01769         size_type rows_a, size_type cols_a,
01770         const T1& val,
01771         const diag_t& select_1,
01772         const fromval_t& select_2
01773     )
01774     { assign_diag_fromval(rows_a, cols_a, val); }
01775 
01776 
01778 
01782     template <typename In>
01783     void assign
01784     (
01785         size_type rows_a, size_type cols_a,
01786         const In& in,
01787         const diag_t& select_1,
01788         const fromseq_t& select_2
01789     )
01790     { assign_diag_fromseq(rows_a, cols_a, in); }
01791 
01792 
01794 
01797     template <typename T1>
01798     void assign_diag_fromval (size_type rows_a, size_type cols_a, const T1& val);
01799 
01800 
01802 
01806     template <typename In>
01807     void assign_diag_fromseq (size_type rows_a, size_type cols_a, In in);
01808 
01809 
01811 
01823     template <typename In_or_T1>
01824     void assign_diag
01825     (
01826         size_type rows_a, size_type cols_a,
01827         const In_or_T1& x
01828     )
01829     {
01830         assign_diag_from_seq_or_val
01831         (
01832             rows_a, cols_a, x,
01833             bool_type<type_pair_traits<In_or_T1, T>::is_convertible>::value
01834         );
01835     }
01836 
01837 
01839 
01840     template <typename In_or_T1>
01841     void assign
01842     (
01843         size_type rows_a, size_type cols_a,
01844         const In_or_T1& x,
01845         const diag_t& select_1
01846     )
01847     { assign_diag(rows_a, cols_a, x); }
01848 
01849 
01850     template <typename In_or_T1>
01851     void assign_diag_from_seq_or_val
01852     (
01853         size_type rows_a, size_type cols_a,
01854         const In_or_T1& x, const true_type&
01855     )
01856     { assign_diag_fromval(rows_a, cols_a, x); }
01857 
01858 
01859     template <typename In_or_T1>
01860     void assign_diag_from_seq_or_val
01861     (
01862         size_type rows_a, size_type cols_a,
01863         const In_or_T1& x, const false_type&
01864     )
01865     { assign_diag_fromseq(rows_a, cols_a, x); }
01866 
01867 
01868 
01869 
01872     //  square_matrix_t parameter if types size_type and T are correlated
01873     //  and overloading is not worked.
01874     //  @param rowscols_a size of a matrix, it is number of rows
01875     //      (or number of columns)
01876     //  @param val value for initialization of each item
01877     //  @param select helper argument for choosing this constructor,
01878     //      use square_matrix  */
01879     //void assign (size_type rowscols_a, T val, const square_matrix_t& select)
01880     //{
01881     //  unique_clear();
01882     //  rep().assign(rowscols_a, rowscols_a, val);
01883     //}
01884 
01885 
01888     //  @param cols_a number of columns
01889     //  @param val value for initialization of each items,
01890     //      by default this is TT::null() */
01891     //void assign (size_type rows_a, size_type cols_a, T val = factory<T>::null())
01892     //{
01893     //  unique_clear();
01894     //  rep().assign(rows_a, cols_a, val);
01895     //}
01896 
01897 
01899 
01900 
01903     //  @param val value on the diagonal
01904     //  @param select helper argument for choosing this constructor,
01905     //      use diag  */
01906     //void assign (size_type rowscols_a, const T val, const diag_t& select);
01907 
01908     //void assign
01909     //(
01910     //  size_type rows_a, size_type cols_a,
01911     //  const T val, const diag_t& select
01912     //);
01913 
01915 
01918     void assign
01919     (
01920         size_type rowscols_a,
01921         const eye_t& select
01922     )
01923     {
01924         unique_clear();
01925         assign_diag_fromval(rowscols_a, factory<T>::unit());
01926     }
01927 
01929 
01933     void assign
01934     (
01935         size_type rows_a, size_type cols_a,
01936         const eye_t& select
01937     )
01938     {
01939         unique_clear();
01940         assign_diag_fromval(rows_a, cols_a, factory<T>::unit());
01941     }
01942 
01943 #endif
01944 
01945     // @}
01946 
01947 
01948     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01950 
01951 
01952     // @{
01953 
01955 
01956     const_reference el (size_type i, size_type j) const
01957     {
01958         ARAGELI_ASSERT_0(i < nrows() && j < ncols());
01959         return mem(i*ncols() + j);
01960     }
01961     
01963 
01964     reference el (size_type i, size_type j)
01965     {
01966         ARAGELI_ASSERT_0(i < nrows() && j < ncols());
01967         unique();
01968         return mem(i*ncols() + j);
01969     }
01970 
01972 
01973     const_reference operator() (size_type i, size_type j) const
01974     { return el(i, j); }
01975     
01977 
01978     reference operator() (size_type i, size_type j)
01979     { return el(i, j); }
01980 
01982 
01984     const_reference at (size_type i, size_type j) const
01985     {
01986         if(i > nrows() || j > ncols())throw out_of_range();
01987         return el(i, j);
01988     }
01989     
01991 
01993     reference at (size_type i, size_type j)
01994     {
01995         if(i > nrows() || j > ncols())throw out_of_range();
01996         return el(i, j);
01997     }
01998 
01999     // @}
02000 
02001 
02002     void resize (size_type rows_a, size_type cols_a)
02003     {
02004         unique_clear();
02005         mem().resize(rows_a*cols_a);
02006         rep().rows = rows_a;
02007         rep().cols = cols_a;
02008     }
02009 
02010 
02011     bool pack ()
02012     {
02013         if(size() != capacity())
02014         {
02015             do_pack();
02016             return true;
02017         }
02018         else return false;
02019     }
02020 
02021 
02022     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
02023     // Some properties access.
02024 
02025 
02027     size_type nrows () const { return rep().rows; }
02028 
02030     size_type ncols () const { return rep().cols; }
02031     
02033     size_type size () const { return mem().size(); }
02034 
02036 
02039     size_type length () const { return std::max(nrows(), ncols()); }
02040 
02041     size_type capacity () const { return mem().capacity(); }
02042 
02044 
02047     bool is_empty () const
02048     {
02049         ARAGELI_ASSERT_1(!mem().empty() || (nrows() == 0 || ncols() == 0));
02050         return mem().empty();
02051     }
02052 
02054 
02057     bool is_null () const;
02058 
02060 
02063     bool is_unit () const;
02064 
02066 
02069     bool is_opposite_unit () const;
02070 
02072 
02073     bool is_square () const { return nrows() == ncols(); }
02074 
02075 
02076     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
02077     // Some modificatory operations.
02078 
02079 
02081 
02083     matrix& opposite ();
02084 
02086 
02090     matrix& inverse ();
02091 
02093 
02095     matrix& each_inverse ();
02096 
02097 
02098     template <typename T1> matrix& add_scalar (const T1& x);
02099     template <typename T1> matrix& sub_scalar (const T1& x);
02100     template <typename T1> matrix& mul_scalar (const T1& x);
02101     template <typename T1> matrix& div_scalar (const T1& x);
02102     template <typename T1> matrix& mod_scalar (const T1& x);
02103     template <typename T1> matrix& bitand_scalar (const T1& x);
02104     template <typename T1> matrix& bitor_scalar (const T1& x);
02105     template <typename T1> matrix& bitxor_scalar (const T1& x);
02106     template <typename T1> matrix& shl_scalar (const T1& x);
02107     template <typename T1> matrix& shr_scalar (const T1& x);
02108     
02109     template <typename T1> matrix& add_matrix (const T1& x) { return each_add_matrix(x); }
02110     template <typename T1> matrix& sub_matrix (const T1& x) { return each_sub_matrix(x); }
02111     template <typename T1> matrix& mul_matrix (const T1& x);
02112     template <typename T1> matrix& div_matrix (const T1& x);
02113     template <typename T1> matrix& mod_matrix (const T1& x) { return each_mod_matrix(x); }
02114     template <typename T1> matrix& bitand_matrix (const T1& x) { return each_bitand_matrix(x); }
02115     template <typename T1> matrix& bitor_matrix (const T1& x) { return each_bitor_matrix(x); }
02116     template <typename T1> matrix& bitxor_matrix (const T1& x) { return each_bitxor_matrix(x); }
02117     template <typename T1> matrix& shl_matrix (const T1& x) { return each_shl_matrix(x); }
02118     template <typename T1> matrix& shr_matrix (const T1& x) { return each_shr_matrix(x); }
02119 
02120     template <typename T1> matrix& each_add_matrix (const T1& x);
02121     template <typename T1> matrix& each_sub_matrix (const T1& x);
02122     template <typename T1> matrix& each_mul_matrix (const T1& x);
02123     template <typename T1> matrix& each_div_matrix (const T1& x);
02124     template <typename T1> matrix& each_mod_matrix (const T1& x);
02125     template <typename T1> matrix& each_bitand_matrix (const T1& x);
02126     template <typename T1> matrix& each_bitor_matrix (const T1& x);
02127     template <typename T1> matrix& each_bitxor_matrix (const T1& x);
02128     template <typename T1> matrix& each_shl_matrix (const T1& x);
02129     template <typename T1> matrix& each_shr_matrix (const T1& x);
02130 
02131 
02138 
02139     template <typename T1> matrix& operator+= (const T1& x) { return add_scalar(x); }
02140     template <typename T1> matrix& operator-= (const T1& x) { return sub_scalar(x); }
02141     template <typename T1> matrix& operator*= (const T1& x) { return mul_scalar(x); }
02142     template <typename T1> matrix& operator/= (const T1& x) { return div_scalar(x); }
02143     template <typename T1> matrix& operator%= (const T1& x) { return mod_scalar(x); }
02144     template <typename T1> matrix& operator&= (const T1& x) { return bitand_scalar(x); }
02145     template <typename T1> matrix& operator|= (const T1& x) { return bitor_scalar(x); }
02146     template <typename T1> matrix& operator^= (const T1& x) { return bitxor_scalar(x); }
02147     template <typename T1> matrix& operator<<= (const T1& x) { return shl_scalar(x); }
02148     template <typename T1> matrix& operator>>= (const T1& x) { return shr_scalar(x); }
02149 
02150     // BEGIN OF TEMPORARY EXTENTION
02151     
02152     matrix& operator+= (const T& x) { return add_scalar(x); }
02153     matrix& operator-= (const T& x) { return sub_scalar(x); }
02154     matrix& operator*= (const T& x) { return mul_scalar(x); }
02155     matrix& operator/= (const T& x) { return div_scalar(x); }
02156     matrix& operator%= (const T& x) { return mod_scalar(x); }
02157     matrix& operator&= (const T& x) { return bitand_scalar(x); }
02158     matrix& operator|= (const T& x) { return bitor_scalar(x); }
02159     matrix& operator^= (const T& x) { return bitxor_scalar(x); }
02160     matrix& operator<<= (const T& x) { return shl_scalar(x); }
02161     matrix& operator>>= (const T& x) { return shr_scalar(x); }
02162 
02163     // END OF TEMPORARY EXTENTION
02164 
02165 
02166     // @}
02167 
02168 
02175 
02176     template <typename T1, bool REFCNT1>
02177     matrix& operator+= (const matrix<T1, REFCNT1>& x) { return add_matrix(x); }
02178 
02179     template <typename T1, bool REFCNT1>
02180     matrix& operator-= (const matrix<T1, REFCNT1>& x) { return sub_matrix(x); }
02181 
02182     template <typename T1, bool REFCNT1>
02183     matrix& each_add (const matrix<T1, REFCNT1>& x) { return each_add_matrix(x); }
02184 
02185     template <typename T1, bool REFCNT1>
02186     matrix& each_sub (const matrix<T1, REFCNT1>& x) { return each_sub_matrix(x); }
02187 
02188     template <typename T1, bool REFCNT1>
02189     matrix& each_mul (const matrix<T1, REFCNT1>& x) { return each_mul_matrix(x); }
02190 
02191     template <typename T1, bool REFCNT1>
02192     matrix& each_div (const matrix<T1, REFCNT1>& x) { return each_div_matrix(x); }
02193 
02194     template <typename T1, bool REFCNT1>
02195     matrix& each_mod (const matrix<T1, REFCNT1>& x) { return each_mod_matrix(x); }
02196 
02197     template <typename T1, bool REFCNT1>
02198     matrix& each_bitand (const matrix<T1, REFCNT1>& x) { return each_bitand_matrix(x); }
02199 
02200     template <typename T1, bool REFCNT1>
02201     matrix& each_bitor (const matrix<T1, REFCNT1>& x) { return each_bitor_matrix(x); }
02202 
02203     template <typename T1, bool REFCNT1>
02204     matrix& each_bitxor (const matrix<T1, REFCNT1>& x) { return each_bitxor_matrix(x); }
02205 
02206     template <typename T1, bool REFCNT1>
02207     matrix& each_shl (const matrix<T1, REFCNT1>& x) { return each_shl_matrix(x); }
02208 
02209     template <typename T1, bool REFCNT1>
02210     matrix& each_shr (const matrix<T1, REFCNT1>& x) { return each_shr_matrix(x); }
02211 
02212     // @}
02213 
02214 
02216     template <typename T1, bool REFCNT1>
02217     matrix& operator*= (const matrix<T1, REFCNT1>& x) { return mul_matrix(x); }
02218 
02220 
02225     template <typename T1, bool REFCNT1>
02226     matrix& operator/= (const matrix<T1, REFCNT1>& x) { return div_matrix(x); }
02227 
02229 
02230     matrix operator- () const
02231     {
02232         matrix res(*this);
02233         return res.opposite();
02234     }
02235     
02237     const matrix& operator+ () const { return *this; }
02238 
02239     matrix& operator++ ()
02240     {
02241         std::for_each(begin(), end(), func::prefix_increment<T, T&>());
02242         return *this;
02243     }
02244 
02245     matrix operator++ (int) { matrix t = *this; operator++(); return t; }
02246 
02247     matrix& operator-- ()
02248     {
02249         std::for_each(begin(), end(), func::prefix_decrement<T, T&>());
02250         return *this;
02251     }
02252 
02253     matrix operator-- (int) { matrix t = *this; operator--(); return t; }
02254 
02255 
02256     //std::pair<size_type, size_type> find_max () const;
02257     //std::pair<size_type, size_type> find_min () const;
02258 
02260     void transpose ();
02261 
02263     template <typename T1, bool REFCNT1>
02264     void swap (matrix<T1, REFCNT1>& x)
02265     {
02266         _Internal::swap_help_1
02267             (*this, x, store, x.store, equal_types<T, T1>::value);
02268     }
02269 
02270 
02271     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
02273 
02274     
02275     // @{
02276 
02278 
02279     iterator begin () { unique(); return mem().begin(); }
02280     
02282 
02283     iterator end () { unique(); return mem().end(); }
02284 
02286     const_iterator begin () const { return mem().begin(); }
02287 
02289     const_iterator end () const { return mem().end(); }
02290 
02291     // @}
02292 
02293 
02294     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
02296 
02297 
02298     // @{
02299 
02301 
02302     void insert_row (size_type pos, const T& val);
02303     
02305 
02307     template <typename T1, bool REFCNT1>
02308     void insert_row (size_type pos, const vector<T1, REFCNT1>& vals);
02309 
02311 
02312     template <typename In>
02313     void insert_row (size_type pos, In first);
02314 
02316 
02317     void insert_rows (size_type pos, size_type n, const T& val);
02318     
02320 
02322     template <typename T1, bool REFCNT1>
02323     void insert_rows (size_type pos, size_type n, const vector<T1, REFCNT1>& vals);
02324 
02326 
02327     template <typename In>
02328     void insert_rows (size_type pos, size_type n, In first);
02329 
02331     void erase_row (size_type pos);
02332 
02334     void erase_rows (size_type pos, size_type n);
02335 
02337     void swap_rows (size_type xpos, size_type ypos);
02338 
02340     template <typename T1>
02341     void mult_row (size_type i, const T1& x);
02342     
02344     template <typename T1>
02345     void div_row (size_type i, const T1& x);
02346     
02348     template <typename T1>
02349     void mod_row (size_type i, const T1& x);
02350     
02352     void add_rows (size_type dstpos, size_type srcpos);
02353     
02355     void sub_rows (size_type dstpos, size_type srcpos);
02356 
02358     template <typename T2>
02359     void addmult_rows (size_type dstpos, size_type srcpos, const T2& y);
02360 
02362     template <typename T1, typename T2>
02363     void addmult_rows
02364     (
02365         size_type dstpos, const T1& x,
02366         size_type srcpos, const T2& y
02367     );
02368 
02369     // WARNING! TEMPORARY DECLARATION. Conflicts are possible.
02371     template <typename T1, typename T2>
02372     void addmult_rows
02373     (
02374         size_type dstpos, const T1& x,
02375         int srcpos, const T2& y
02376     )
02377     { addmult_rows(dstpos, x, size_type(srcpos), y); }
02378 
02379     // WARNING! TEMPORARY DECLARATION. Conflicts are possible.
02381     template <typename T1, typename V, typename T2>
02382     void addmult_rows
02383     (
02384         size_type dstpos, const T1& x,
02385         const V& srcvec, const T2& y
02386     );
02387 
02389     vector<T, true> copy_row (size_type i) const
02390     //{ return vector<T, true>(begin() + i*ncols(), begin() + (i + 1)*ncols()); }
02391     { return vector<T, true>(ncols(), begin() + i*ncols()); }
02392 
02394 
02395     template <typename V>
02396     V& copy_row (size_type i, V& res) const
02397     {
02398         //res.assign(begin() + i*ncols(), begin() + (i + 1)*ncols());
02399         res.assign(ncols(), begin() + i*ncols());
02400         return res;
02401     }
02402 
02403     template <typename SV>
02404     matrix<T, true> copy_rows (const SV& sv) const
02405     {
02406         matrix<T, true> res;
02407         return copy_rows(sv, res);
02408     }
02409 
02410     template <typename SV, typename M>
02411     M& copy_rows (const SV& sv, M& res) const;
02412     
02413     template <typename SV>
02414     void erase_rows (const SV& sv);
02415 
02416     template <typename SV, typename M>
02417     M& take_rows (const SV& sv, M& res)
02418     {
02419         copy_rows(sv, res);
02420         erase_rows(sv);
02421         return res;
02422     }
02423 
02424     template <typename SV>
02425     matrix<T, true> take_rows (const SV& sv)
02426     {
02427         matrix<T, true> res;
02428         return take_rows(sv, res);
02429     }
02430 
02431 
02432     template <typename V>
02433     V& take_row (size_type i, V& res)
02434     {
02435         copy_row(i, res);
02436         erase_row(i);
02437         return res;
02438     }
02439 
02440     vector<T, true> take_row (size_type i)
02441     {
02442         vector<T, true> res;
02443         return take_row(i, res);
02444     }
02445 
02446 
02447     template <typename V>
02448     void assign_row (size_type i, const V& v)
02449     {
02450         ARAGELI_ASSERT_0(i < nrows());
02451         ARAGELI_ASSERT_0(v.size() >= ncols());
02452         std::copy(v.begin(), v.begin() + ncols(), begin() + ncols()*i);
02453     }
02454 
02455 
02456     // @}
02457 
02458 
02459     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
02461     
02462     
02463     // @{
02464 
02466 
02467     void insert_col (size_type pos, const T& val);
02468     
02470 
02472     template <typename T1, bool REFCNT1>
02473     void insert_col (size_type pos, const vector<T1, REFCNT1>& vals);
02474 
02476 
02477     template <typename In>
02478     void insert_col (size_type pos, In first);
02479 
02481 
02482     void insert_cols (size_type pos, size_type n, const T& val);
02483     
02485 
02487     template <typename T1, bool REFCNT1>
02488     void insert_cols (size_type pos, size_type n, const vector<T1, REFCNT1>& vals);
02489 
02491 
02492     template <typename In>
02493     void insert_cols (size_type pos, size_type n, In first);
02494 
02496     void erase_col (size_type pos);
02497 
02499     void erase_cols (size_type pos, size_type n);
02500 
02502     void swap_cols (size_type xpos, size_type ypos);
02503 
02505     template <typename T1>
02506     void mult_col (size_type i, const T1& x);
02507     
02509     template <typename T1>
02510     void div_col (size_type i, const T1& x);
02511     
02513     template <typename T1>
02514     void mod_col (size_type i, const T1& x);
02515     
02517     void add_cols (size_type dstpos, size_type srcpos);
02518     
02520     void sub_cols (size_type dstpos, size_type srcpos);
02521 
02523     template <typename T2>
02524     void addmult_cols (size_type dstpos, size_type srcpos, const T2& y);
02525 
02527     template <typename T1, typename T2>
02528     void addmult_cols
02529     (
02530         size_type dstpos, const T1& x,
02531         size_type srcpos, const T2& y
02532     );
02533 
02535     template <typename T1, typename T2>
02536     void addmult_cols
02537     (
02538         size_type dstpos, const T1& x,
02539         int srcpos, const T2& y
02540     )
02541     { addmult_cols(dstpos, x, size_type(srcpos), y); }
02542 
02544     template <typename T1, typename V, typename T2>
02545     void addmult_cols
02546     (
02547         size_type dstpos, const T1& x,
02548         const V& srcvec, const T2& y
02549     );
02550 
02552     vector<T, true> copy_col (size_type i) const
02553     {
02554         vector<T, true> res;
02555         return copy_col(i, res);
02556     }
02557 
02559 
02560     template <typename V>
02561     V& copy_col (size_type i, V& res) const;
02562 
02563     template <typename SV>
02564     matrix<T, true> copy_cols (const SV& sv) const
02565     {
02566         matrix<T, true> res;
02567         return copy_cols(sv, res);
02568     }
02569 
02570     template <typename SV, typename M>
02571     M& copy_cols (const SV& sv, M& res) const;
02572     
02573     template <typename SV>
02574     void erase_cols (const SV& sv);
02575 
02576     template <typename SV, typename M>
02577     M& take_cols (const SV& sv, M& res)
02578     {
02579         copy_cols(sv, res);
02580         erase_cols(sv);
02581         return res;
02582     }
02583 
02584     template <typename SV>
02585     matrix<T, true> take_cols (const SV& sv)
02586     {
02587         matrix<T, true> res;
02588         return take_cols(sv, res);
02589     }
02590 
02591     template <typename V>
02592     V& take_col (size_type i, V& res)
02593     {
02594         copy_col(i, res);
02595         erase_col(i);
02596         return res;
02597     }
02598 
02599     vector<T, true> take_col (size_type i)
02600     {
02601         vector<T, true> res;
02602         return take_col(i, res);
02603     }
02604 
02605     template <typename V>
02606     void assign_col (size_type j, const V& v)
02607     {
02608         ARAGELI_ASSERT_0(j < ncols());
02609         ARAGELI_ASSERT_0(v.size() >= nrows());
02610         
02611         for(size_type i = 0; i < nrows(); ++i)
02612             el(i, j) = v[i];
02613     }
02614 
02615     // @}
02616 
02617 
02618     template <typename M>
02619     void insert_matrix_bottom (const M& m)
02620     {
02621         ARAGELI_ASSERT_0(m.ncols() == ncols());
02622         
02623         // TODO: Make it faster!
02624         for(size_type i = 0; i < m.nrows(); ++i)
02625             insert_row(nrows(), m.copy_row(i));
02626     }
02627 
02628 
02629     template <typename RS, typename CS>
02630     matrix<T, true> copy_submatrix (const RS& rs, const CS& cs) const
02631     {
02632         matrix<T, true> res;
02633         return copy_submatrix(rs, cs, res);
02634     }
02635 
02636     template <typename RS, typename CS, typename M>
02637     M& copy_submatrix (const RS& rs, const CS& cs, M& res) const;
02638 
02639     template <typename RS, typename CS>
02640     void erase_submatrix (const RS& rs, const CS& cs);
02641 
02642     template <typename RS, typename CS, typename M>
02643     M& take_submatrix (const RS& rs, const CS& cs, M& res)
02644     {
02645         copy_submatrix(rs, cs, res);
02646         erase_submatrix(rs, cs);
02647         return res;
02648     }
02649 
02650     template <typename RS, typename CS>
02651     matrix<T, true> take_submatrix (const RS& rs, const CS& cs)
02652     {
02653         matrix<T, true> res;
02654         return take_submatrix(rs, cs, res);
02655     }
02656 
02657 
02659 
02666     bool unique () { return store.unique(); }
02667 
02669 
02674     bool unique_clear () { return store.unique_clear(); }
02675 
02676 private:
02677 
02678     Rep& rep () { return store.value(); }
02679     const Rep& rep () const { return store.value(); }
02680 
02681     Mem& mem () { return rep().mem; }
02682     const Mem& mem () const { return rep().mem; }
02683 
02684     reference mem (size_type i) { return mem()[i]; }
02685     const_reference mem (size_type i) const { return mem()[i]; }
02686 
02687     bool do_pack ();
02688 
02689     refcntr_proxy<Rep, REFCNT> store;
02690 };
02691 
02692 
02693 #if 0
02694 
02696 template <typename TE2, bool REFCNTE2>
02697 struct type_pair_traits<big_int, matrix<TE2, REFCNTE2> >
02698     : public type_pair_traits_for_unknown_and_vector_matrix
02699         <big_int, matrix<TE2, REFCNTE2> > {};
02700 
02701 #endif
02702 
02703 template <typename T, bool REFCNT>
02704 matrix<T, true> transpose (const matrix<T, REFCNT>& a)
02705 {
02706     matrix<T, true> res = a;
02707     res.transpose();
02708     return res;
02709 }
02710 
02711 
02713 
02720 template
02721 <
02722     typename T1, bool REFCNT1,
02723     typename T2, bool REFCNT2
02724 >
02725 inline int cmp
02726 (
02727     const matrix<T1, REFCNT1>& a,
02728     const matrix<T2, REFCNT2>& b
02729 )
02730 {
02731     if(a.nrows() < b.nrows())return -1;
02732     if(a.nrows() > b.nrows())return +1;
02733     if(a.ncols() < b.ncols())return -1;
02734     if(a.ncols() > b.ncols())return +1;
02735     return _Internal::aggregate_cmp(a.begin(), a.end(), b.begin(), b.end());
02736 }
02737 
02738 
02739 
02740 #define _ARAGELI_MATRIX_CMP(OPER)                                           \
02741     template                                                                \
02742     <                                                                       \
02743         typename T1, bool REFCNT1,                                          \
02744         typename T2, bool REFCNT2                                           \
02745     >                                                                       \
02746     inline bool operator OPER                                               \
02747     (const matrix<T1, REFCNT1>& a, const matrix<T2, REFCNT2>& b)            \
02748     { return cmp(a, b) OPER 0; }                                            \
02749                                                                             \
02750     template                                                                \
02751     <                                                                       \
02752         typename T1, bool REFCNT1,                                          \
02753         typename T2                                                         \
02754     >                                                                       \
02755     inline bool operator OPER                                               \
02756     (const matrix<T1, REFCNT1>& a, const T2& b)                             \
02757     {                                                                       \
02758         return cmp                                                          \
02759         (                                                                   \
02760             a,                                                              \
02761             matrix<T2, false>(a.nrows(), a.ncols, b, fromsize)      \
02762         ) OPER 0;                                                           \
02763     }                                                                       \
02764                                                                             \
02765     template                                                                \
02766     <                                                                       \
02767         typename T1,                                                        \
02768         typename T2, bool REFCNT2                                           \
02769     >                                                                       \
02770     inline bool operator OPER                                               \
02771     (const T1& a, const matrix<T2, REFCNT2>& b)                             \
02772     {                                                                       \
02773         return cmp                                                          \
02774         (                                                                   \
02775             matrix<T2, false>(b.nrows(), b.ncols(), a, fromsize),   \
02776             b                                                               \
02777         ) OPER 0;                                                           \
02778     }
02779 
02780 
02782 // @{
02783 
02784 _ARAGELI_MATRIX_CMP(<=)
02785 _ARAGELI_MATRIX_CMP(>=)
02786 _ARAGELI_MATRIX_CMP(<)
02787 _ARAGELI_MATRIX_CMP(>)
02788 _ARAGELI_MATRIX_CMP(==)
02789 _ARAGELI_MATRIX_CMP(!=)
02790 
02791 // @}
02792 
02793 #undef _ARAGELI_MATRIX_CMP
02794 
02795 
02796 #define _ARAGELI_GENERIC_MATRIX_OPERATORS1(MNEM, OPERB)             \
02797 template <typename T1, typename T2, typename T3>                    \
02798 T3& each_##MNEM##_matrix_matrix (const T1& a, const T2& b, T3& res) \
02799 {                                                                   \
02800     ARAGELI_ASSERT_0(a.size() == b.size());                         \
02801     ARAGELI_ASSERT_0(res.size() == a.size());                       \
02802                                                                     \
02803     typename T1::const_iterator ia = a.begin(), iend = a.end();     \
02804     typename T2::const_iterator ib = b.begin();                     \
02805     typename T3::iterator ic = res.begin();                         \
02806                                                                     \
02807     for(; ia != iend; ++ia, ++ib, ++ic)                             \
02808         *ic = *ia OPERB *ib;                                        \
02809                                                                     \
02810     return res;                                                     \
02811 }                                                                   \
02812                                                                     \
02813 template <typename T1, typename T2, typename T3>                    \
02814 T3& MNEM##_matrix_scalar (const T1& a, const T2& b, T3& res)        \
02815 {                                                                   \
02816     ARAGELI_ASSERT_0(res.size() == a.size());                       \
02817                                                                     \
02818     typename T1::const_iterator ia = a.begin(), iend = a.end();     \
02819     typename T3::iterator ic = res.begin();                         \
02820                                                                     \
02821     for(; ia != iend; ++ia, ++ic)                                   \
02822         *ic = *ia OPERB b;                                          \
02823                                                                     \
02824     return res;                                                     \
02825 }                                                                   \
02826                                                                     \
02827 template <typename T1, typename T2, typename T3>                    \
02828 T3& MNEM##_scalar_matrix (const T1& a, const T2& b, T3& res)        \
02829 {                                                                   \
02830     ARAGELI_ASSERT_0(res.size() == b.size());                       \
02831                                                                     \
02832     typename T2::const_iterator ib = b.begin(), iend = b.end();     \
02833     typename T3::iterator ic = res.begin();                         \
02834                                                                     \
02835     for(; ib != iend; ++ib, ++ic)                                   \
02836         *ic = a OPERB *ib;                                          \
02837                                                                     \
02838     return res;                                                     \
02839 }
02840 
02841 
02842 _ARAGELI_GENERIC_MATRIX_OPERATORS1(add, +)
02843 _ARAGELI_GENERIC_MATRIX_OPERATORS1(sub, -)
02844 _ARAGELI_GENERIC_MATRIX_OPERATORS1(mul, *)
02845 _ARAGELI_GENERIC_MATRIX_OPERATORS1(div, /)
02846 _ARAGELI_GENERIC_MATRIX_OPERATORS1(mod, %)
02847 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitand, &)
02848 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitor, |)
02849 _ARAGELI_GENERIC_MATRIX_OPERATORS1(bitxor, ^)
02850 _ARAGELI_GENERIC_MATRIX_OPERATORS1(shl, <<)
02851 _ARAGELI_GENERIC_MATRIX_OPERATORS1(shr, >>)
02852 
02853 
02854 #define _ARAGELI_GENERIC_MATRIX_OPERATORS2(MNEM)                \
02855 template <typename T1, typename T2, typename T3>                \
02856 T3& MNEM##_matrix_matrix (const T1& a, const T2& b, T3& res)    \
02857 { return each_##MNEM##_matrix_matrix(a, b, res); }
02858 
02859 template <typename T1, typename T2, typename T3>
02860 T3& mul_matrix_matrix (const T1& a, const T2& b, T3& res)
02861 { res = a; return res.mul_matrix(b); }
02862 
02863 template <typename T1, typename T2, typename T3>
02864 T3& div_matrix_matrix (const T1& a, const T2& b, T3& res)
02865 { res = a; return res.div_matrix(b); }
02866 
02867 
02868 _ARAGELI_GENERIC_MATRIX_OPERATORS2(add)
02869 _ARAGELI_GENERIC_MATRIX_OPERATORS2(sub)
02870 _ARAGELI_GENERIC_MATRIX_OPERATORS2(mod)
02871 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitand)
02872 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitor)
02873 _ARAGELI_GENERIC_MATRIX_OPERATORS2(bitxor)
02874 _ARAGELI_GENERIC_MATRIX_OPERATORS2(shl)
02875 _ARAGELI_GENERIC_MATRIX_OPERATORS2(shr)
02876 
02877 
02878 #undef _ARAGELI_GENERIC_MATRIX_OPERATORS1
02879 #undef _ARAGELI_GENERIC_MATRIX_OPERATORS2
02880 
02881 
02882 #define _ARAGELI_MATRIX_BINARY_BY_UNARY(MNEM, OPERB)    \
02883     template                                            \
02884     <                                                   \
02885         typename T1, bool REFCNT1,                      \
02886         typename T2, bool REFCNT2                       \
02887     >                                                   \
02888     inline matrix<T1, REFCNT1> operator OPERB           \
02889     (                                                   \
02890         const matrix<T1, REFCNT1>& a,                   \
02891         const matrix<T2, REFCNT2>& b                    \
02892     )                                                   \
02893     {                                                   \
02894         matrix<T1, REFCNT1> t                           \
02895             (a.nrows(), a.ncols(), fromsize);   \
02896         return MNEM##_matrix_matrix(a, b, t);           \
02897     }                                                   \
02898                                                         \
02899     template                                            \
02900     <                                                   \
02901         typename T1, bool REFCNT1,                      \
02902         typename T2                                     \
02903     >                                                   \
02904     inline matrix<T1, REFCNT1> operator OPERB           \
02905     (                                                   \
02906         const matrix<T1, REFCNT1>& a,                   \
02907         const T2& b                                     \
02908     )                                                   \
02909     {                                                   \
02910         matrix<T1, REFCNT1> t                           \
02911             (a.nrows(), a.ncols(), fromsize);   \
02912         return MNEM##_matrix_scalar(a, b, t);           \
02913     }                                                   \
02914                                                         \
02915     template                                            \
02916     <                                                   \
02917         typename T1,                                    \
02918         typename T2, bool REFCNT2                       \
02919     >                                                   \
02920     inline matrix<T2, REFCNT2> operator OPERB           \
02921     (                                                   \
02922         const T1& a,                                    \
02923         const matrix<T2, REFCNT2>& b                    \
02924     )                                                   \
02925     {                                                   \
02926         matrix<T2, REFCNT2> t                           \
02927             (b.nrows(), b.ncols(), fromsize);   \
02928         return MNEM##_scalar_matrix(a, b, t);           \
02929     }                                                   \
02930                                                         \
02931     template <typename T1, bool REFCNT1>                \
02932     inline matrix<T1, REFCNT1> operator OPERB           \
02933     (                                                   \
02934         const matrix<T1, REFCNT1>& a,                   \
02935         const T1& b                                     \
02936     )                                                   \
02937     {                                                   \
02938         matrix<T1, REFCNT1> t                           \
02939             (a.nrows(), a.ncols(), fromsize);   \
02940         return MNEM##_matrix_scalar(a, b, t);           \
02941     }                                                   \
02942                                                         \
02943     template <typename T2, bool REFCNT2>                \
02944     inline matrix<T2, REFCNT2> operator OPERB           \
02945     (                                                   \
02946         const T2& a,                                    \
02947         const matrix<T2, REFCNT2>& b                    \
02948     )                                                   \
02949     {                                                   \
02950         matrix<T2, REFCNT2> t                           \
02951             (b.nrows(), b.ncols(), fromsize);   \
02952         return MNEM##_scalar_matrix(a, b, t);           \
02953     }                                                   \
02954                                                         \
02955     /* BEGIN OF TEMPORARY EXTENTION */                  \
02956     template <typename T1, bool REFCNT1>                \
02957     inline matrix<rational<T1>, REFCNT1>                \
02958     operator OPERB                                      \
02959     (                                                   \
02960         const matrix<rational<T1>, REFCNT1>& a,         \
02961         const rational<T1>& b                           \
02962     )                                                   \
02963     {                                                   \
02964         matrix<rational<T1>, REFCNT1> t                 \
02965             (a.nrows(), a.ncols(), fromsize);   \
02966         return MNEM##_matrix_scalar(a, b, t);           \
02967     }                                                   \
02968                                                         \
02969     template <typename T2, bool REFCNT2>                \
02970     inline matrix<rational<T2>, REFCNT2>                \
02971     operator OPERB                                      \
02972     (                                                   \
02973         const rational<T2>& a,                          \
02974         const matrix<rational<T2>, REFCNT2>& b          \
02975     )                                                   \
02976     {                                                   \
02977         matrix<rational<T2>, REFCNT2> t                 \
02978             (b.nrows(), b.ncols(), fromsize);   \
02979         return MNEM##_scalar_matrix(a, b, t);           \
02980     }                                                   \
02981                                                         \
02982     template                                            \
02983     <                                                   \
02984             typename T1, typename D1,                   \
02985             bool REFCNT1, bool REFCNT2                  \
02986     >                                                   \
02987     inline matrix<sparse_polynom                        \
02988         <T1, D1, REFCNT1>, REFCNT2>                     \
02989     operator OPERB                                      \
02990     (                                                   \
02991         const matrix<sparse_polynom                     \
02992             <T1, D1, REFCNT1>, REFCNT2>& a,             \
02993         const sparse_polynom<T1, D1, REFCNT1>& b        \
02994     )                                                   \
02995     {                                                   \
02996         matrix<sparse_polynom                           \
02997             <T1, D1, REFCNT1>, REFCNT2> t               \
02998             (a.nrows(), a.ncols(), fromsize);   \
02999         return MNEM##_matrix_scalar(a, b, t);           \
03000     }                                                   \
03001                                                         \
03002     template                                            \
03003     <                                                   \
03004             typename T1, typename D1,                   \
03005             bool REFCNT1, bool REFCNT2                  \
03006     >                                                   \
03007     inline matrix<sparse_polynom                        \
03008         <T1, D1, REFCNT1>, REFCNT2>                     \
03009     operator OPERB                                      \
03010     (                                                   \
03011         const sparse_polynom<T1, D1, REFCNT1>& a,       \
03012         const matrix<sparse_polynom                     \
03013             <T1, D1, REFCNT1>, REFCNT2>& b              \
03014     )                                                   \
03015     {                                                   \
03016         matrix<sparse_polynom                           \
03017             <T1, D1, REFCNT1>, REFCNT2> t               \
03018             (b.nrows(), b.ncols(), fromsize);   \
03019         return MNEM##_scalar_matrix(a, b, t);           \
03020     }
03021     /* END OF TEMPORARY EXTENTION */
03022 
03023 
03025 // @{
03026 
03027 _ARAGELI_MATRIX_BINARY_BY_UNARY(add, +)
03028 _ARAGELI_MATRIX_BINARY_BY_UNARY(sub, -)
03029 _ARAGELI_MATRIX_BINARY_BY_UNARY(mul, *)
03030 _ARAGELI_MATRIX_BINARY_BY_UNARY(div, /)
03031 _ARAGELI_MATRIX_BINARY_BY_UNARY(mod, %)
03032 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitand, &)
03033 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitor, |)
03034 _ARAGELI_MATRIX_BINARY_BY_UNARY(bitxor, ^)
03035 _ARAGELI_MATRIX_BINARY_BY_UNARY(shl, <<)
03036 _ARAGELI_MATRIX_BINARY_BY_UNARY(shr, >>)
03037 
03038 // @}
03039 
03040 
03041 #undef _ARAGELI_MATRIX_BINARY_BY_UNARY
03042 
03043 
03044 //#define _ARAGELI_MATRIX_BINARY_BY_UNARY(OPERU, OPERB) \
03045 //  template                                            \
03046 //  <                                                   \
03047 //      typename T1, bool REFCNT1,                      \
03048 //      typename T2, bool REFCNT2                       \
03049 //  >                                                   \
03050 //  inline matrix<T1, REFCNT1> operator OPERB           \
03051 //  (                                                   \
03052 //      const matrix<T1, REFCNT1>& a,                   \
03053 //      const matrix<T2, REFCNT2>& b                    \
03054 //  )                                                   \
03055 //  {                                                   \
03056 //      matrix<T1, REFCNT1> t(a);                       \
03057 //      return t OPERU b;                               \
03058 //  }
03059 //
03060 //  
03061 //#define _ARAGELI_MATRIX_BINARY_SCALAR(OPERU, OPERB)           \
03062 //  template                                                \
03063 //  <                                                       \
03064 //      typename T1, bool REFCNT1,                          \
03065 //      typename T2                                         \
03066 //  >                                                       \
03067 //  inline matrix<T1, REFCNT1> operator OPERB               \
03068 //  (                                                       \
03069 //      const matrix<T1, REFCNT1>& a,                       \
03070 //      const T2& b                                         \
03071 //  )                                                       \
03072 //  {                                                       \
03073 //      matrix<T1, REFCNT1> t(a);                           \
03074 //      return t OPERB##= b;                                \
03075 //  }                                                       \
03076 //                                                          \
03077 //  template                                                \
03078 //  <                                                       \
03079 //      typename T1,                                        \
03080 //      typename T2, bool REFCNT2                           \
03081 //  >                                                       \
03082 //  inline matrix<T2, REFCNT2> operator OPERB               \
03083 //  (                                                       \
03084 //      const T1& a,                                        \
03085 //      const matrix<T2, REFCNT2>& b                        \
03086 //  )                                                       \
03087 //  {                                                       \
03088 //      /* создавать матрицу скаляров не рационально */     \
03089 //      matrix<T2, REFCNT2> t(b.nrows(), b.ncols(), a);     \
03090 //      return t.OPERU(b);                                  \
03091 //  }
03092 //
03093 //
03096 //
03097 //_ARAGELI_MATRIX_BINARY_BY_UNARY(+=, +)
03098 //_ARAGELI_MATRIX_BINARY_BY_UNARY(-=, -)
03099 //_ARAGELI_MATRIX_BINARY_BY_UNARY(*=, *)
03100 //_ARAGELI_MATRIX_BINARY_BY_UNARY(/=, /)
03101 //
03102 //_ARAGELI_MATRIX_BINARY_SCALAR(each_add, +)
03103 //_ARAGELI_MATRIX_BINARY_SCALAR(each_sub, -)
03104 //_ARAGELI_MATRIX_BINARY_SCALAR(each_mul, *)
03105 //_ARAGELI_MATRIX_BINARY_SCALAR(each_div, /)
03106 //_ARAGELI_MATRIX_BINARY_SCALAR(each_mod, %)
03107 //
03109 
03110 
03111 //template
03112 //<
03113 //  typename T1, bool REFCNT1,
03114 //  typename T2, bool REFCNT2
03115 //>
03116 //bool operator==
03117 //(
03118 //  const matrix<T1, REFCNT1>& a,
03119 //  const matrix<T2, REFCNT2>& b
03120 //);
03121 //
03122 //
03123 //template
03124 //<
03125 //  typename T1, bool REFCNT1,
03126 //  typename T2, bool REFCNT2
03127 //>
03128 //inline bool operator!=
03129 //(
03130 //  const matrix<T1, REFCNT1>& a,
03131 //  const matrix<T2, REFCNT2>& b
03132 //)
03133 //{ return !(a == b); }
03134 
03135 
03137 
03139 template
03140 <
03141     typename T1, bool REFCNT1,
03142     typename T2, bool REFCNT2
03143 >
03144 vector<T2, REFCNT2> operator*
03145 (
03146     const matrix<T1, REFCNT1>& m,
03147     const vector<T2, REFCNT2>& x
03148 );
03149 
03150 
03152 
03154 template
03155 <
03156     typename T2, bool REFCNT2,
03157     typename T1, bool REFCNT1
03158 >
03159 vector<T2, REFCNT2> operator*
03160 (
03161     const vector<T2, REFCNT2>& x,
03162     const matrix<T1, REFCNT1>& m
03163 );
03164 
03165 
03166 extern const char* matrix_output_list_first_bracket_default;
03167 extern const char* matrix_output_list_second_bracket_default;
03168 extern const char* matrix_output_list_row_separator_default;
03169 extern const char* matrix_output_list_first_row_bracket_default;
03170 extern const char* matrix_output_list_second_row_bracket_default;
03171 extern const char* matrix_output_list_col_separator_default;
03172 extern const char* matrix_input_list_first_bracket_default;
03173 extern const char* matrix_input_list_second_bracket_default;
03174 extern const char* matrix_input_list_row_separator_default;
03175 extern const char* matrix_input_list_first_row_bracket_default;
03176 extern const char* matrix_input_list_second_row_bracket_default;
03177 extern const char* matrix_input_list_col_separator_default;
03178 extern const char* matrix_output_aligned_left_col_default;
03179 extern const char* matrix_output_aligned_right_col_default;
03180 extern const char* matrix_output_aligned_inter_col_default;
03181 
03182 
03184 
03186 template <typename T, bool REFCNT>
03187 std::ostream& output_list
03188 (
03189     std::ostream& out,
03190     const matrix<T, REFCNT>& x,
03191     const char* first_bracket       = matrix_output_list_first_bracket_default,
03192     const char* second_bracket      = matrix_output_list_second_bracket_default,
03193     const char* row_separator       = matrix_output_list_row_separator_default,
03194     const char* first_row_bracket   = matrix_output_list_first_row_bracket_default,
03195     const char* second_row_bracket  = matrix_output_list_second_row_bracket_default,
03196     const char* col_separator       = matrix_output_list_col_separator_default
03197 );
03198 
03199 
03201 template <typename T, bool REFCNT>
03202 std::istream& input_list
03203 (
03204     std::istream& out,
03205     matrix<T, REFCNT>& x,
03206     const char* first_bracket       = matrix_input_list_first_bracket_default,
03207     const char* second_bracket      = matrix_input_list_second_bracket_default,
03208     const char* row_separator       = matrix_input_list_row_separator_default,
03209     const char* first_row_bracket   = matrix_input_list_first_row_bracket_default,
03210     const char* second_row_bracket  = matrix_input_list_second_row_bracket_default,
03211     const char* col_separator       = matrix_input_list_col_separator_default
03212 );
03213 
03214 
03216 template <typename T, bool REFCNT>
03217 std::ostream& output_aligned
03218 (
03219     std::ostream& out,
03220     const matrix<T, REFCNT>& x,
03221     const char* left_col    = matrix_output_aligned_left_col_default,
03222     const char* right_col   = matrix_output_aligned_right_col_default,
03223     const char* inter_col   = matrix_output_aligned_inter_col_default
03224 );
03225 
03226 
03228 template
03229 <
03230     typename T1, bool REFCNT1,
03231     typename T2, bool REFCNT2
03232 >
03233 std::ostream& output_aligned_ver_pair
03234 (
03235     std::ostream& out,
03236     const matrix<T1, REFCNT1>& m1,
03237     const matrix<T2, REFCNT2>& m2,
03238     const char* left_col = "|| ",
03239     const char* right_col = " ||",
03240     const char* inter_col = " ",
03241     const char* hsplitter = "-"
03242 );
03243 
03244 
03246 template
03247 <
03248     typename T1, bool REFCNT1,
03249     typename T2, bool REFCNT2
03250 >
03251 std::ostream& output_aligned_hor_pair
03252 (
03253     std::ostream& out,
03254     const matrix<T1, REFCNT1>& m1,
03255     const matrix<T2, REFCNT2>& m2,
03256     const char* left_col = "|| ",
03257     const char* right_col = " ||",
03258     const char* inter_col = " ",
03259     const char* vsplitter = " | "
03260 );
03261 
03262 
03264 
03267 template
03268 <
03269     typename T1, bool REFCNT1,
03270     typename T2, bool REFCNT2,
03271     typename T3, bool REFCNT3
03272 >
03273 std::ostream& output_aligned_corner_triplet_br
03274 (
03275     std::ostream& out,
03276     const matrix<T1, REFCNT1>& m1,
03277     const matrix<T2, REFCNT2>& m2,
03278     const matrix<T3, REFCNT3>& m3,
03279     const char* left_col = "|| ",
03280     const char* right_col = " ||",
03281     const char* inter_col = " ",
03282     const char* vsplitter = " | ",
03283     const char* hsplitter = "-"
03284 );
03285 
03286 
03288 template <typename T, bool REFCNT>
03289 std::ostream& operator<< (std::ostream& out, const matrix<T, REFCNT>& x)
03290 { return output_list(out, x); }
03291 
03293 template <typename T, bool REFCNT>
03294 std::istream& operator>> (std::istream& out, matrix<T, REFCNT>& x)
03295 { return input_list(out, x); }
03296 
03297 
03299 template <typename T, bool REFCNT>
03300 std::ofstream& operator<< (std::ofstream& out, const matrix<T, REFCNT>& x)
03301 { return static_cast<std::ofstream&>(output_list(out, x)); }
03302 
03304 template <typename T, bool REFCNT>
03305 std::ifstream& operator>> (std::ifstream& out, matrix<T, REFCNT>& x)
03306 { return static_cast<std::ifstream&>(input_list(out, x)); }
03307 
03308 
03309 // BEGIN OF TEMPORARY EXTENTION
03310 
03311 template <typename T, bool REFCNT>
03312 std::ostream& operator<< (std::ostringstream& out, const matrix<T, REFCNT>& x)
03313 { return output_list(out, x); }
03314 
03316 template <typename T, bool REFCNT>
03317 std::istream& operator>> (std::istringstream& out, matrix<T, REFCNT>& x)
03318 { return input_list(out, x); }
03319 
03320 // END OF TEMPORARY EXTENTION
03321 
03322 
03324 template <typename T, bool REFCNT>
03325 struct factory<matrix<T, REFCNT> >
03326 {
03327 private:
03328 
03329     typedef matrix<T, REFCNT> TTT;
03330 
03331 public:
03332 
03333     static const bool is_specialized = true;
03334     
03335     static const TTT& unit ()
03336     {
03337         static const TTT unit_s(1, eye);
03338         return unit_s;
03339     }
03340     
03341     static TTT unit (const TTT& pat)
03342     { return TTT(pat.nrows(), Arageli::unit<T>(), diag); }
03343     
03344     static const TTT& opposite_unit ()
03345     {
03346         static const TTT opposite_unit_s
03347             (1, Arageli::opposite_unit<T>(), diag);
03348         return opposite_unit_s;
03349     }
03350     
03351     static TTT opposite_unit (const TTT& pat)
03352     { return TTT(pat.nrows(), Arageli::opposite_unit<T>(), diag); }
03353     
03354     static const TTT& null ()
03355     {
03356         static const TTT null_s(1, Arageli::null<T>(), fromval);
03357         return null_s;
03358     }
03359     
03360     static TTT null (const TTT& pat)
03361     { return TTT(pat.nrows(), Arageli::null<T>(), diag); }
03362 
03363 };
03364 
03365 
03366 template <typename T, bool REFCNT>
03367 inline matrix<T, REFCNT> opposite
03368 (const matrix<T, REFCNT>& x)
03369 { return -x; }
03370 
03371 template <typename T, bool REFCNT>
03372 inline matrix<T, REFCNT>& opposite
03373 (const matrix<T, REFCNT>& x, matrix<T, REFCNT>* y)
03374 { return (*y = x).opposite(); }
03375 
03376 template <typename T, bool REFCNT>
03377 inline matrix<T, REFCNT>& opposite
03378 (matrix<T, REFCNT>* x)
03379 { return x->opposite(); }
03380 
03381 //template <typename T, bool REFCNT>
03382 //inline matrix<T, REFCNT> inverse
03383 //(const matrix<T, REFCNT>& x)
03384 //{
03385 //  matrix<T, REFCNT> t(x);
03386 //  return x.inverse();
03387 //}
03388 
03389 template <typename T, bool REFCNT>
03390 inline matrix<T, REFCNT>& inverse
03391 (const matrix<T, REFCNT>& x, matrix<T, REFCNT>* y)
03392 { return (*y = x).inverse(); }
03393 
03394 template <typename T, bool REFCNT>
03395 inline matrix<T, REFCNT>& inverse
03396 (matrix<T, REFCNT>* x)
03397 { return x->inverse(); }
03398 
03399 
03400 template <typename T, bool REFCNT>
03401 inline bool is_unit (const matrix<T, REFCNT>& x)
03402 { return x.is_unit(); }
03403 
03404 template <typename T, bool REFCNT>
03405 inline bool is_opposite_unit (const matrix<T, REFCNT>& x)
03406 { return x.is_opposite_unit(); }
03407 
03408 template <typename T, bool REFCNT>
03409 inline bool is_null (const matrix<T, REFCNT>& x)
03410 { return x.is_null(); }
03411 
03412 
03413 template <typename T, bool REFCNT>
03414 struct type_traits<matrix<T, REFCNT> >
03415     : public type_traits_default<matrix<T, REFCNT> >
03416 {
03417     static const bool is_specialized = type_traits<T>::is_specialized;
03418 
03419     static const bool is_number = false;
03420     static const bool is_integer_number = false;
03421     static const bool is_polynom = false;
03422     static const bool is_real_number = false;
03423     static const bool is_rational_number = false;
03424     static const bool is_complex_number = false;
03425     static const bool is_ring = type_traits<T>::is_ring;    // +, -, *, null, unit
03426     static const bool is_field = false;
03427     static const bool is_finite = type_traits<T>::is_finite;
03428     static const bool is_additive_group = type_traits<T>::is_additive_group;    // +, -, null
03429     static const bool is_multiplicative_group = false;
03430     static const bool has_zero_divisor = type_traits<T>::has_zero_divisor;
03431     static const bool is_integer_modulo_ring = false;
03432     static const bool is_matrix = true;
03433     static const bool is_vector = false;
03434     
03435     static const bool has_commutative_multiplication =
03436                         type_traits<T>::has_commutative_multiplication &&
03437                         type_traits<T>::has_commutative_addition;
03438     
03439     static const bool has_commutative_addition =
03440                         type_traits<T>::has_commutative_addition;
03441 
03442     static const bool has_null = type_traits<T>::has_null;
03443     
03444     static const bool has_unit =
03445                         type_traits<T>::has_unit &&
03446                         type_traits<T>::has_null;
03447     
03448     static const bool has_opposite_unit =
03449                         type_traits<T>::has_opposite_unit &&
03450                         type_traits<T>::has_null;
03451 
03453     static const bool is_aggregate = true;
03454     
03456     typedef T element_type;
03457 
03458     typedef type_category::dense_matrix category_type;
03459     static const category_type category_value;
03460 };
03461 
03462 
03463 template <typename T, bool REFCNT>
03464 const type_category::dense_matrix
03465     type_traits<matrix<T, REFCNT> >::category_value =
03466     type_category::dense_matrix();
03467 
03468 
03469 template <typename T, bool REFCNT>
03470 inline std::ostream& output_polynom_first
03471 (std::ostream& out, const matrix<T, REFCNT>& x)
03472 { return output_list(out, x); }
03473 
03474 template <typename T, bool REFCNT>
03475 inline std::ostream& output_polynom_internal
03476 (std::ostream& out, const matrix<T, REFCNT>& x)
03477 { return output_list(out << "+", x); }
03478 
03479 template <typename T, bool REFCNT>
03480 inline std::ostream& output_pow
03481 (std::ostream& out, const matrix<T, REFCNT>& x)
03482 { return output_list(out, x); }
03483 
03484 template <typename T, bool REFCNT>
03485 inline std::istream& input_polynom_first
03486 (std::istream& in, matrix<T, REFCNT>& x)
03487 { return input_list(in, x); }
03488 
03489 template <typename T, bool REFCNT>
03490 std::istream& input_polynom_internal
03491 (std::istream& in, matrix<T, REFCNT>& x);
03492 
03493 template <typename T, bool REFCNT>
03494 inline std::istream& input_pow
03495 (std::istream& in, matrix<T, REFCNT>& x)
03496 { return input_polynom_first(in, x); }
03497 
03498 
03500 template
03501 <
03502     typename T1, bool REFCNT1,
03503     typename T2, bool REFCNT2,
03504     typename T3, bool REFCNT3
03505 >
03506 void fill_submatrix_col
03507 (
03508     const matrix<T1, REFCNT1>& orig,
03509     const vector<T2, REFCNT2>& indexes,
03510     matrix<T3, REFCNT3>& res
03511 )
03512 {
03513     res.assign_fromsize(orig.nrows(), indexes.size());
03514 
03515     for(typename vector<T2, REFCNT2>::size_type j = 0; j < indexes.size(); ++j)
03516     {
03517         const T2& index = indexes[j];
03518 
03519         ARAGELI_ASSERT_0(index >= 0);
03520         ARAGELI_ASSERT_0(index < orig.ncols());
03521 
03522         for(typename matrix<T3, REFCNT3>::size_type i = 0; i < res.nrows(); ++i)
03523             res(i, j) = orig(i, index);
03524     }
03525 }
03526 
03527 
03529 template
03530 <
03531     typename T1, bool REFCNT1,
03532     typename T2, bool REFCNT2,
03533     typename T3, bool REFCNT3
03534 >
03535 void fill_submatrix_row
03536 (
03537     const matrix<T1, REFCNT1>& orig,
03538     const vector<T2, REFCNT2>& indexes,
03539     matrix<T3, REFCNT3>& res
03540 )
03541 {
03542     res.assign_fromsize(indexes.size(), orig.ncols());
03543 
03544     for(typename vector<T2, REFCNT2>::size_type i = 0; i < indexes.size(); ++i)
03545     {
03546         const T2& index = indexes[i];
03547 
03548         ARAGELI_ASSERT_0(index >= 0);
03549         ARAGELI_ASSERT_0(index < orig.nrows());
03550 
03551         for(typename matrix<T3, REFCNT3>::size_type j = 0; j < res.ncols(); ++j)
03552             res(i, j) = orig(index, j);
03553     }
03554 }
03555 
03556 
03557 }
03558 
03559 
03560 namespace std
03561 {
03562 
03564 template
03565 <
03566     typename T1, bool REFCNT1,
03567     typename T2, bool REFCNT2
03568 >
03569 inline void swap
03570 (
03571     Arageli::matrix<T1, REFCNT1>& a,
03572     Arageli::matrix<T2, REFCNT2>& b
03573 )
03574 { a.swap(b); }
03575 
03576 
03578 template <typename T1, bool REFCNT1>
03579 inline void swap
03580 (
03581     Arageli::matrix<T1, REFCNT1>& a,
03582     Arageli::matrix<T1, REFCNT1>& b
03583 )
03584 { a.swap(b); }
03585 
03586 }
03587 
03588 
03589 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
03590     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_MATRIX
03591     #include "matrix.cpp"
03592     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_MATRIX
03593 #endif
03594 
03595 
03596 #endif
03597 

Generated on Thu Aug 31 17:38:08 2006 for Arageli by  doxygen 1.4.7