matrix.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     matrix.cpp -- Описание см. в файле 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 
00013 #include "config.hpp"
00014 
00015 #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || \
00016     defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_MATRIX)
00017 
00018 #include <cstddef>
00019 #include <list>
00020 #include <sstream>
00021 
00022 #include "matrix.hpp"
00023 #include "vector.hpp"
00024 //#include "gauss.hpp"
00025 #include "_utility.hpp"
00026 
00027 
00028 namespace Arageli
00029 {
00030 
00031 // See definition of this fuction template at "gauss.cpp".
00032 template <typename T, bool REFCNT>
00033 matrix<T, REFCNT> inverse (const matrix<T, REFCNT>& A);
00034 
00035 
00036 template <typename T, bool REFCNT>
00037 void matrix<T, REFCNT>::assign_fromstr (const char* s)
00038 {
00039     std::istringstream buf(s);
00040     static_cast<std::istream&>(buf) >> *this;
00041     if(!buf && !buf.eof())
00042         throw incorrect_string(s);
00043 }
00044 
00045 
00046 template <typename T, bool REFCNT>
00047 template <typename Val>
00048 void matrix<T, REFCNT>::assign_fromval
00049 (size_type rows_a, size_type cols_a, const Val& val)
00050 {
00051     // WARNING! TEMPORARY IMPLEMENTATION!
00052     resize(rows_a, cols_a);
00053     std::fill(begin(), end(), val);
00054 }
00055 
00056 
00057 template <typename T, bool REFCNT>
00058 template <typename Seq>
00059 void matrix<T, REFCNT>::assign_fromseq
00060 (size_type rows_a, size_type cols_a, Seq seq)
00061 {
00062     // WARNING! TEMPORARY IMPLEMENTATION!
00063     resize(rows_a, cols_a);
00064     for(iterator i = begin(); i != end(); ++i)
00065         *i = *seq++;
00066 }
00067 
00068 
00069 template <typename T, bool REFCNT>
00070 template <typename Val>
00071 void matrix<T, REFCNT>::assign_diag_fromval
00072 (size_type rows_a, size_type cols_a, const Val& val)
00073 {
00074     // WARNING! TEMPORARY IMPLEMENTATION!
00075     assign_fromsize(rows_a, cols_a);
00076     size_type minsize = std::min(rows_a, cols_a);
00077     for(size_type i = 0; i < minsize; ++i)
00078         el(i, i) = val;
00079 }
00080 
00081 
00082 template <typename T, bool REFCNT>
00083 template <typename Seq>
00084 void matrix<T, REFCNT>::assign_diag_fromseq
00085 (size_type rows_a, size_type cols_a, Seq seq)
00086 {
00087     // WARNING! TEMPORARY IMPLEMENTATION!
00088     assign_fromsize(rows_a, cols_a);
00089     size_type minsize = std::min(rows_a, cols_a);
00090     for(size_type i = 0; i < minsize; ++i)
00091         el(i, i) = *seq++;
00092 }
00093 
00094 
00095 //template <typename T, bool REFCNT>
00096 //template <typename T1>
00097 //void matrix<T, REFCNT>::assign_diag_fromval
00098 //(size_type rows_a, size_type cols_a, const T1& val)
00099 //{
00100 //  unique_clear();
00101 //  rep().assign(rows_a, cols_a, factory<T>::null());   // WARNING! Temporary solution.
00102 //  size_type n = std::min(rows_a, cols_a);
00103 //  n *= cols_a;
00104 //  for(size_type i = 0; i < n; i += cols_a + 1)
00105 //      mem(i) = val;
00106 //}
00107 //
00108 //
00109 //template <typename T, bool REFCNT>
00110 //template <typename In>
00111 //void matrix<T, REFCNT>::assign_diag_fromseq
00112 //(size_type rows_a, size_type cols_a, In in)
00113 //{
00114 //  unique_clear();
00115 //  rep().assign(rows_a, cols_a, factory<T>::null());   // WARNING! Temporary solution.
00116 //  size_type n = std::min(rows_a, cols_a);
00117 //  n *= cols_a;
00118 //  for(size_type i = 0; i < n; i += cols_a + 1, ++in)
00119 //      mem(i) = *in;
00120 //}
00121 //
00122 //
00123 //template <typename T, bool REFCNT>
00124 //template <typename In>
00125 //void matrix<T, REFCNT>::assign_colwise
00126 //(size_type rows_a, size_type cols_a, In in)
00127 //{
00128 //  unique_clear();
00129 //  rep().assign(rows_a, cols_a, factory<T>::null());   // WARNING! Temporary solution.
00130 //  
00131 //  // WARNING! Temporary solution.
00132 //  
00133 //  for(size_type j = 0; j < ncols(); ++j)
00134 //      for(size_type i = 0; i < nrows(); ++i)
00135 //          el(i, j) = *in++;
00136 //}
00137 
00138 
00139 template <typename T, bool REFCNT>
00140 bool matrix<T, REFCNT>::is_null () const
00141 {
00142     for(size_type i = 0; i < size(); ++i)
00143         if(!Arageli::is_null(mem(i)))return false;
00144     return true;
00145 }
00146 
00147 
00148 template <typename T, bool REFCNT>
00149 bool matrix<T, REFCNT>::is_unit () const
00150 {
00151     if(is_empty())return false;
00152     if(!is_square())return false;
00153     if(!Arageli::is_unit(el(0, 0)))return false;
00154     
00155     for(size_type i = 1; i < size();)
00156     {
00157         for(size_type j = 0; j < ncols(); ++j, ++i)
00158             if(!Arageli::is_null(mem(i)))return false;
00159         if(!Arageli::is_unit(mem(i++)))return false;
00160     }
00161 
00162     return true;
00163 }
00164 
00165 
00166 template <typename T, bool REFCNT>
00167 bool matrix<T, REFCNT>::is_opposite_unit () const
00168 {
00169     if(is_empty())return false;
00170     if(!is_square())return false;
00171     if(!Arageli::is_opposite_unit(el(0, 0)))return false;
00172     
00173     for(size_type i = 1; i < size();)
00174     {
00175         for(size_type j = 0; j < ncols(); ++j, ++i)
00176             if(!Arageli::is_null(mem(i)))return false;
00177         if(!Arageli::is_opposite_unit(mem(i++)))return false;
00178     }
00179 
00180     return true;
00181 }
00182 
00183 
00184 template <typename T, bool REFCNT>
00185 matrix<T, REFCNT>& matrix<T, REFCNT>::inverse ()
00186 { *this = Arageli::inverse(*this); }
00187 
00188 
00189 template <typename T, bool REFCNT>
00190 matrix<T, REFCNT>& matrix<T, REFCNT>::each_inverse ()
00191 {
00192     for(size_type i = 0; i < size(); ++i)
00193         Arageli::inverse(&mem(i));
00194     return *this;
00195 }
00196 
00197 
00198 #define _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(OPER, MNEM)                   \
00199     template <typename T1, bool REFCNT1>                                \
00200     template <typename T2>                                              \
00201     matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::MNEM##_scalar             \
00202     (const T2& x)                                                       \
00203     {                                                                   \
00204         if(is_empty())return *this;                                     \
00205         /*unique();*/                                                   \
00206                                                                         \
00207         iterator i = begin(), iend = end();                             \
00208         for(; i < iend; ++i)                                            \
00209             *i OPER x;                                                  \
00210                                                                         \
00211         return *this;                                                   \
00212     }                                                                   \
00213                                                                         \
00214     template <typename T1, bool REFCNT1>                                \
00215     template <typename T2>                                              \
00216     matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::each_##MNEM##_matrix      \
00217     (const T2& x)                                                       \
00218     {                                                                   \
00219         ARAGELI_ASSERT_0(x.nrows() == nrows());                         \
00220         ARAGELI_ASSERT_0(x.ncols() == ncols());                         \
00221         if(is_empty())return *this;                                     \
00222         /*unique();*/                                                   \
00223                                                                         \
00224         iterator i1 = begin(), i1end = end();                           \
00225         typename T2::const_iterator i2 = x.begin();                     \
00226         for(; i1 < i1end; ++i1, ++i2)                                   \
00227             *i1 OPER *i2;                                               \
00228                                                                         \
00229         return *this;                                                   \
00230     }
00231 
00232 
00233 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(+=, add)
00234 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(-=, sub)
00235 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(*=, mul)
00236 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(/=, div);
00237 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(%=, mod);
00238 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(&=, bitand)
00239 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(|=, bitor)
00240 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(^=, bitxor)
00241 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(<<=, shl)
00242 _ARAGELI_MATRIX_OPERATOR_ASSIGN_1(>>=, shr)
00243 
00244 #undef _ARAGELI_MATRIX_OPERATOR_ASSIGN_1
00245 
00246 
00247 //template <typename T1, bool REFCNT1>
00248 //template <typename T2>
00249 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator+=
00250 //(const T2& x)
00251 //{
00252 //  if(is_empty())return *this;
00253 //  unique();
00254 //
00255 //  for(size_type i = 0; i < size(); ++i)
00256 //      mem(i) += x;
00257 //
00258 //  return *this;
00259 //}
00260 //
00261 //
00262 //template <typename T1, bool REFCNT1>
00263 //template <typename T2>
00264 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator-=
00265 //(const T2& x)
00266 //{
00267 //  if(is_empty())return *this;
00268 //  unique();
00269 //
00270 //  for(size_type i = 0; i < size(); ++i)
00271 //      mem(i) -= x;
00272 //
00273 //  return *this;
00274 //}
00275 //
00276 //
00277 //template <typename T1, bool REFCNT1>
00278 //template <typename T2>
00279 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator*=
00280 //(const T2& x)
00281 //{
00282 //  if(is_empty())return *this;
00283 //  unique();
00284 //
00285 //  for(size_type i = 0; i < size(); ++i)
00286 //      mem(i) *= x;
00287 //
00288 //  return *this;
00289 //}
00290 //
00291 //
00292 //template <typename T1, bool REFCNT1>
00293 //template <typename T2>
00294 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator/=
00295 //(const T2& x)
00296 //{
00297 //  ARAGELI_ASSERT_0(!Arageli::is_null(x));
00298 //  if(is_empty())return *this;
00299 //  unique();
00300 //
00301 //  for(size_type i = 0; i < size(); ++i)
00302 //      mem(i) /= x;
00303 //
00304 //  return *this;
00305 //}
00306 //
00307 //
00308 //template <typename T1, bool REFCNT1>
00309 //template <typename T2>
00310 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator%=
00311 //(const T2& x)
00312 //{
00313 //  ARAGELI_ASSERT_0(!is_null(x));
00314 //  if(is_empty())return *this;
00315 //  unique();
00316 //
00317 //  for(size_type i = 0; i < size(); ++i)
00318 //      mem(i) %= x;
00319 //
00320 //  return *this;
00321 //}
00322 //
00323 //
00324 //template <typename T1, bool REFCNT1>
00325 //template <typename T2, bool REFCNT2>
00326 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator+=
00327 //(const matrix<T2, REFCNT2>& x)
00328 //{
00329 //  ARAGELI_ASSERT_0(x.nrows() == nrows());
00330 //  ARAGELI_ASSERT_0(x.ncols() == ncols());
00331 //
00332 //  if(is_empty())return *this;
00333 //  unique();
00334 //
00335 //  for(size_type i = 0; i < size(); ++i)
00336 //      mem(i) += x.mem(i);
00337 //
00338 //  return *this;
00339 //}
00340 //
00341 //
00342 //template <typename T1, bool REFCNT1>
00343 //template <typename T2, bool REFCNT2>
00344 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::operator-=
00345 //(const matrix<T2, REFCNT2>& x)
00346 //{
00347 //  ARAGELI_ASSERT_0(x.nrows() == nrows());
00348 //  ARAGELI_ASSERT_0(x.ncols() == ncols());
00349 //
00350 //  if(is_empty())return *this;
00351 //  unique();
00352 //
00353 //  for(size_type i = 0; i < size(); ++i)
00354 //      mem(i) -= x.mem(i);
00355 //
00356 //  return *this;
00357 //}
00358 
00359 
00360 template <typename T1, bool REFCNT1>
00361 template <typename T2>
00362 matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::mul_matrix
00363 (const T2& right)
00364 {
00365     ARAGELI_ASSERT_0(ncols() == right.nrows());
00366 
00367     if(is_empty() && ncols() == right.ncols())return *this;
00368 
00369     if
00370     (
00371         reinterpret_cast<const void*>(this) !=
00372         reinterpret_cast<const void*>(&right)
00373     )
00374     {
00375         matrix left;
00376         swap(left);
00377         assign_fromsize(left.nrows(), right.ncols());
00378 
00379         // WARNING. This is slow implementation. It can be very quickly.
00380         
00381         for(size_type i = 0; i < nrows(); ++i)
00382             for(size_type j = 0; j < ncols(); ++j)
00383                 for(size_type k = 0; k < left.ncols(); ++k)
00384                     el(i, j) += left(i, k) * right(k, j);
00385     }
00386     else
00387     {
00388         ARAGELI_ASSERT_1(is_square());
00389         matrix arg(nrows()/*::null(), square_matrix*/);
00390         swap(arg);
00391 
00392         for(size_type i = 0; i < nrows(); ++i)
00393             for(size_type j = 0; j < nrows(); ++j)
00394                 for(size_type k = 0; k < nrows(); ++k)
00395                     el(i, j) += arg(i, k) * arg(k, j);
00396     }
00397 
00398     return *this;
00399 }
00400 
00401 
00402 template <typename T1, bool REFCNT1>
00403 template <typename T2>
00404 matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::div_matrix
00405 (const T2& right)
00406 {
00407     try { *this *= Arageli::inverse(right); }
00408     catch(const matrix_is_singular&)
00409     { throw division_by_zero(); }
00410     return *this;
00411 }
00412 
00413 
00414 //template <typename T1, bool REFCNT1>
00415 //template <typename T2, bool REFCNT2>
00416 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::each_mul
00417 //(const matrix<T2, REFCNT2>& x)
00418 //{
00419 //  ARAGELI_ASSERT_0(nrows() == x.nrows());
00420 //  ARAGELI_ASSERT_0(ncols() == x.ncols());
00421 //
00422 //  if(is_empty())return *this;
00423 //  unique();
00424 //
00425 //  for(size_type i = 0; i < size(); ++i)
00426 //      mem(i) *= x.mem(i);
00427 //
00428 //  return *this;
00429 //}
00430 //
00431 //
00432 //template <typename T1, bool REFCNT1>
00433 //template <typename T2, bool REFCNT2>
00434 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::each_div
00435 //(const matrix<T2, REFCNT2>& x)
00436 //{
00437 //  ARAGELI_ASSERT_0(nrows() == x.nrows());
00438 //  ARAGELI_ASSERT_0(ncols() == x.ncols());
00439 //
00440 //  if(is_empty())return *this;
00441 //  unique();
00442 //
00443 //  for(size_type i = 0; i < size(); ++i)
00444 //  {
00445 //      ARAGELI_ASSERT_0(!is_null(x.mem(i)));
00446 //      mem(i) /= x.mem(i);
00447 //  }
00448 //
00449 //  return *this;
00450 //}
00451 //
00452 //
00453 //template <typename T1, bool REFCNT1>
00454 //template <typename T2, bool REFCNT2>
00455 //matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::each_mod
00456 //(const matrix<T2, REFCNT2>& x)
00457 //{
00458 //  ARAGELI_ASSERT_0(nrows() == x.nrows());
00459 //  ARAGELI_ASSERT_0(ncols() == x.ncols());
00460 //
00461 //  if(is_empty())return *this;
00462 //  unique();
00463 //
00464 //  for(size_type i = 0; i < size(); ++i)
00465 //  {
00466 //      ARAGELI_ASSERT_0(!is_null(x.mem(i)));
00467 //      mem(i) %= x.mem(i);
00468 //  }
00469 //
00470 //  return *this;
00471 //}
00472 
00473 
00474 template <typename T1, bool REFCNT1>
00475 matrix<T1, REFCNT1>& matrix<T1, REFCNT1>::opposite ()
00476 {
00477     if(is_empty())return *this;
00478     unique();
00479 
00480     for(size_type i = 0; i < size(); ++i)
00481         Arageli::opposite(&mem(i));
00482 
00483     return *this;
00484 }
00485 
00486 
00487 template <typename T1, bool REFCNT1>
00488 void matrix<T1, REFCNT1>::transpose ()
00489 {
00490     // a temporary matrix with 'transposed' sizes
00491     matrix<T1, true> t(ncols(), nrows(), fromsize);
00492 
00493     for(size_type i = 0; i < nrows(); ++i)
00494         for(size_type j = 0; j < ncols(); ++j)
00495             t(j, i) = el(i, j);
00496 
00497     swap(t);
00498 }
00499 
00500 
00501 
00502 //template <typename T1, bool REFCNT1>
00503 //std::pair<typename matrix<T1, REFCNT1>::size_type, typename matrix<T1, REFCNT1>::size_type> matrix<T1, REFCNT1>::find_max () const
00504 //{
00505 //  // WARNING. Slow implementation.
00506 //
00507 //  ARAGELI_ASSERT_0(!is_empty());
00508 //
00509 //  T1 res = el(0, 0);
00510 //  size_type ires = 0, jres = 0;
00511 //
00512 //  for(size_type i = 0; i < nrows(); ++i)
00513 //      for(size_type j = 0; j < ncols(); ++j)
00514 //          if(el(i, j) > res)
00515 //          {
00516 //              res = el(i, j);
00517 //              ires = i;
00518 //              jres = j;
00519 //          }
00520 //
00521 //  return std::make_pair(ires, jres);
00522 //}
00523 //
00524 //
00525 //template <typename T1, bool REFCNT1>
00526 //std::pair<typename matrix<T1, REFCNT1>::size_type, typename matrix<T1, REFCNT1>::size_type> matrix<T1, REFCNT1>::find_min () const
00527 //{
00528 //  // WARNING. Slow implementation.
00529 //
00530 //  ARAGELI_ASSERT_0(!is_empty());
00531 //
00532 //  T1 res = el(0, 0);
00533 //  size_type ires = 0, jres = 0;
00534 //
00535 //  for(size_type i = 0; i < nrows(); ++i)
00536 //      for(size_type j = 0; j < ncols(); ++j)
00537 //          if(el(i, j) < res)
00538 //          {
00539 //              res = el(i, j);
00540 //              ires = i;
00541 //              jres = j;
00542 //          }
00543 //
00544 //  return std::make_pair(ires, jres);
00545 //}
00546 
00547 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00548 
00549 template <typename T, bool REFCNT>
00550 void matrix<T, REFCNT>::insert_row (size_type pos, const T& val)
00551 {
00552     ARAGELI_ASSERT_0(pos <= nrows());
00553 
00554     unique();
00555     mem().insert(begin() + pos*ncols(), ncols(), val);
00556     ++rep().rows;
00557 }
00558 
00559 
00560 template <typename T, bool REFCNT>
00561 template <typename T1, bool REFCNT1>
00562 void matrix<T, REFCNT>::insert_row
00563 (size_type pos, const vector<T1, REFCNT1>& vals)
00564 {
00565     ARAGELI_ASSERT_0(vals.size() >= ncols());
00566     ARAGELI_ASSERT_0(pos <= nrows());
00567 
00568     unique();
00569     if(ncols() == 0 && nrows() == 0)resize(0, vals.size());
00570     mem().insert(begin() + pos*ncols(), vals.begin(), vals.begin() + ncols());
00571     ++rep().rows;
00572 }
00573 
00574 
00575 template <typename T, bool REFCNT>
00576 template <typename In>
00577 void matrix<T, REFCNT>::insert_row (size_type pos, In first)
00578 {
00579     ARAGELI_ASSERT_0(pos <= nrows());
00580 
00581     // WARNING! If In is input stream iterator then
00582     // the following expression is incorrect.
00583     
00584     In last = std::advance(first, ncols());
00585 
00586     unique();
00587     mem().insert(begin() + pos*ncols(), first, last);
00588     ++rep().rows;
00589 }
00590 
00591 
00592 template <typename T, bool REFCNT>
00593 void matrix<T, REFCNT>::insert_rows
00594 (size_type pos, size_type n, const T& val)
00595 {
00596     ARAGELI_ASSERT_0(pos <= nrows());
00597 
00598     // WARNING. This is slow implementation.
00599 
00600     for(size_type i = pos; i < pos + n; ++i)
00601         insert_row(pos, val);
00602 }
00603 
00604 
00605 template <typename T, bool REFCNT>
00606 template <typename T1, bool REFCNT1>
00607 void matrix<T, REFCNT>::insert_rows
00608 (size_type pos, size_type n, const vector<T1, REFCNT1>& vals)
00609 {
00610     ARAGELI_ASSERT_0(pos <= nrows());
00611 
00612     // WARNING. This is slow implementation.
00613 
00614     for(size_type i = pos; i < pos + n; ++i)
00615         insert_row(pos, vals);
00616 }
00617 
00618 
00619 
00620 template <typename T, bool REFCNT>
00621 template <typename In>
00622 void matrix<T, REFCNT>::insert_rows
00623 (size_type pos, size_type n, In first)
00624 {
00625     ARAGELI_ASSERT_0(pos <= nrows());
00626 
00627     // WARNING. This is slow implementation.
00628 
00629     for(size_type i = pos; i < pos + n; ++i)
00630         insert_row(pos, first);
00631 }
00632 
00633 
00634 template <typename T, bool REFCNT>
00635 void matrix<T, REFCNT>::erase_row (size_type pos)
00636 {
00637     ARAGELI_ASSERT_0(pos < nrows());
00638 
00639     unique();
00640     mem().erase(begin() + pos*ncols(), begin() + (pos + 1)*ncols());
00641     --rep().rows;
00642 }
00643 
00644 
00645 template <typename T, bool REFCNT>
00646 void matrix<T, REFCNT>::erase_rows (size_type pos, size_type n)
00647 {
00648     ARAGELI_ASSERT_0(pos < nrows());
00649     ARAGELI_ASSERT_0(pos + n <= nrows());
00650 
00651     unique();
00652     mem().erase(begin() + pos*ncols(), begin() + (pos + n)*ncols());
00653     rep().rows -= n;
00654 }
00655 
00656 template <typename T, bool REFCNT>
00657 void matrix<T, REFCNT>::swap_rows (size_type xpos, size_type ypos)
00658 {
00659     ARAGELI_ASSERT_0(xpos < nrows());
00660     ARAGELI_ASSERT_0(ypos < nrows());
00661 
00662     if(xpos == ypos)return;
00663 
00664     std::swap_ranges
00665     (
00666         begin() + xpos*ncols(), begin() + (xpos + 1)*ncols(),
00667         begin() + ypos*ncols()
00668     );
00669 }
00670 
00671 
00672 template <typename T, bool REFCNT>
00673 template <typename T1>
00674 void matrix<T, REFCNT>::mult_row (size_type i, const T1& x)
00675 {
00676     ARAGELI_ASSERT_0(i < nrows());
00677 
00678     unique();
00679     for(size_type j = i*ncols(); j < (i+1)*ncols(); ++j)
00680         mem(j) *= x;
00681 }
00682 
00683 
00684 template <typename T, bool REFCNT>
00685 template <typename T1>
00686 void matrix<T, REFCNT>::div_row (size_type i, const T1& x)
00687 {
00688     ARAGELI_ASSERT_0(i < nrows());
00689 
00690     unique();
00691     size_type endpos = (i+1)*ncols();
00692     for(size_type j = i*ncols(); j < endpos; ++j)
00693         mem(j) /= x;
00694 }
00695 
00696 
00697 template <typename T, bool REFCNT>
00698 template <typename T1>
00699 void matrix<T, REFCNT>::mod_row (size_type i, const T1& x)
00700 {
00701     ARAGELI_ASSERT_0(i < nrows());
00702 
00703     unique();
00704     size_type endpos = (i+1)*ncols();
00705     for(size_type j = i*ncols(); j < endpos; ++j)
00706         mem(j) = mod(mem(j), x);
00707 }
00708 
00709 
00710 // row[dstpos] += row[srcpos]
00711 template <typename T, bool REFCNT>
00712 void matrix<T, REFCNT>::add_rows (size_type dstpos, size_type srcpos)
00713 {
00714     ARAGELI_ASSERT_0(dstpos < nrows());
00715     ARAGELI_ASSERT_0(srcpos < nrows());
00716     ARAGELI_ASSERT_0(srcpos != dstpos);
00717 
00718     unique();
00719     size_type endpos = (srcpos+1)*ncols();
00720     for(size_type i = srcpos*ncols(), j = dstpos*ncols(); i < endpos; ++i, ++j)
00721         mem(j) += mem(i);
00722 }
00723 
00724 
00725 // row[dstpos] -= row[srcpos]
00726 template <typename T, bool REFCNT>
00727 void matrix<T, REFCNT>::sub_rows (size_type dstpos, size_type srcpos)
00728 {
00729     ARAGELI_ASSERT_0(dstpos < nrows());
00730     ARAGELI_ASSERT_0(srcpos < nrows());
00731     ARAGELI_ASSERT_0(srcpos != dstpos);
00732 
00733     unique();
00734     size_type endpos = (srcpos+1)*ncols();
00735     for(size_type i = srcpos*ncols(), j = dstpos*ncols(); i < endpos; ++i, ++j)
00736         mem(j) -= mem(i);
00737 }
00738 
00739 
00740 // row[dstpos] += y*row[srcpos]
00741 template <typename T, bool REFCNT>
00742 template <typename T2>
00743 void matrix<T, REFCNT>::addmult_rows
00744 (size_type dstpos, size_type srcpos, const T2& y)
00745 {
00746     ARAGELI_ASSERT_0(dstpos < nrows());
00747     ARAGELI_ASSERT_0(srcpos < nrows());
00748     ARAGELI_ASSERT_0(dstpos != srcpos);
00749 
00750     unique();
00751     size_type endpos = (srcpos+1)*ncols();
00752     for(size_type i = srcpos*ncols(), j = dstpos*ncols(); i < endpos; ++i, ++j)
00753         mem(j) += y*mem(i);
00754 }
00755 
00756 
00757 // row[dstpos] = x*row[dstpos] + y*row[srcpos]
00758 template <typename T, bool REFCNT>
00759 template <typename T1, typename T2>
00760 void matrix<T, REFCNT>::addmult_rows
00761 (
00762     size_type dstpos, const T1& x,
00763     size_type srcpos, const T2& y
00764 )
00765 {
00766     ARAGELI_ASSERT_0(dstpos < nrows());
00767     ARAGELI_ASSERT_0(srcpos < nrows());
00768     ARAGELI_ASSERT_0(dstpos != srcpos);
00769 
00770     unique();
00771     size_type endpos = (srcpos+1)*ncols();
00772     for(size_type i = srcpos*ncols(), j = dstpos*ncols(); i < endpos; ++i, ++j)
00773         (mem(j) *= x) += y*mem(i);
00774 }
00775 
00776 
00777 template <typename T, bool REFCNT>
00778 template <typename T1, typename V, typename T2>
00779 void matrix<T, REFCNT>::addmult_rows
00780 (
00781     size_type dstpos, const T1& x,
00782     const V& srcvec, const T2& y
00783 )
00784 {
00785     ARAGELI_ASSERT_0(dstpos < nrows());
00786     ARAGELI_ASSERT_0(srcvec.size() == ncols());
00787 
00788     unique();
00789     size_type endpos = ncols();
00790     for(size_type i = 0, j = dstpos*ncols(); i < endpos; ++i, ++j)
00791         (mem(j) *= x) += y*srcvec[i];
00792 }
00793 
00794 
00795 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00796 
00797 template <typename T, bool REFCNT>
00798 void matrix<T, REFCNT>::insert_col (size_type pos, const T& val)
00799 {
00800     ARAGELI_ASSERT_0(pos <= ncols());
00801 
00802     unique();
00803     size_type oldsize = size();
00804 
00805     if(oldsize == 0)
00806     {
00807         rep().cols++;
00808         return;
00809     }
00810 
00811     mem().resize(oldsize + nrows());
00812 
00813     // reverse copying of the data
00814 
00815     iterator src = mem().begin() + oldsize; // at the old end of the storage
00816     iterator dst = mem().end();
00817     ARAGELI_ASSERT_1(dst == src + nrows());
00818     iterator end = dst - (ncols() - pos);
00819     
00820     // copying of the last piece (the end of the last row)
00821     while(dst != end)*--dst = *--src;
00822 
00823     ARAGELI_ASSERT_1(src != mem().begin());
00824     ARAGELI_ASSERT_1(src <= dst);
00825     *(--dst) = val;
00826     ARAGELI_ASSERT_1(dst - src == nrows() - 1);
00827 
00828     size_type newncols = ncols() + 1;
00829     iterator endend = mem().begin() + pos + 1;  
00830     
00831     for(;;)
00832     {
00833         if(end == endend)break;
00834         end -= newncols;
00835         while(dst != end)*--dst = *--src;
00836         *(--dst) = val;
00837     }
00838 
00839     ARAGELI_ASSERT_1(dst == src);
00840     ARAGELI_ASSERT_1(dst == mem().begin() + pos);
00841     
00842     rep().cols++;
00843     
00844 
00846 
00847     //transpose();
00848     //insert_row(pos, val);
00849     //transpose();
00850 }
00851 
00852 
00853 template <typename T, bool REFCNT>
00854 template <typename T1, bool REFCNT1>
00855 void matrix<T, REFCNT>::insert_col
00856 (size_type pos, const vector<T1, REFCNT1>& vals)
00857 {
00858     ARAGELI_ASSERT_0(pos <= ncols());
00859     ARAGELI_ASSERT_0(vals.size() >= nrows());
00860 
00861     unique();
00862     if(ncols() == 0 && nrows() == 0)resize(vals.size(), 0);
00863     size_type oldsize = size();
00864 
00865     if(oldsize == 0)
00866     {
00867         rep().cols++;
00868         return; // ERROR
00869     }
00870 
00871     mem().resize(oldsize + nrows());
00872 
00873     // reverse copying of the data
00874 
00875     iterator src = mem().begin() + oldsize; // at the old end of the storage
00876     iterator dst = mem().end();
00877     ARAGELI_ASSERT_1(dst == src + nrows());
00878     iterator end = dst - (ncols() - pos);
00879     
00880     // copying of the last piece (the end of the last row)
00881     while(dst != end)*--dst = *--src;
00882 
00883     //ARAGELI_ASSERT_1(src != mem().begin());
00884     ARAGELI_ASSERT_1(src <= dst);
00885     typename vector<T1, REFCNT1>::const_iterator pval = vals.begin() + nrows();
00886     *(--dst) = *(--pval);
00887     ARAGELI_ASSERT_1(dst - src == nrows() - 1);
00888 
00889     size_type newncols = ncols() + 1;
00890     iterator endend = mem().begin() + pos + 1;
00891     
00892     for(;;)
00893     {
00894         if(end == endend)break;
00895         end -= newncols;
00896         while(dst != end)*--dst = *--src;
00897         *(--dst) = *(--pval);
00898     }
00899 
00900     ARAGELI_ASSERT_1(dst == src);
00901     ARAGELI_ASSERT_1(dst == mem().begin() + pos);
00902     ARAGELI_ASSERT_1(pval == vals.begin());
00903     
00904     rep().cols++;
00905     
00906     
00908 
00909     //transpose();
00910     //insert_row(pos, vals);
00911     //transpose();
00912 }
00913 
00914 
00915 template <typename T, bool REFCNT>
00916 template <typename In>
00917 void matrix<T, REFCNT>::insert_col (size_type pos, In first)
00918 {
00919     ARAGELI_ASSERT_0(pos <= ncols());
00920 
00921     unique();
00922     size_type oldsize = size();
00923 
00924     if(oldsize == 0)
00925     {
00926         rep().cols++;
00927         return;
00928     }
00929 
00930     mem().resize(oldsize + nrows());
00931 
00932     // reverse copying of the data
00933 
00934     iterator src = mem().begin() + oldsize; // at the old end of the storage
00935     iterator dst = mem().end();
00936     ARAGELI_ASSERT_1(dst == src + nrows());
00937     iterator end = dst - (ncols() - pos);
00938     
00939     // copying of the last piece (the end of the last row)
00940     while(dst != end)*--dst = *--src;
00941 
00942     ARAGELI_ASSERT_1(src != mem().begin());
00943     ARAGELI_ASSERT_1(src <= dst);
00944     //*(--dst) = *(--pval);
00945     --dst;
00946     ARAGELI_ASSERT_1(dst - src == nrows() - 1);
00947 
00948     size_type newncols = ncols() + 1;
00949     iterator endend = mem().begin() + pos + 1;  
00950     
00951     for(;;)
00952     {
00953         if(end == endend)break;
00954         end -= newncols;
00955         while(dst != end)*--dst = *--src;
00956         //*(--dst) = *(--pval);
00957         --dst;
00958     }
00959 
00960     ARAGELI_ASSERT_1(dst == src);
00961     ARAGELI_ASSERT_1(dst == mem().begin() + pos);
00962     //ARAGELI_ASSERT_1(pval == vals.begin());
00963     
00964     rep().cols++;
00965 
00966     end = mem().end() - (newncols - pos) + 1;
00967     for(dst = begin() + pos; dst < end; dst += newncols)
00968         *dst = *first++;
00969 
00970 
00972 
00973     //transpose();
00974     //insert_row(pos, first);
00975     //transpose();
00976 }
00977 
00978 
00979 template <typename T, bool REFCNT>
00980 void matrix<T, REFCNT>::insert_cols
00981 (size_type pos, size_type n, const T& val)
00982 {
00983     ARAGELI_ASSERT_0(pos <= ncols());
00984 
00985     // WARNING. This is slow implementation.
00986 
00987     for(size_type i = pos; i < pos + n; ++i)
00988         insert_col(pos, val);
00989 
00990 
00992 
00993     //transpose();
00994     //insert_rows(pos, n, val);
00995     //transpose();
00996 }
00997 
00998 
00999 template <typename T, bool REFCNT>
01000 template <typename T1, bool REFCNT1>
01001 void matrix<T, REFCNT>::insert_cols
01002 (size_type pos, size_type n, const vector<T1, REFCNT1>& vals)
01003 {
01004     ARAGELI_ASSERT_0(pos <= ncols());
01005 
01006     // WARNING. This is slow implementation.
01007 
01008     for(size_type i = pos; i < pos + n; ++i)
01009         insert_col(pos, vals);
01010 
01011 
01013 
01014     //transpose();
01015     //insert_rows(pos, n, vals);
01016     //transpose();
01017 }
01018 
01019 
01020 
01021 template <typename T, bool REFCNT>
01022 template <typename In>
01023 void matrix<T, REFCNT>::insert_cols
01024 (size_type pos, size_type n, In first)
01025 {
01026     ARAGELI_ASSERT_0(pos <= ncols());
01027 
01028     // WARNING. This is slow implementation.
01029 
01030     for(size_type i = pos; i < pos + n; ++i)
01031         insert_col(pos, first);
01032 
01033 
01035 
01036     //transpose();
01037     //insert_rows(pos, n, first);
01038     //transpose();
01039 }
01040 
01041 
01042 template <typename T, bool REFCNT>
01043 void matrix<T, REFCNT>::erase_col (size_type pos)
01044 {
01045     ARAGELI_ASSERT_0(pos < ncols());
01046     
01047     unique();
01048     size_type oldsize = size();
01049 
01050     if(oldsize == 0)
01051     {
01052         rep().cols--;
01053         return;
01054     }
01055 
01056     iterator dst = mem().begin() + pos;
01057     iterator src = dst + 1;
01058     size_type newncols = ncols() - 1;
01059     iterator endend = mem().end() - (ncols() - pos) + 1;
01060 
01061     while(src != endend)
01062     {
01063         iterator end = src + newncols;
01064         while(src != end)*dst++ = *src++;
01065         ++src;  // jump over deleted element in the current row
01066     }
01067 
01068     iterator end = mem().end();
01069     while(src != end)*dst++ = *src++;
01070 
01071     mem().resize(oldsize - nrows());
01072     rep().cols--;
01073 
01075 
01076     //transpose();
01077     //erase_row(pos);
01078     //transpose();
01079 }
01080 
01081 
01082 template <typename T, bool REFCNT>
01083 void matrix<T, REFCNT>::erase_cols (size_type pos, size_type n)
01084 {
01085     ARAGELI_ASSERT_0(pos < ncols());
01086     ARAGELI_ASSERT_0(pos + n <= ncols());
01087 
01088     unique();
01089     size_type oldsize = size();
01090 
01091     if(oldsize == 0)
01092     {
01093         rep().cols-=n;
01094         return;
01095     }
01096 
01097     iterator dst = mem().begin() + pos;
01098     iterator src = dst + n;
01099     size_type newncols = ncols() - n;
01100     iterator endend = mem().end() - (newncols - pos);
01101 
01102     while(src != endend)
01103     {
01104         iterator end = src + newncols;
01105         while(src != end)*dst++ = *src++;
01106         src += n;   // jump over deleted elements in the current row
01107     }
01108 
01109     iterator end = mem().end();
01110     while(src != end)*dst++ = *src++;
01111 
01112     mem().resize(oldsize - n*nrows());
01113     rep().cols -= n;
01114     
01115 
01117 
01118     //transpose();
01119     //erase_rows(pos, n);
01120     //transpose();
01121 }
01122 
01123 template <typename T, bool REFCNT>
01124 void matrix<T, REFCNT>::swap_cols (size_type xpos, size_type ypos)
01125 {
01126     ARAGELI_ASSERT_0(xpos < ncols());
01127     ARAGELI_ASSERT_0(ypos < ncols());
01128 
01129     if(xpos == ypos || is_empty())return;
01130 
01131     unique();
01132     
01133     iterator p1 = mem().begin() + xpos, p2 = mem().begin() + ypos;
01134     size_type nc = ncols();
01135     iterator end = mem().end() - (nc - xpos);
01136 
01137     for(;;)
01138     {
01139         std::iter_swap(p1, p2);
01140         if(p1 == end)break;
01141         p1 += nc; p2 += nc;
01142     }
01143 
01144     ARAGELI_ASSERT_1(mem().end() - (nc - ypos) == p2);
01145     
01146 
01148 
01149     //matrix t = *this;
01150     //t.transpose();
01151     //t.swap_rows(xpos, ypos);
01152     //t.transpose();
01153     //ARAGELI_ASSERT_1(t.nrows() == nrows() && t.ncols() == ncols());
01154     //std::copy(t.mem().begin(), t.mem().end(), mem().begin());
01155 }
01156 
01157 
01158 template <typename T, bool REFCNT>
01159 template <typename T1>
01160 void matrix<T, REFCNT>::mult_col (size_type i, const T1& x)
01161 {
01162     ARAGELI_ASSERT_0(i < ncols());
01163 
01164     if(is_empty())return;
01165 
01166     unique();
01167     
01168     iterator p = mem().begin() + i;
01169     size_type nc = ncols();
01170     iterator end = mem().end() - (nc - i);
01171 
01172     for(;;)
01173     {
01174         *p *= x;
01175         if(p == end)break;
01176         p += nc;
01177     }
01178 
01179 
01181 
01182     //matrix t = *this;
01183     //t.transpose();
01184     //t.mult_row(i, x);
01185     //t.transpose();
01186     //ARAGELI_ASSERT_1(t.nrows() == nrows() && t.ncols() == ncols());
01187     //std::copy(t.mem().begin(), t.mem().end(), mem().begin());
01188 }
01189 
01190 
01191 template <typename T, bool REFCNT>
01192 template <typename T1>
01193 void matrix<T, REFCNT>::div_col (size_type i, const T1& x)
01194 {
01195     ARAGELI_ASSERT_0(i < ncols());
01196 
01197     if(is_empty())return;
01198 
01199     unique();
01200 
01201     iterator p = mem().begin() + i;
01202     size_type nc = ncols();
01203     iterator end = mem().end() - (nc - i);
01204 
01205     for(;;)
01206     {
01207         *p /= x;
01208         if(p == end)break;
01209         p += nc;
01210     }
01211 }
01212 
01213 
01214 
01215 template <typename T, bool REFCNT>
01216 template <typename T1>
01217 void matrix<T, REFCNT>::mod_col (size_type i, const T1& x)
01218 {
01219     ARAGELI_ASSERT_0(i < ncols());
01220 
01221     if(is_empty())return;
01222 
01223     unique();
01224 
01225     iterator p = mem().begin() + i;
01226     size_type nc = ncols();
01227     iterator end = mem().end() - (nc - i);
01228 
01229     for(;;)
01230     {
01231         *p = mod(*p, x);
01232         if(p == end)break;
01233         p += nc;
01234     }
01235 }
01236 
01237 
01238 
01239 // col[dstpos] += col[srcpos]
01240 template <typename T, bool REFCNT>
01241 void matrix<T, REFCNT>::add_cols (size_type dstpos, size_type srcpos)
01242 {
01243     ARAGELI_ASSERT_0(dstpos < ncols());
01244     ARAGELI_ASSERT_0(srcpos < ncols());
01245     ARAGELI_ASSERT_0(srcpos != dstpos);
01246 
01247     if(is_empty())return;
01248 
01249     unique();
01250     
01251     iterator p1 = mem().begin() + dstpos, p2 = mem().begin() + srcpos;
01252     size_type nc = ncols();
01253     iterator end = mem().end() - (nc - dstpos);
01254 
01255     for(;;)
01256     {
01257         *p1 += *p2;
01258         if(p1 == end)break;
01259         p1 += nc; p2 += nc;
01260     }
01261 
01262     ARAGELI_ASSERT_1(mem().end() - (nc - srcpos) == p2);
01263     
01265 
01266     //matrix t = *this;
01267     //t.transpose();
01268     //t.add_rows(dstpos, srcpos);
01269     //t.transpose();
01270     //ARAGELI_ASSERT_1(t.nrows() == nrows() && t.ncols() == ncols());
01271     //std::copy(t.mem().begin(), t.mem().end(), mem().begin());
01272 }
01273 
01274 
01275 // col[dstpos] -= col[srcpos]
01276 template <typename T, bool REFCNT>
01277 void matrix<T, REFCNT>::sub_cols (size_type dstpos, size_type srcpos)
01278 {
01279     ARAGELI_ASSERT_0(dstpos < ncols());
01280     ARAGELI_ASSERT_0(srcpos < ncols());
01281     ARAGELI_ASSERT_0(srcpos != dstpos);
01282 
01283     if(is_empty())return;
01284 
01285     unique();
01286     
01287     iterator p1 = mem().begin() + dstpos, p2 = mem().begin() + srcpos;
01288     size_type nc = ncols();
01289     iterator end = mem().end() - (nc - dstpos);
01290 
01291     for(;;)
01292     {
01293         *p1 -= *p2;
01294         if(p1 == end)break;
01295         p1 += nc; p2 += nc;
01296     }
01297 
01298     ARAGELI_ASSERT_1(mem().end() - (nc - srcpos) == p2);
01299     
01301 
01302     //matrix t = *this;
01303     //t.transpose();
01304     //t.sub_rows(dstpos, srcpos);
01305     //t.transpose();
01306     //ARAGELI_ASSERT_1(t.nrows() == nrows() && t.ncols() == ncols());
01307     //std::copy(t.mem().begin(), t.mem().end(), mem().begin());
01308 }
01309 
01310 
01311 // col[dstpos] += y*col[srcpos]
01312 template <typename T, bool REFCNT>
01313 template <typename T2>
01314 void matrix<T, REFCNT>::addmult_cols
01315 (size_type dstpos, size_type srcpos, const T2& y)
01316 {
01317     ARAGELI_ASSERT_0(dstpos < ncols());
01318     ARAGELI_ASSERT_0(srcpos < ncols());
01319     ARAGELI_ASSERT_0(srcpos != dstpos);
01320 
01321     if(is_empty())return;
01322 
01323     unique();
01324     
01325     iterator p1 = mem().begin() + dstpos, p2 = mem().begin() + srcpos;
01326     size_type nc = ncols();
01327     iterator end = mem().end() - (nc - dstpos);
01328 
01329     for(;;)
01330     {
01331         *p1 += y*(*p2);
01332         if(p1 == end)break;
01333         p1 += nc; p2 += nc;
01334     }
01335 
01336     ARAGELI_ASSERT_1(mem().end() - (nc - srcpos) == p2);
01337 }
01338 
01339 
01340 // col[dstpos] = x*col[dstpos] + y*col[srcpos]
01341 template <typename T, bool REFCNT>
01342 template <typename T1, typename T2>
01343 void matrix<T, REFCNT>::addmult_cols
01344 (
01345     size_type dstpos, const T1& x,
01346     size_type srcpos, const T2& y
01347 )
01348 {
01349     ARAGELI_ASSERT_0(dstpos < ncols());
01350     ARAGELI_ASSERT_0(srcpos < ncols());
01351     ARAGELI_ASSERT_0(srcpos != dstpos);
01352 
01353     if(is_empty())return;
01354 
01355     unique();
01356     
01357     iterator p1 = mem().begin() + dstpos, p2 = mem().begin() + srcpos;
01358     size_type nc = ncols();
01359     iterator end = mem().end() - (nc - dstpos);
01360 
01361     for(;;)
01362     {
01363         *p1 = x*(*p1) + y*(*p2);
01364         if(p1 == end)break;
01365         p1 += nc; p2 += nc;
01366     }
01367 
01368     ARAGELI_ASSERT_1(mem().end() - (nc - srcpos) == p2);
01369 }
01370 
01371 
01372 template <typename T, bool REFCNT>
01373 template <typename T1, typename V, typename T2>
01374 void matrix<T, REFCNT>::addmult_cols
01375 (
01376     size_type dstpos, const T1& x,
01377     const V& srcvec, const T2& y
01378 )
01379 {
01380     ARAGELI_ASSERT_0(dstpos < ncols());
01381     ARAGELI_ASSERT_0(srcvec.size() == nrows());
01382 
01383     if(is_empty())return;
01384 
01385     unique();
01386     
01387     iterator p1 = mem().begin() + dstpos;
01388     typename V::const_iterator p2 = srcvec.begin();
01389     size_type nc = ncols();
01390     iterator end = mem().end() - (nc - dstpos);
01391 
01392     for(;;)
01393     {
01394         *p1 = x*(*p1) + y*(*p2);
01395         if(p1 == end)break;
01396         p1 += nc; ++p2;
01397     }
01398 
01399     ARAGELI_ASSERT_1(p2 == srcvec.end());
01400 }
01401 
01402 
01403 template <typename T, bool REFCNT>
01404 template <typename V>
01405 V& matrix<T, REFCNT>::copy_col
01406 (size_type i, V& res) const
01407 {
01408     ARAGELI_ASSERT_0(i < ncols());
01409     res.resize(nrows());
01410     for(size_type j = 0; j < nrows(); ++j)
01411         res[j] = el(j, i);
01412     return res;
01413 }
01414 
01415 
01416 template <typename T, bool REFCNT>
01417 template <typename SV, typename M>
01418 M& matrix<T, REFCNT>::copy_rows (const SV& sv, M& res) const
01419 {
01420     size_type nc = ncols();
01421     res.assign_fromsize(sv.size(), nc);
01422 
01423     const_iterator data = begin();
01424     typename M::iterator resi = res.begin();
01425     typename SV::const_iterator svi = sv.begin(), svend = sv.end();
01426 
01427     for(; svi != svend; ++svi)
01428     {
01429         size_type r = *svi;
01430         ARAGELI_ASSERT_0(r < nrows());
01431         resi = std::copy(data + r*nc, data + r*nc + nc, resi);
01432     }
01433 
01434     return res;
01435 }
01436 
01437 
01438 template <typename T, bool REFCNT>
01439 template <typename SV>
01440 void matrix<T, REFCNT>::erase_rows (const SV& sv)
01441 {
01442     if(sv.is_empty())return;
01443 
01444     SV svt = sv;    // copy because need sorting and uniquelization
01445     typedef typename SV::iterator SViter;
01446     std::sort(svt.begin(), svt.end());
01447 
01448     SViter
01449         svti = svt.begin(),
01450         svtend = std::unique(svti, svt.end());
01451 
01452     size_type curerased = *svti, nc = ncols();
01453 
01454     ARAGELI_ASSERT_0(*(svtend-1) < size());
01455     ARAGELI_ASSERT_0(curerased < size());
01456     
01457     iterator
01458         thisdst = begin() + curerased*nc,
01459         thissrc = thisdst + nc,
01460         thisend = end();
01461 
01462     for(;;)
01463     {
01464         ++svti;
01465 
01466         if(svti != svtend && *svti == curerased+1)
01467         {
01468             ++curerased;
01469             ++svti;
01470             ARAGELI_ASSERT_0(thissrc != thisend);
01471             thissrc += nc;
01472         }
01473 
01474         ARAGELI_ASSERT_1(thissrc != thisend || svti == svtend);
01475 
01476         iterator tend =     // end of current copied part of the vector
01477             svti == svtend ?
01478             thisend : thissrc + (*svti - curerased - 1)*nc;
01479 
01480         thisdst = std::copy(thissrc, tend, thisdst);
01481 
01482         if(tend == thisend)
01483             break;
01484 
01485         thissrc = tend + nc;
01486         ARAGELI_ASSERT_1(svti != svtend);
01487         curerased = *svti;
01488     }
01489 
01490     ARAGELI_ASSERT_1(svti == svtend);
01491     ARAGELI_ASSERT_1(thisdst + (svtend - svt.begin())*nc == thisend);
01492     mem().erase(thisdst, thisend);
01493     ARAGELI_ASSERT_1(mem().size()%nc == 0);
01494     rep().rows = mem().size()/nc;
01495 }
01496 
01497 
01498 template <typename T, bool REFCNT>
01499 template <typename SV, typename M>
01500 M& matrix<T, REFCNT>::copy_cols (const SV& sv, M& res) const
01501 {
01502     // WARNING!!! SLOW IMPLEMENTATION!!!
01503 
01504     res.assign_fromsize(nrows(), sv.size());
01505     typename SV::const_iterator svi = sv.begin(), svend = sv.end();
01506     size_type nr = nrows();
01507     typename M::size_type i = 0;
01508 
01509     for(; svi != svend; ++svi, ++i)
01510     {
01511         size_type c = *svi;
01512         for(size_type r = 0; r < nr; ++r)
01513             res(r, i) = el(r, c);
01514     }
01515 
01516     return res;
01517 }
01518 
01519 
01520 template <typename T, bool REFCNT>
01521 template <typename SV>
01522 void matrix<T, REFCNT>::erase_cols (const SV& sv)
01523 {
01524     // WARNING!!! SLOW IMPLEMENTATION!!!
01525 
01526     if(sv.is_empty())return;
01527 
01528     SV svt = sv;    // copy because need sorting and uniquelization
01529     std::sort(svt.begin(), svt.end(), std::greater<typename SV::value_type>());
01530     svt.erase(std::unique(svt.begin(), svt.end()), svt.end());
01531 
01532     for(typename SV::const_iterator i = svt.begin(); i < svt.end(); ++i)
01533         erase_col(*i);
01534 }
01535 
01536 
01537 template <typename T, bool REFCNT>
01538 template <typename RS, typename CS, typename M>
01539 M& matrix<T, REFCNT>::copy_submatrix (const RS& rs, const CS& cs, M& res) const
01540 {
01541     // WARNING!!! SLOW IMPLEMENTATION!!!
01542 
01543     res.assign_fromsize(rs.size(), cs.size());
01544 
01545     for(size_type i = 0; i < rs.size(); ++i)
01546         for(size_type j = 0; j < cs.size(); ++j)
01547             res(i, j) = el(rs[i], cs[j]);
01548 
01549     return res;
01550 }
01551 
01552 
01553 template <typename T, bool REFCNT>
01554 template <typename RS, typename CS>
01555 void matrix<T, REFCNT>::erase_submatrix (const RS& rs, const CS& cs)
01556 {
01557     erase_rows(rs);
01558     erase_cols(cs);
01559 }
01560 
01561 
01562 template <typename T, bool REFCNT>
01563 bool matrix<T, REFCNT>::do_pack ()
01564 {
01565     ARAGELI_ASSERT_1(size() < capacity());
01566 
01567     unique();
01568     Rep trep = rep();
01569     trep.swap(rep());
01570 }
01571 
01572 
01573 
01574 
01575 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01576 
01577 //template
01578 //<
01579 //  typename T1, bool REFCNT1,
01580 //  typename T2, bool REFCNT2
01581 //>
01582 //bool operator==
01583 //(
01584 //  const matrix<T1, REFCNT1>& a,
01585 //  const matrix<T2, REFCNT2>& b
01586 //)
01587 //{
01588 //  if(a.nrows() != b.nrows() || a.ncols() != b.ncols())
01589 //      return false;
01590 //  
01591 //  return std::equal(a.begin(), a.end(), b.begin());
01592 //}
01593 
01594 
01595 template
01596 <
01597     typename T1, bool REFCNT1,
01598     typename T2, bool REFCNT2
01599 >
01600 vector<T2, REFCNT2> operator*
01601 (
01602     const matrix<T1, REFCNT1>& m,
01603     const vector<T2, REFCNT2>& x
01604 )
01605 {
01606     ARAGELI_ASSERT_0(m.ncols() == x.size());
01607     
01608     vector<T2, REFCNT2> res(m.nrows());
01609 
01610     for(std::size_t i = 0; i < m.nrows(); ++i)
01611     {
01612         typename vector<T2, REFCNT2>::reference cur = res[i];
01613         
01614         for(std::size_t j = 0; j < m.ncols(); ++j)
01615             cur += m(i, j)*x[j];
01616     }
01617 
01618     return res;
01619 }
01620 
01621 
01622 template
01623 <
01624     typename T2, bool REFCNT2,
01625     typename T1, bool REFCNT1
01626 >
01627 vector<T2, REFCNT2> operator*
01628 (
01629     const vector<T2, REFCNT2>& x,
01630     const matrix<T1, REFCNT1>& m
01631 )
01632 {
01633     ARAGELI_ASSERT_0(m.nrows() == x.size());
01634     
01635     vector<T2, REFCNT2> res(m.ncols());
01636 
01637     for(std::size_t i = 0; i < m.ncols(); ++i)
01638     {
01639         typename vector<T2, REFCNT2>::reference cur = res[i];
01640         
01641         for(std::size_t j = 0; j < m.nrows(); ++j)
01642             cur += m(j, i)*x[j];
01643     }
01644 
01645     return res;
01646 }
01647 
01648 
01649 template <typename T, bool REFCNT>
01650 std::ostream& output_list
01651 (
01652     std::ostream& out,
01653     const matrix<T, REFCNT>& x,
01654     const char* first_bracket,
01655     const char* second_bracket,
01656     const char* row_separator,
01657     const char* first_row_bracket,
01658     const char* second_row_bracket,
01659     const char* col_separator
01660 )
01661 {
01662     out << first_bracket;
01663     typedef typename matrix<T, REFCNT>::size_type size_type;
01664     
01665     if(!x.is_empty())
01666     {
01667         ARAGELI_ASSERT_0(x.ncols() && x.nrows());
01668         
01669         out << first_row_bracket << x(0, 0);
01670         for(size_type j = 1; j < x.ncols(); ++j)
01671             out << col_separator << x(0, j);
01672         out << second_row_bracket;
01673         
01674         for(size_type i = 1; i < x.nrows(); ++i)
01675         {
01676             out << row_separator << first_row_bracket << x(i, 0);       
01677             for(size_type j = 1; j < x.ncols(); ++j)
01678                 out << col_separator << x(i, j);
01679             out << second_row_bracket;
01680         }
01681     }
01682     
01683     out << second_bracket;
01684     return out;
01685 }
01686 
01687 
01688 template <typename T, bool REFCNT>
01689 std::istream& input_list
01690 (
01691     std::istream& in,
01692     matrix<T, REFCNT>& x,
01693     const char* first_bracket,
01694     const char* second_bracket,
01695     const char* row_separator,
01696     const char* first_row_bracket,
01697     const char* second_row_bracket,
01698     const char* col_separator
01699 )
01700 {
01701     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(first_bracket));
01702     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(second_bracket));
01703     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(row_separator));
01704     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(first_row_bracket));
01705     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(second_row_bracket));
01706     ARAGELI_ASSERT_0(_Internal::is_not_contains_spaces(col_separator));
01707 
01708     if(!_Internal::read_literal(in, first_bracket))
01709     {
01710         in.clear(std::ios_base::failbit);
01711         return in;
01712     }
01713 
01714     if(*second_bracket && _Internal::read_literal(in, second_bracket))
01715     { // empty matrix
01716         x.assign_fromsize(0, 0);
01717         return in;
01718     }
01719 
01720     typedef std::list<vector<T, true> > Buf;    // temporary buffer for rows
01721     Buf buf;
01722     std::size_t cols;
01723 
01724     do
01725     {
01726         vector<T, false> tmp;
01727         
01728         input_list
01729         (
01730             in, tmp, first_row_bracket,
01731             second_row_bracket, col_separator
01732         );
01733 
01734         if(!in)
01735         {
01736             in.clear(std::ios_base::badbit);
01737             return in;
01738         }
01739 
01740         if(buf.empty())
01741             cols = tmp.size();
01742         else if(cols != tmp.size())
01743         {
01744             in.clear(std::ios_base::badbit);
01745             return in;
01746         }
01747 
01748         buf.push_back(tmp);
01749 
01750     }while(_Internal::read_literal(in, row_separator));
01751 
01752 
01753     if(!_Internal::read_literal(in, second_bracket))
01754     {
01755         in.clear(std::ios_base::badbit);
01756         return in;
01757     }
01758 
01759     x.assign_fromsize(buf.size(), cols);
01760     typename matrix<T, REFCNT>::iterator j = x.begin();
01761     
01762     for(typename Buf::iterator i = buf.begin(); i != buf.end(); ++i)
01763     {
01764         ARAGELI_ASSERT_1(i->size() == cols);
01765         j = std::copy(i->begin(), i->end(), j);
01766     }
01767 
01768     ARAGELI_ASSERT_1(j == x.end());
01769 
01770     return in;
01771 }
01772 
01773 
01774 template <typename T, bool REFCNT>
01775 std::ostream& output_aligned
01776 (
01777     std::ostream& out,
01778     const matrix<T, REFCNT>& x,
01779     const char* left_col,
01780     const char* right_col,
01781     const char* inter_col
01782 )
01783 {
01784     if(x.is_empty())
01785     {
01786         out << left_col << right_col << '\n';
01787         return out;
01788     }
01789     
01790     std::vector<std::string> buf(x.size());
01791     std::vector<std::size_t> maxlens(x.ncols());
01792     std::size_t ii = 0; // index for buf
01793     
01794     for(std::size_t j = 0; j < x.ncols(); ++j)
01795     {
01796         std::size_t maxlen = 0;
01797 
01798         for(std::size_t i = 0; i < x.nrows(); ++i, ++ii)
01799         {
01800             std::ostringstream strbuf;
01801             strbuf.copyfmt(out);
01802             strbuf << x(i, j);
01803             buf[ii] = strbuf.str();
01804 
01805             if(buf[ii].length() > maxlen)
01806                 maxlen = buf[ii].length();
01807         }
01808 
01809         maxlens[j] = maxlen;
01810     }
01811 
01812 
01813 
01814     for(std::size_t i = 0; i < x.nrows(); ++i)
01815     {
01816         out << left_col;
01817 
01818         std::string& str = buf[i];
01819         std::size_t numspace = maxlens[0] - str.length();
01820 
01821         out
01822             << std::string(numspace/2, ' ')
01823             << str << std::string(numspace - numspace/2, ' ');
01824         
01825         for(std::size_t j = 1; j < x.ncols(); ++j)
01826         {
01827             std::string& str = buf[j*x.nrows() + i];
01828             std::size_t numspace = maxlens[j] - str.length();
01829 
01830             out
01831                 << inter_col << std::string(numspace/2, ' ')
01832                 << str << std::string(numspace - numspace/2, ' ');
01833         }
01834 
01835         out << right_col << '\n';
01836     }
01837 
01838     return out;
01839 }
01840 
01841 
01842 template
01843 <
01844     typename T1, bool REFCNT1,
01845     typename T2, bool REFCNT2
01846 >
01847 std::ostream& output_aligned_ver_pair
01848 (
01849     std::ostream& out,
01850     const matrix<T1, REFCNT1>& m1,
01851     const matrix<T2, REFCNT2>& m2,
01852     const char* left_col,
01853     const char* right_col,
01854     const char* inter_col,
01855     const char* hsplitter
01856 )
01857 {
01858     ARAGELI_ASSERT_0(m1.ncols() == m2.ncols());
01859 
01860     if(m1.is_empty() && m2.is_empty())
01861     {
01862         out << left_col << right_col << '\n';
01863         return out;
01864     }
01865 
01866     std::vector<std::string> buf(m1.size() + m2.size());
01867     std::vector<std::size_t> maxlens(m1.ncols());
01868     std::size_t ii = 0; // index for buf
01869     
01870     for(std::size_t j = 0; j < m1.ncols(); ++j)
01871     {
01872         std::size_t maxlen = 0;
01873 
01874         for(std::size_t i = 0; i < m1.nrows(); ++i, ++ii)
01875         {
01876             std::string& curbuf = buf[ii];
01877             
01878             std::ostringstream strbuf;
01879             strbuf << m1(i, j);
01880             curbuf = strbuf.str();
01881 
01882             std::size_t curlen = curbuf.length();
01883             if(curlen > maxlen)maxlen = curlen;
01884         }
01885 
01886         for(std::size_t i = 0; i < m2.nrows(); ++i, ++ii)
01887         {
01888             std::string& curbuf = buf[ii];
01889             
01890             std::ostringstream strbuf;
01891             strbuf << m2(i, j);
01892             curbuf = strbuf.str();
01893 
01894             std::size_t curlen = curbuf.length();
01895             if(curlen > maxlen)maxlen = curlen;
01896         }
01897 
01898         maxlens[j] = maxlen;
01899     }
01900 
01901 
01902     for(std::size_t i = 0; i < m1.nrows(); ++i)
01903     {
01904         out << left_col;
01905 
01906         std::string& str = buf[i];
01907         std::size_t numspace = maxlens[0] - str.length();
01908 
01909         out
01910             << std::string(numspace/2, ' ')
01911             << str << std::string(numspace - numspace/2, ' ');
01912         
01913         for(std::size_t j = 1; j < m1.ncols(); ++j)
01914         {
01915             std::string& str = buf[j*(m1.nrows() + m2.nrows()) + i];
01916             std::size_t numspace = maxlens[j] - str.length();
01917 
01918             out
01919                 << inter_col << std::string(numspace/2, ' ')
01920                 << str << std::string(numspace - numspace/2, ' ');
01921         }
01922 
01923         out << right_col << '\n';
01924     }
01925 
01926     ARAGELI_ASSERT_1(m1.ncols());
01927 
01928     std::size_t width = (m1.ncols() - 1)*std::strlen(inter_col);
01929     width = std::accumulate(maxlens.begin(), maxlens.end(), width);
01930     std::size_t splitter_len = std::strlen(hsplitter);
01931     std::size_t insplit = width/splitter_len;
01932 
01933     out << left_col;
01934 
01935     for(std::size_t i = 0; i < insplit; ++i)
01936         out << hsplitter;
01937 
01938     insplit = width%splitter_len;
01939 
01940     for(std::size_t i = 0; i < insplit; ++i)
01941         out << hsplitter[i];
01942 
01943     out << right_col << '\n';
01944     
01945     for(std::size_t i = 0; i < m2.nrows(); ++i)
01946     {
01947         out << left_col;
01948 
01949         std::string& str = buf[i +  + m1.nrows()];
01950         std::size_t numspace = maxlens[0] - str.length();
01951 
01952         out
01953             << std::string(numspace/2, ' ')
01954             << str << std::string(numspace - numspace/2, ' ');
01955         
01956         for(std::size_t j = 1; j < m2.ncols(); ++j)
01957         {
01958             std::string& str = buf[j*(m1.nrows() + m2.nrows()) + i + m1.nrows()];
01959             std::size_t numspace = maxlens[j] - str.length();
01960 
01961             out
01962                 << inter_col << std::string(numspace/2, ' ')
01963                 << str << std::string(numspace - numspace/2, ' ');
01964         }
01965 
01966         out << right_col << '\n';
01967     }
01968 
01969     return out;
01970 }
01971 
01972 
01973 template
01974 <
01975     typename T1, bool REFCNT1,
01976     typename T2, bool REFCNT2
01977 >
01978 std::ostream& output_aligned_hor_pair
01979 (
01980     std::ostream& out,
01981     const matrix<T1, REFCNT1>& m1,
01982     const matrix<T2, REFCNT2>& m2,
01983     const char* left_col,
01984     const char* right_col,
01985     const char* inter_col,
01986     const char* vsplitter
01987 )
01988 {
01989     ARAGELI_ASSERT_0(m1.nrows() == m2.nrows());
01990 
01991     if(m1.is_empty() && m2.is_empty())
01992     {
01993         out << left_col << right_col << '\n';
01994         return out;
01995     }
01996 
01997     std::vector<std::string> buf1(m1.size());
01998     std::vector<std::size_t> maxlens1(m1.ncols());
01999     std::size_t ii = 0; // index for buf
02000     
02001     for(std::size_t j = 0; j < m1.ncols(); ++j)
02002     {
02003         std::size_t maxlen = 0;
02004 
02005         for(std::size_t i = 0; i < m1.nrows(); ++i, ++ii)
02006         {
02007             std::ostringstream strbuf;
02008             strbuf << m1(i, j);
02009             buf1[ii] = strbuf.str();
02010 
02011             if(buf1[ii].length() > maxlen)
02012                 maxlen = buf1[ii].length();
02013         }
02014 
02015         maxlens1[j] = maxlen;
02016     }
02017 
02018     std::vector<std::string> buf2(m2.size());
02019     std::vector<std::size_t> maxlens2(m1.ncols());
02020     ii = 0; // index for buf
02021 
02022     for(std::size_t j = 0; j < m2.ncols(); ++j)
02023     {
02024         std::size_t maxlen = 0;
02025 
02026         for(std::size_t i = 0; i < m2.nrows(); ++i, ++ii)
02027         {
02028             std::ostringstream strbuf;
02029             strbuf << m2(i, j);
02030             buf2[ii] = strbuf.str();
02031 
02032             if(buf2[ii].length() > maxlen)
02033                 maxlen = buf2[ii].length();
02034         }
02035 
02036         maxlens2[j] = maxlen;
02037     }
02038 
02039 
02040     for(std::size_t i = 0; i < m1.nrows(); ++i)
02041     {
02042         out << left_col;
02043 
02044         {
02045             std::string& str = buf1[i];
02046             std::size_t numspace = maxlens1[0] - str.length();
02047 
02048             out
02049                 << std::string(numspace/2, ' ')
02050                 << str << std::string(numspace - numspace/2, ' ');
02051             
02052             for(std::size_t j = 1; j < m1.ncols(); ++j)
02053             {
02054                 std::string& str = buf1[j*m1.nrows() + i];
02055                 std::size_t numspace = maxlens1[j] - str.length();
02056 
02057                 out
02058                     << inter_col << std::string(numspace/2, ' ')
02059                     << str << std::string(numspace - numspace/2, ' ');
02060             }
02061         }
02062 
02063         out << vsplitter;
02064 
02065         {
02066             std::string& str = buf2[i];
02067             std::size_t numspace = maxlens2[0] - str.length();
02068 
02069             out
02070                 << std::string(numspace/2, ' ')
02071                 << str << std::string(numspace - numspace/2, ' ');
02072             
02073             for(std::size_t j = 1; j < m2.ncols(); ++j)
02074             {
02075                 std::string& str = buf2[j*m2.nrows() + i];
02076                 std::size_t numspace = maxlens2[j] - str.length();
02077 
02078                 out
02079                     << inter_col << std::string(numspace/2, ' ')
02080                     << str << std::string(numspace - numspace/2, ' ');
02081             }
02082         }
02083 
02084         out << right_col << '\n';
02085     }
02086 
02087     return out;
02088 }
02089 
02090 
02091 template
02092 <
02093     typename T1, bool REFCNT1,
02094     typename T2, bool REFCNT2,
02095     typename T3, bool REFCNT3
02096 >
02097 std::ostream& output_aligned_corner_triplet_br
02098 (
02099     std::ostream& out,
02100     const matrix<T1, REFCNT1>& m1,
02101     const matrix<T2, REFCNT2>& m2,
02102     const matrix<T3, REFCNT3>& m3,
02103     const char* left_col,
02104     const char* right_col,
02105     const char* inter_col,
02106     const char* vsplitter,
02107     const char* hsplitter
02108 )
02109 {
02110     /*
02111         ||         m1  ||
02112         ||        ---- ||
02113         ||  m3  |  m2  ||
02114     */
02115 
02116     ARAGELI_ASSERT_0(m1.ncols() == m2.ncols());
02117     ARAGELI_ASSERT_0(m3.nrows() == m2.nrows());
02118 
02119     if(m1.is_empty() && m2.is_empty())
02120     {
02121         out << left_col << right_col;
02122         return out;
02123     }
02124 
02125     std::stringstream strbuf;
02126 
02127     output_aligned_ver_pair(strbuf, m1, m2, "", "", inter_col, hsplitter);
02128     std::string m12str = strbuf.str();
02129     strbuf.str("");
02130 
02131     output_aligned(strbuf, m3, "", "", inter_col);
02132     std::string m3str = strbuf.str();
02133     strbuf.str("");
02134 
02135     std::size_t width3 = m3str.find('\n');
02136     ARAGELI_ASSERT_1(width3 < m3str.length());
02137 
02138     std::string tlspace(width3 + std::strlen(vsplitter), ' ');
02139 
02140     std::size_t cur12 = 0, cur3 = 0;
02141 
02142     for(std::size_t i = 0; i < m1.nrows() + 1; ++i)
02143     {
02144         std::size_t end12 = m12str.find('\n', cur12);
02145         ARAGELI_ASSERT_1(end12 < m12str.length());
02146         
02147         out
02148             << left_col << tlspace
02149             << m12str.substr(cur12, end12 - cur12)
02150             << right_col << '\n';
02151 
02152         cur12 = end12 + 1;
02153     }
02154 
02155     for(std::size_t i = 0; i < m2.nrows(); ++i)
02156     {
02157         std::size_t end3 = m3str.find('\n', cur3);
02158         ARAGELI_ASSERT_1(end3 < m3str.length());
02159 
02160         std::size_t end12 = m12str.find('\n', cur12);
02161         ARAGELI_ASSERT_1(end12 < m12str.length());
02162         
02163         out
02164             << left_col
02165             << m3str.substr(cur3, end3 - cur3)
02166             << vsplitter
02167             << m12str.substr(cur12, end12 - cur12)
02168             << right_col << '\n';
02169 
02170         cur12 = end12 + 1;
02171         cur3 = end3 + 1;
02172     }
02173 
02174     return out;
02175 }
02176 
02177 
02178 template <typename T, bool REFCNT>
02179 std::istream& input_polynom_internal
02180 (std::istream& in, matrix<T, REFCNT>& x)
02181 {
02182     char ch = 0;
02183     in >> ch;
02184     if(!in && !in.eof() || ch != '+' && ch != '-')return in;
02185     matrix<T, REFCNT> res;
02186     input_list(in, res);
02187     if(!in && !in.eof())return in;
02188     if(ch == '-')res.opposite();
02189     x = res;
02190     return in;
02191 }
02192 
02193 
02194 } // namespace Arageli
02195 
02196 
02197 #else
02198 
02199 #include "matrix.hpp"
02200 
02201 
02202 namespace Arageli
02203 {
02204 
02205 const char* matrix_output_list_first_bracket_default = "(";
02206 const char* matrix_output_list_second_bracket_default = ")";
02207 const char* matrix_output_list_row_separator_default = ", ";
02208 const char* matrix_output_list_first_row_bracket_default = "(";
02209 const char* matrix_output_list_second_row_bracket_default = ")";
02210 const char* matrix_output_list_col_separator_default = ", ";
02211 const char* matrix_input_list_first_bracket_default = "(";
02212 const char* matrix_input_list_second_bracket_default = ")";
02213 const char* matrix_input_list_row_separator_default = ",";
02214 const char* matrix_input_list_first_row_bracket_default = "(";
02215 const char* matrix_input_list_second_row_bracket_default = ")";
02216 const char* matrix_input_list_col_separator_default = ",";
02217 const char* matrix_output_aligned_left_col_default = "||";
02218 const char* matrix_output_aligned_right_col_default = "||";
02219 const char* matrix_output_aligned_inter_col_default = " ";
02220 
02221 }
02222 
02223 
02224 #endif // #ifndef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE

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