00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 }
00236
00237
00239
00248 template
00249 <
00250 typename A, typename B, typename Q, typename Basis,
00251 typename T, typename T_factory,
00252 typename Ctrler
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
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
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
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
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
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
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
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
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
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
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
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
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
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
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