sparse_polynom.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     sparse_polynom.hpp
00004 
00005     This file is a part of Arageli library.
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 
00023 #ifndef _ARAGELI_sparse_polynom_hpp_
00024 #define _ARAGELI_sparse_polynom_hpp_
00025 
00026 #include "config.hpp"
00027 
00028 #include <iostream>
00029 #include <list>
00030 #include <iomanip>
00031 #include <algorithm>
00032 #include <cmath>
00033 
00034 #include "frwrddecl.hpp"
00035 
00036 #include "type_traits.hpp"
00037 #include "config.hpp"
00038 #include "exception.hpp"
00039 #include "refcntr.hpp"
00040 #include "iteradapt.hpp"
00041 #include "type_opers.hpp"
00042 #include "factory.hpp"
00043 #include "cmp.hpp"
00044 #include "io.hpp"
00045 #include "powerest.hpp"
00046 #include "big_int.hpp"
00047 #include "rational.hpp"
00048 #include "_utility.hpp"
00049 
00050 #include "std_import.hpp"
00051 
00052 //****************************************************************************
00053 
00054 namespace Arageli
00055 {
00056 
00057 template <typename T> class rational;
00058 
00059 
00061 
00065 template
00066 <
00067     typename F,
00068     typename I
00069 >
00070 class monom
00071 {
00072     template <typename F1, typename I1>
00073     friend class monom;
00074 
00075 public:
00076 
00077     typedef F coef_type;    
00078     typedef I degree_type;  
00079 
00081 
00082     monom () : coef_m(factory<coef_type>::null()), degree_m(factory<degree_type>::null()) {}
00083 
00085 
00087     monom (const F& c) : coef_m(c), degree_m(factory<degree_type>::null()) {}
00088 
00090 
00092     monom (const F& c, const I& d) : coef_m(c), degree_m(d) {}
00093 
00095     template <typename F1, typename I1>
00096     monom (const monom<F1, I1>& x)
00097     : coef_m(x.coef_m), degree_m(x.degree_m) {}
00098 
00100 
00101     monom (const char* s);
00102 
00103     template <typename F1, typename I1>
00104     monom& operator= (const monom<F1, I1>& x)
00105     {
00106         coef_m = x.coef_m; degree_m = x.degree_m;
00107         return *this;
00108     }
00109 
00110     monom& operator= (const char* s)
00111     { return *this = monom(s); }
00112 
00114 
00115     bool is_const () const { return Arageli::is_null(degree_m); }
00116 
00118 
00120     bool is_null () const { return Arageli::is_null(coef_m); }
00121 
00123 
00125     bool is_unit () const
00126     { return Arageli::is_unit(coef_m) && Arageli::is_null(degree_m); }
00127 
00129 
00131     bool is_opposite_unit () const
00132     {
00133         return Arageli::is_opposite_unit(coef_m) &&
00134             Arageli::is_null(degree_m);
00135     }
00136 
00137     
00139 
00140     bool is_x () const
00141     { return Arageli::is_unit(coef_m) && Arageli::is_unit(degree_m); }
00142 
00144     const coef_type& coef () const { return coef_m; }
00145     
00147     coef_type& coef () { return coef_m; }
00148     
00150     const degree_type& degree () const { return degree_m; }
00151     
00153     degree_type& degree () { return degree_m; }
00154 
00156 
00158     template <typename F1, typename I1>
00159     bool can_add (const monom<F1, I1>& x) const
00160     { return degree_m == x.degree_m; }
00161 
00163     monom& opposite ()
00164     {
00165         Arageli::opposite(&coef_m);
00166         return *this;
00167     }
00168     
00170     monom operator- () const
00171     { return monom(Arageli::opposite(coef_m), degree_m); }
00172     
00174     const monom& operator+ () const { return *this; }
00175 
00176     monom& operator++ ()
00177     {
00178         ARAGELI_ASSERT_0(is_const());
00179         ++coef_m;
00180         return *this;
00181     }
00182 
00183     monom operator++ (int) { monom t = *this; operator++(); return t; }
00184 
00185     monom& operator-- ()
00186     {
00187         ARAGELI_ASSERT_0(is_const());
00188         --coef_m;
00189         return *this;
00190     }
00191 
00192     monom operator-- (int) { monom t = *this; operator--(); return t; }
00193 
00195 
00197     template <typename F1>
00198     monom& operator+= (const F1& x)
00199     {
00200         ARAGELI_ASSERT_0(is_const());
00201         coef_m += x;
00202         return *this;
00203     }
00204     
00206 
00209     template <typename F1>
00210     monom& operator-= (const F1& x)
00211     {
00212         ARAGELI_ASSERT_0(is_const());
00213         coef_m -= x;
00214         return *this;
00215     }
00216     
00218 
00220     template <typename F1>
00221     monom& operator*= (const F1& x)
00222     {
00223         coef_m *= x;
00224         return *this;
00225     }
00226     
00228 
00231     template <typename F1>
00232     monom& operator/= (const F1& x)
00233     {
00234         ARAGELI_ASSERT_0(!Arageli::is_null(x));
00235         coef_m /= x;
00236         return *this;
00237     }
00238     
00240 
00243     template <typename F1>
00244     monom& operator%= (const F1& x)
00245     {
00246         ARAGELI_ASSERT_0(!Arageli::is_null(x));
00247         coef_m %= x;
00248         return *this;
00249     }
00250     
00252 
00254     template <typename F1, typename I1>
00255     monom& operator+= (const monom<F1, I1>& x)
00256     {
00257         ARAGELI_ASSERT_0(can_add(x));
00258         coef_m += x.coef_m;
00259         return *this;
00260     }
00261     
00263 
00266     template <typename F1, typename I1>
00267     monom& operator-= (const monom<F1, I1>& x)
00268     {
00269         ARAGELI_ASSERT_0(can_add(x));
00270         coef_m -= x.coef_m;
00271         return *this;
00272     }
00273 
00275 
00277     template <typename F1, typename I1>
00278     monom& operator*= (const monom<F1, I1>& x)
00279     {
00280         coef_m *= x.coef_m;
00281         degree_m += x.degree_m;
00282         return *this;
00283     }
00284     
00286 
00288     template <typename F1, typename I1>
00289     monom& operator/= (const monom<F1, I1>& x)
00290     {
00291         ARAGELI_ASSERT_0(!Arageli::is_null(x.coef_m));
00292         
00293         if(degree_m >= x.degree_m)
00294         {
00295             coef_m /= x.coef_m;
00296             degree_m -= x.degree_m;
00297         }
00298         else
00299         {
00300             coef_m = factory<coef_type>::null();
00301             degree_m = null<degree_type>();
00302         }
00303         
00304         return *this;
00305     }
00306     
00308 
00311     template <typename F1, typename I1>
00312     monom& operator%= (const monom<F1, I1>& x)
00313     {
00314         ARAGELI_ASSERT_0(!Arageli::is_null(x.coef_m));
00315         if(degree_m >= x.degree_m)coef_m %= x.coef_m;
00316         return *this;
00317     }
00318 
00320     template <typename F1, typename I1>
00321     void swap (monom<F1, I1>& x)
00322     {
00323         std::swap(coef_m, x.coef_m);
00324         std::swap(degree_m, x.degree_m);
00325     }
00326 
00327 private:
00328 
00329     coef_type coef_m;
00330     degree_type degree_m;
00331 
00332 };
00333 
00334 
00335 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00336 
00337 
00338 template <typename F, typename I>
00339 struct type_traits<monom<F, I> >
00340     : public type_traits_default<monom<F, I> >
00341 {
00342     static const bool is_specialized =
00343                         type_traits<F>::is_specialized &&
00344                         type_traits<I>::is_specialized;
00345 
00346     static const bool is_integer_number = false;
00347     static const bool is_polynom = false;
00348     static const bool is_real_number = false;
00349     static const bool is_rational_number = false;
00350     static const bool is_complex_number = false;
00351     static const bool is_ring = false;
00352     static const bool is_field = false;
00353     
00354     static const bool is_finite =
00355                         type_traits<F>::is_finite &&
00356                         type_traits<I>::is_finite;
00357     
00358     static const bool is_additive_group = type_traits<F>::is_ring;
00359     static const bool is_multiplicative_group = false;
00360 
00361     static const bool has_zero_divisor =
00362                         type_traits<F>::has_zero_divisor &&
00363                         type_traits<I>::has_null;
00364 
00365     static const bool is_integer_modulo_ring = false;
00366     static const bool is_matrix = false;
00367     static const bool is_vector = false;
00368 
00369     static const bool has_commutative_multiplication =
00370                         type_traits<F>::has_commutative_multiplication &&
00371                         type_traits<I>::has_commutative_addition;
00372 
00373     static const bool has_commutative_addition =
00374                         type_traits<F>::has_commutative_addition;
00375     
00376     static const bool has_null =
00377                         type_traits<F>::has_null &&
00378                         type_traits<I>::has_null;
00379 
00380     static const bool has_unit =
00381                         type_traits<F>::has_unit &&
00382                         type_traits<I>::has_null;
00383 
00384     static const bool has_opposite_unit =
00385                         type_traits<F>::has_opposite_unit &&
00386                         type_traits<I>::has_null;
00387     
00389     static const bool is_aggregate = true;
00390     
00392     typedef F element_type;
00393 
00394 };
00395 
00396 
00397 
00398 
00399 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00400 
00401 template <typename F, typename I>
00402 struct factory<monom<F, I> >
00403 {
00404     static const bool is_specialized = true;
00405 
00406     static const monom<F, I>& unit ()
00407     {
00408         static const monom<F, I> unit_s(Arageli::unit<F>());
00409         return unit_s;
00410     }
00411 
00412     static monom<F, I> unit (const monom<F, I>& x)
00413     { return monom<F, I>(Arageli::unit(x.coef())); }
00414 
00415     static const monom<F, I>& opposite_unit ()
00416     {
00417         static const monom<F, I> opposite_unit_s(Arageli::opposite_unit<F>());  
00418         return opposite_unit_s;
00419     }
00420 
00421     static monom<F, I> opposite_unit (const monom<F, I>& x)
00422     { return monom<F, I>(opposite_unit(x.coef())); }
00423 
00424     static const monom<F, I>& null ()
00425     {
00426         static const monom<F, I> null_s(Arageli::null<F>());
00427         return null_s;
00428     }
00429 
00430     static monom<F, I> null (const monom<F, I>& x)
00431     { return monom<F, I>(Arageli::null(x.coef())); }
00432 
00433 };
00434 
00435 
00436 template <typename F, typename I>
00437 inline bool is_unit (const monom<F, I>& x)
00438 { return x.is_unit(); }
00439 
00440 template <typename F, typename I>
00441 inline bool is_opposite_unit (const monom<F, I>& x)
00442 { return x.is_opposite_unit(); }
00443 
00444 template <typename F, typename I>
00445 inline bool is_null (const monom<F, I>& x)
00446 { return x.is_null(); }
00447 
00448 template <typename F, typename I>
00449 inline monom<F, I> opposite (const monom<F, I>& x)
00450 { return -x; }
00451 
00452 template <typename F, typename I>
00453 inline monom<F, I>& opposite (const monom<F, I>& x, monom<F, I>* y)
00454 { return (*y = x).opposite(); }
00455 
00456 template <typename F, typename I>
00457 inline monom<F, I>& opposite (monom<F, I>* x)
00458 { return x->opposite(); }
00459 
00460 template <typename F, typename I>
00461 inline monom<F, I> inverse (const monom<F, I>& x)
00462 {
00463     ARAGELI_ASSERT_0(x.is_const());
00464     return inverse(x.coef());
00465 }
00466 
00467 template <typename F, typename I>
00468 inline monom<F, I>& inverse (const monom<F, I>& x, monom<F, I>* y)
00469 {
00470     ARAGELI_ASSERT_0(x.is_const());
00471     inverse(x.coef(), &y->coef());
00472     y->degree() = x.degree();
00473     return *y;
00474 }
00475 
00476 template <typename F, typename I>
00477 inline monom<F, I>& inverse (monom<F, I>* x)
00478 {
00479     ARAGELI_ASSERT_0(x.is_const());
00480     inverse(&x->coef());
00481     return *x;
00482 }
00483 
00484 template <typename F, typename I>
00485 inline std::ostream& output_polynom_first (std::ostream& out, const monom<F, I>& x)
00486 { return out << '(' << x << ')'; }
00487 
00488 template <typename F, typename I>
00489 inline std::ostream& output_polynom_internal
00490 (std::ostream& out, const monom<F, I>& x)
00491 { return out << "+(" << x << ')'; }
00492 
00493 template <typename F, typename I>
00494 inline std::ostream& output_pow (std::ostream& out, const monom<F, I>& x)
00495 { return out << '(' << x << ')'; }
00496 
00497 template <typename F, typename I>
00498 std::istream& input_polynom_first (std::istream& in, monom<F, I>& x);
00499 
00500 template <typename F, typename I>
00501 std::istream& input_polynom_internal
00502 (std::istream& in, monom<F, I>& x);
00503 
00504 template <typename F, typename I>
00505 inline std::istream& input_pow (std::istream& in, monom<F, I>& x)
00506 { return input_polynom_first(in, x); }
00507 
00508 
00509 
00512 
00513 
00514 
00521 
00544 
00545 
00574 
00590 
00591 
00600 
00601 
00623 
00625 
00647 
00663 
00678 
00696 
00722 
00726 
00744 
00755 
00805 
00819 
00831 
00844 
00848 
00852 
00853 
00856 
00858 
00861 
00862 
00865 
00867 
00873 
00878 
00888 
00890 
00893 
00894 
00897 
00900 
00916 
00919 
00922 
00925 
00940 
00943 
00944 
00947 
00948 
00953 
00955 
00961 
00970 
00979 
00982 
00991 
00992 
00996 
01025 
01026 
01034 
01042 
01050 
01058 
01060 
01068 
01070 
01074 
01075 
01085 
01086 
01095 
01096 
01108 
01109 
01121 
01122 
01133 
01134 
01137 
01138 
01142 
01143 
01147 
01148 
01159 
01160 
01172 
01179 
01182 
01187 
01190 
01192 
01195 
01204 
01275 
01276 
01327 
01328 
01350 
01351 
01377 
01381 
01382 
01388 
01391 
01394 
01397 
01401 
01405 
01409 
01416 
01426 
01429 
01432 
01435 
01438 
01441 
01445 
01449 
01453 
01457 
01461 
01465 
01469 
01476 
01479 
01483 
01488 
01489 
01495 
01496 
01504 
01506 
01524 
01531 
01615 
01617 
01620 
01633 
01634 
01638 
01639 
01720 
01729 
01736 
01743 
01760 
01765 
01781 
01797 
01814 
01839 
01843 
01861 
01872 
01984 
01985 
01999 
02007 
02138 
02390 
02393 
02441 
02463 
02516 
02517 
02523 
02525 
02596 
02597 
02603 
02605 

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