gauss.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     gauss.hpp -- Some algorithms of linear algebra.
00004 
00005     This file is part of Arageli library.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005--2006
00009     
00010     University of Nizhni Novgorod, Russia
00011 
00012 *****************************************************************************/
00013 
00014 #ifndef _ARAGELI_GAUSS_HPP_
00015 #define _ARAGELI_GAUSS_HPP_
00016 
00017 
00026 #include "config.hpp"
00027 
00028 #include <cmath>
00029 #include <iostream>
00030 #include <iomanip>
00031 #include <functional>
00032 
00033 #include "type_opers.hpp"
00034 #include "type_traits.hpp"
00035 #include "factory.hpp"
00036 #include "exception.hpp"
00037 #include "powerest.hpp"
00038 #include "vector.hpp"
00039 #include "matrix.hpp"
00040 
00041 #include "std_import.hpp"
00042 
00043 namespace Arageli
00044 {
00045 
00046 
00048 
00050 template <typename M>
00051 void gauss_field_row_iter
00052 (
00053     M& a,
00054     typename M::size_type row,
00055     typename M::size_type col
00056 );
00057 
00058 
00060 
00062 template <typename M>
00063 void gauss_field_col_iter
00064 (
00065     M& a,
00066     typename M::size_type row,
00067     typename M::size_type col
00068 );
00069 
00070 
00072 
00074 template <typename M, typename T>
00075 void gauss_bareiss_row_iter
00076 (
00077     M& a,
00078     typename M::size_type row,
00079     typename M::size_type col,
00080     T& det, T& det_denom
00081 );
00082 
00083 
00085 
00087 template <typename M, typename T>
00088 void gauss_bareiss_col_iter
00089 (
00090     M& a,
00091     typename M::size_type row,
00092     typename M::size_type col,
00093     T& det, T& det_denom
00094 );
00095 
00096 
00098 
00100 template <typename M>
00101 void gauss_bareiss_row_iter
00102 (
00103     M& a,
00104     typename M::size_type row,
00105     typename M::size_type col
00106 )
00107 {
00108     typename M::element_type det, det_denom;
00109     gauss_bareiss_row_iter(a, row, col, det, det_denom);
00110 }
00111 
00112 
00114 
00116 template <typename M>
00117 void gauss_bareiss_col_iter
00118 (
00119     M& a,
00120     typename M::size_type row,
00121     typename M::size_type col
00122 )
00123 {
00124     typename M::element_type det, det_denom;
00125     gauss_bareiss_col_iter(a, row, col, det, det_denom);
00126 }
00127 
00128 
00129 namespace ctrl
00130 {
00131 
00132 struct rref_gauss_field_idler
00133 {
00134     class abort : public ctrl::abort {};
00135 
00136     template <typename A>
00137     void preamble (const A&) const {}
00138 
00139     template <typename B, typename Q, typename Det, typename Basis>
00140     void conclusion (const B&, const Q&, const Det&, const Basis&) const {}
00141 
00142     template <typename B, typename Q, typename Det, typename Basis>
00143     void before_iter (const B&, const Q&, const Det&, const Basis&) const {}
00144 
00145     template <typename B, typename Q, typename Det, typename Basis>
00146     void after_iter (const B&, const Q&, const Det&, const Basis&) const {}
00147 
00148     template <typename J>
00149     void find_biggest_in_col (const J&) const {}
00150 
00151     template <typename J>
00152     void negligible_col (const J&) const {}
00153 
00154     template <typename I, typename J>
00155     void pivot_item (const I&, const J& j) const {}
00156 
00157     template <typename I1, typename I2, typename B, typename Q, typename Det>
00158     void swap_rows (const I1& i1, const I2& i2, const B&, const Q&, const Det&) const {}
00159 
00160     template <typename J>
00161     void eliminate_col (const J&) const {}
00162 
00163     template <typename B, typename Q, typename Det>
00164     void after_elimination (const B&, const Q&, const Det&) const {}
00165 };
00166 
00167 
00168 struct rref_gauss_bareiss_idler : public rref_gauss_field_idler
00169 {
00170     class abort : public ctrl::abort {};
00171 
00172     template
00173     <
00174         typename B, typename Q, typename Det,
00175         typename Basis, typename Det_denom
00176     >
00177     void before_iter
00178     (const B&, const Q&, const Det&, const Basis&, const Det_denom&) const {}
00179 
00180     template
00181     <
00182         typename B, typename Q, typename Det,
00183         typename Basis, typename Det_denom
00184     >
00185     void after_iter
00186     (const B&, const Q&, const Det&, const Basis&, const Det_denom&) const {}
00187 
00188     template
00189     <
00190         typename I1, typename I2, typename B,
00191         typename Q, typename Det, typename Det_denom
00192     >
00193     void swap_rows
00194     (const I1&, const I2&, const B&, const Q&, const Det&, const Det_denom&) const {}
00195 
00196     template <typename B, typename Q, typename Det, typename Det_denom>
00197     void after_elimination
00198     (const B&, const Q&, const Det&, const Det_denom&) const {}
00199 
00200     template <typename J>
00201     void find_nonzero_in_col (const J&) const {}
00202 };
00203 
00204 
00205 struct rref_field_idler
00206 {
00207     class abort : public ctrl::abort {};
00208 
00209     rref_gauss_field_idler ctrl_rref_gauss_field () const
00210     { return rref_gauss_field_idler(); }
00211 };
00212 
00213 
00214 struct rref_int_idler
00215 {
00216     class abort : public ctrl::abort {};
00217 
00218     rref_gauss_bareiss_idler ctrl_rref_gauss_bareiss () const
00219     { return rref_gauss_bareiss_idler(); }
00220 };
00221 
00222 
00223 struct rref_idler
00224 {
00225     class abort : public ctrl::abort {};
00226 
00227     rref_field_idler ctrl_rref_field () const
00228     { return rref_field_idler(); }
00229 
00230     rref_int_idler ctrl_rref_int () const
00231     { return rref_int_idler(); }
00232 };
00233 
00234 
00235 } // namespace ctrl
00236 
00237 
00239 
00248 template
00249 <
00250     typename A, typename B, typename Q, typename Basis,
00251     typename T, typename T_factory,
00252     typename Ctrler // control visitor
00253 >
00254 void rref_gauss_field
00255 (
00256     const A& a, B& b, Q& q, Basis& basis,
00257     T& det,
00258     const T_factory& tfctr,
00259     Ctrler ctrler
00260 );
00261 
00262 
00264 template
00265 <
00266     typename A, typename B, typename Q, typename Basis, typename T,
00267     typename Ctrler // control visitor
00268 >
00269 inline void rref_gauss_field
00270 (const A& a, B& b, Q& q, Basis& basis, T& det, Ctrler ctrler)
00271 { rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrler); }
00272 
00273 
00275 template <typename A, typename B, typename Q, typename Basis, typename T>
00276 inline void rref_gauss_field (const A& a, B& b, Q& q, Basis& basis, T& det)
00277 { rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_field_idler()); }
00278 
00279 
00281 template <typename A, typename B, typename Q, typename Basis>
00282 inline void rref_gauss_field (const A& a, B& b, Q& q, Basis& basis)
00283 {
00284     typedef typename B::element_type T;
00285     T det;
00286     rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_field_idler());
00287 }
00288 
00289 
00291 template <typename A, typename B, typename Q>
00292 inline void rref_gauss_field (const A& a, B& b, Q& q)
00293 {
00294     typedef typename B::element_type T;
00295     T det;
00296     vector<typename B::size_type, false> basis;
00297     rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_field_idler());
00298 }
00299 
00300 
00302 template <typename A, typename B>
00303 inline void rref_gauss_field (const A& a, B& b)
00304 {
00305     typedef typename B::element_type T;
00306     T det;
00307     vector<typename B::size_type, false> basis;
00308     B q;
00309     rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_field_idler());
00310 }
00311 
00312 
00314 template <typename A>
00315 inline A rref_gauss_field (const A& a)
00316 {
00317     typedef typename A::element_type T;
00318     T det;
00319     vector<typename A::size_type, false> basis;
00320     A b, q;
00321     rref_gauss_field(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_field_idler());
00322     return b;
00323 }
00324 
00325 // ----------------------------------------
00326 
00328 
00329 template
00330 <
00331     typename A, typename B, typename Q, typename Basis,
00332     typename T, typename T_factory,
00333     typename Ctrler // control visitor
00334 >
00335 inline void rref_field
00336 (
00337     const A& a, B& b, Q& q, Basis& basis,
00338     T& det,
00339     const T_factory& tfctr,
00340     Ctrler ctrler
00341 )
00342 { rref_gauss_field(a, b, q, basis, det, tfctr, ctrler.ctrl_rref_gauss_field()); }
00343 
00344 
00346 template
00347 <
00348     typename A, typename B, typename Q, typename Basis, typename T,
00349     typename Ctrler // control visitor
00350 >
00351 inline void rref_field
00352 (const A& a, B& b, Q& q, Basis& basis, T& det, Ctrler ctrler)
00353 { rref_field(a, b, q, basis, det, factory<T>(), ctrler); }
00354 
00355 
00357 template <typename A, typename B, typename Q, typename Basis, typename T>
00358 inline void rref_field (const A& a, B& b, Q& q, Basis& basis, T& det)
00359 { rref_field(a, b, q, basis, det, factory<T>(), ctrl::rref_field_idler()); }
00360 
00361 
00363 template <typename A, typename B, typename Q, typename Basis>
00364 inline void rref_field (const A& a, B& b, Q& q, Basis& basis)
00365 {
00366     typedef typename B::element_type T;
00367     T det;
00368     rref_field(a, b, q, basis, det, factory<T>(), ctrl::rref_field_idler());
00369 }
00370 
00371 
00373 template <typename A, typename B, typename Q>
00374 inline void rref_field (const A& a, B& b, Q& q)
00375 {
00376     typedef typename B::element_type T;
00377     T det;
00378     vector<typename B::size_type, false> basis;
00379     rref_field(a, b, q, basis, det, factory<T>(), ctrl::rref_field_idler());
00380 }
00381 
00382 
00384 template <typename A, typename B>
00385 inline void rref_field (const A& a, B& b)
00386 {
00387     typedef typename B::element_type T;
00388     T det;
00389     vector<typename B::size_type, false> basis;
00390     B q;
00391     rref_field(a, b, q, basis, det, factory<T>(), ctrl::rref_field_idler());
00392 }
00393 
00394 
00396 template <typename A>
00397 inline A rref_field (const A& a)
00398 {
00399     typedef typename A::element_type T;
00400     T det;
00401     vector<typename A::size_type> basis;
00402     A b, q;
00403     rref_field(a, b, q, basis, det, factory<T>(), ctrl::rref_field_idler());
00404     return b;
00405 }
00406 
00407 
00408 // ----------------------------------------
00409 
00411 template <typename A1, typename A2, typename I>
00412 void mat_col_copy_order
00413 (const A1& a1, A2& a2, const I& idx);
00414 
00416 template <typename A1, typename A2, typename I>
00417 void vec_copy_order
00418 (const A1& a1, A2& a2, const I& idx);
00419 
00420 
00422 template <typename A, typename B>
00423 void vec_inverse_permutation (const A& a, B& b);
00424 
00425 
00427 
00430 // TODO Make this function with an algorithm controller.
00431 template
00432 <
00433     typename A, typename B, typename Q,
00434     typename Basis_in, typename Basis_out,
00435     typename Det
00436 >
00437 void rref_order
00438 (
00439     const A& a, B& b, Q& q,
00440     const Basis_in& basis_in, Basis_out& basis_out,
00441     Det& det
00442 );
00443 
00444 
00446 
00450 template <typename T, bool REFCNT>
00451 matrix<T, REFCNT> inverse (const matrix<T, REFCNT>& A);
00452 
00453 
00455 
00459 template <typename T, bool REFCNT>
00460 T det (const matrix<T, REFCNT>& A);
00461 
00462 
00464 template <typename T, bool REFCNT>
00465 typename matrix<T, REFCNT>::size_type rank
00466 (const matrix<T, REFCNT>& A);
00467 
00468 
00469 
00471 
00481 template
00482 <
00483     typename A, typename B, typename Q, typename Basis,
00484     typename T, typename T_factory,
00485     typename Ctrler // control visitor
00486 >
00487 void rref_gauss_bareiss
00488 (
00489     const A& a, B& b, Q& q, Basis& basis,
00490     T& det,
00491     const T_factory& tfctr,
00492     Ctrler ctrler
00493 );
00494 
00495 
00497 template
00498 <
00499     typename A, typename B, typename Q, typename Basis, typename T,
00500     typename Ctrler // control visitor
00501 >
00502 inline void rref_gauss_bareiss
00503 (const A& a, B& b, Q& q, Basis& basis, T& det, Ctrler ctrler)
00504 { rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrler); }
00505 
00506 
00508 template <typename A, typename B, typename Q, typename Basis, typename T>
00509 inline void rref_gauss_bareiss (const A& a, B& b, Q& q, Basis& basis, T& det)
00510 { rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_bareiss_idler()); }
00511 
00512 
00514 template <typename A, typename B, typename Q, typename Basis>
00515 inline void rref_gauss_bareiss (const A& a, B& b, Q& q, Basis& basis)
00516 {
00517     typedef typename B::element_type T;
00518     T det;
00519     rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_bareiss_idler());
00520 }
00521 
00522 
00524 template <typename A, typename B, typename Q>
00525 inline void rref_gauss_bareiss (const A& a, B& b, Q& q)
00526 {
00527     typedef typename B::element_type T;
00528     T det;
00529     vector<typename B::size_type, false> basis;
00530     rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_bareiss_idler());
00531 }
00532 
00533 
00535 template <typename A, typename B>
00536 inline void rref_gauss_bareiss (const A& a, B& b)
00537 {
00538     typedef typename B::element_type T;
00539     T det;
00540     vector<typename B::size_type, false> basis;
00541     B q;
00542     rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_bareiss_idler());
00543 }
00544 
00545 
00547 template <typename A>
00548 inline A rref_gauss_bareiss (const A& a)
00549 {
00550     typedef typename A::element_type T;
00551     T det;
00552     vector<typename A::size_type, false> basis;
00553     A b, q;
00554     rref_gauss_bareiss(a, b, q, basis, det, factory<T>(), ctrl::rref_gauss_bareiss_idler());
00555     return b;
00556 }
00557 
00558 
00559 // ----------------------------------------
00560 
00562 
00563 template
00564 <
00565     typename A, typename B, typename Q, typename Basis,
00566     typename T, typename T_factory,
00567     typename Ctrler // control visitor
00568 >
00569 inline void rref_int
00570 (
00571     const A& a, B& b, Q& q, Basis& basis,
00572     T& det,
00573     const T_factory& tfctr,
00574     Ctrler ctrler
00575 )
00576 { rref_gauss_bareiss(a, b, q, basis, det, tfctr, ctrler.ctrl_rref_gauss_bareiss()); }
00577 
00578 
00580 template
00581 <
00582     typename A, typename B, typename Q, typename Basis, typename T,
00583     typename Ctrler // control visitor
00584 >
00585 inline void rref_int
00586 (const A& a, B& b, Q& q, Basis& basis, T& det, Ctrler ctrler)
00587 { rref_int(a, b, q, basis, det, factory<T>(), ctrler); }
00588 
00589 
00591 template <typename A, typename B, typename Q, typename Basis, typename T>
00592 inline void rref_int (const A& a, B& b, Q& q, Basis& basis, T& det)
00593 { rref_int(a, b, q, basis, det, factory<T>(), ctrl::rref_int_idler()); }
00594 
00595 
00597 template <typename A, typename B, typename Q, typename Basis>
00598 inline void rref_int (const A& a, B& b, Q& q, Basis& basis)
00599 {
00600     typedef typename B::element_type T;
00601     T det;
00602     rref_int(a, b, q, basis, det, factory<T>(), ctrl::rref_int_idler());
00603 }
00604 
00605 
00607 template <typename A, typename B, typename Q>
00608 inline void rref_int (const A& a, B& b, Q& q)
00609 {
00610     typedef typename B::element_type T;
00611     T det;
00612     vector<typename B::size_type, false> basis;
00613     rref_int(a, b, q, basis, det, factory<T>(), ctrl::rref_int_idler());
00614 }
00615 
00616 
00618 template <typename A, typename B>
00619 inline void rref_int (const A& a, B& b)
00620 {
00621     typedef typename B::element_type T;
00622     T det;
00623     vector<typename B::size_type, false> basis;
00624     B q;
00625     rref_int(a, b, q, basis, det, factory<T>(), ctrl::rref_int_idler());
00626 }
00627 
00628 
00630 template <typename A>
00631 inline A rref_int (const A& a)
00632 {
00633     typedef typename A::element_type T;
00634     T det;
00635     vector<typename A::size_type, false> basis;
00636     A b, q;
00637     rref_int(a, b, q, basis, det, factory<T>(), ctrl::rref_int_idler());
00638     return b;
00639 }
00640 
00641 
00642 // ----------------------------------------
00643 
00644 namespace _Internal
00645 {
00646 
00647 template
00648 <
00649     typename A, typename B, typename Q, typename Basis,
00650     typename T, typename T_factory,
00651     typename Ctrler // control visitor
00652 >
00653 inline void rref_helper_1
00654 (
00655     const A& a, B& b, Q& q, Basis& basis,
00656     T& det,
00657     const T_factory& tfctr,
00658     Ctrler ctrler,
00659     const true_type&
00660 )
00661 { rref_field(a, b, q, basis, det, tfctr, ctrler.ctrl_rref_field()); }
00662 
00663 
00664 template
00665 <
00666     typename A, typename B, typename Q, typename Basis,
00667     typename T, typename T_factory,
00668     typename Ctrler // control visitor
00669 >
00670 inline void rref_helper_1
00671 (
00672     const A& a, B& b, Q& q, Basis& basis,
00673     T& det,
00674     const T_factory& tfctr,
00675     Ctrler ctrler,
00676     const false_type&
00677 )
00678 { rref_int(a, b, q, basis, det, tfctr, ctrler.ctrl_rref_int()); }
00679 
00680 
00681 }
00682 
00683 
00685 
00687 template
00688 <
00689     typename A, typename B, typename Q, typename Basis,
00690     typename T, typename T_factory,
00691     typename Ctrler // control visitor
00692 >
00693 inline void rref
00694 (
00695     const A& a, B& b, Q& q, Basis& basis,
00696     T& det,
00697     const T_factory& tfctr,
00698     Ctrler ctrler
00699 )
00700 {
00701     _Internal::rref_helper_1
00702     (
00703         a, b, q, basis, det, tfctr, ctrler,
00704         bool_type<type_traits<typename B::element_type>::is_field>::value
00705     );
00706 }
00707 
00708 
00710 template
00711 <
00712     typename A, typename B, typename Q, typename Basis, typename T,
00713     typename Ctrler // control visitor
00714 >
00715 inline void rref
00716 (const A& a, B& b, Q& q, Basis& basis, T& det, Ctrler ctrler)
00717 { rref(a, b, q, basis, det, factory<T>(), ctrler); }
00718 
00719 
00721 template <typename A, typename B, typename Q, typename Basis, typename T>
00722 inline void rref (const A& a, B& b, Q& q, Basis& basis, T& det)
00723 { rref(a, b, q, basis, det, factory<T>(), ctrl::rref_idler()); }
00724 
00725 
00727 template <typename A, typename B, typename Q, typename Basis>
00728 void rref (const A& a, B& b, Q& q, Basis& basis)
00729 {
00730     typedef typename B::element_type T;
00731     T det;
00732     rref(a, b, q, basis, det, factory<T>(), ctrl::rref_idler());
00733 }
00734 
00735 
00737 template <typename A, typename B, typename Q>
00738 inline void rref (const A& a, B& b, Q& q)
00739 {
00740     typedef typename B::element_type T;
00741     T det;
00742     vector<typename B::size_type, false> basis;
00743     rref(a, b, q, basis, det, factory<T>(), ctrl::rref_idler());
00744 }
00745 
00746 
00748 template <typename A, typename B>
00749 inline void rref (const A& a, B& b)
00750 {
00751     typedef typename B::element_type T;
00752     T det;
00753     vector<typename B::size_type, false> basis;
00754     B q;
00755     rref(a, b, q, basis, det, factory<T>(), ctrl::rref_idler());
00756 }
00757 
00758 
00760 template <typename A>
00761 inline A rref (const A& a)
00762 {
00763     typedef typename A::element_type T;
00764     T det;
00765     vector<typename A::size_type, false> basis;
00766     A b, q;
00767     rref(a, b, q, basis, det, factory<T>(), ctrl::rref_idler());
00768     return b;
00769 }
00770 
00771 
00772 // ----------------------------------------
00773 
00775 template <typename T, bool REFCNT>
00776 T det_int (const matrix<T, REFCNT>& A);
00777 
00778 
00780 template <typename T, bool REFCNT>
00781 typename matrix<T, REFCNT>::size_type rank_int
00782 (const matrix<T, REFCNT>& A);
00783 
00784 
00785 // The following solve_linsys function have migrated to solve_linsys.{hpp, cpp} files.
00787 //template
00788 //<
00789 //  typename T_A, bool REFCNT_A,
00790 //  typename T_B, bool REFCNT_B,
00791 //  typename T_res, bool REFCNT_res
00792 //>
00793 //inline void solve_linsys
00794 //(
00795 //  const matrix<T_A, REFCNT_A>& A,
00796 //  const vector<T_B, REFCNT_B>& B,
00797 //  vector<T_res, REFCNT_res>& res
00798 //)
00799 //{
00800 //  // WARNING! Slow implementation.
00801 //  res = inverse(A)*B;
00802 //}
00803 //
00804 //
00806 //template
00807 //<
00808 //  typename T_A, bool REFCNT_A,
00809 //  typename T_B, bool REFCNT_B
00810 //>
00811 //inline vector<T_B, REFCNT_B> solve_linsys
00812 //(
00813 //  const matrix<T_A, REFCNT_A>& A,
00814 //  const vector<T_B, REFCNT_B>& B
00815 //)
00816 //{
00817 //  vector<T_B, REFCNT_B> res(B.size());
00818 //  solve_linsys(A, B, res);
00819 //  return res;
00820 //}
00821 
00822 
00823 }
00824 
00825 
00826 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00827     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_GAUSS
00828     #include "gauss.cpp"
00829     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_GAUSS
00830 #endif
00831 
00832 
00833 #endif

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