algebrslt.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     algebrslt.cpp -- See declarations in algebrslt.hpp.
00004 
00005     This file is a part of the Arageli library.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005--2006
00009 
00010 *****************************************************************************/
00011 
00018 #include "config.hpp"
00019 
00020 #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || \
00021     defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_algebrslt)
00022 
00023 #include "exception.hpp"
00024 #include "cmp.hpp"
00025 #include "vector.hpp"
00026 #include "sparse_polynom.hpp"
00027 #include "polyalg.hpp"
00028 #include "sturm.hpp"
00029 #include "resultant.hpp"
00030 
00031 #include "algebrslt.hpp"
00032 
00033 
00034 namespace Arageli
00035 {
00036 
00037 
00038 template
00039 <
00040     typename PolyVec,
00041     typename SegVec,
00042     typename Rslt,
00043     typename P,
00044     typename Seg,
00045     typename F
00046 >
00047 void algebraic_func_rslt
00048 (
00049     const PolyVec& polyvec, // source polynomials
00050     SegVec segvec, // source segments
00051     Rslt rslt, // source resultant
00052     P& p, Seg& seg, // the result: polynomial and segment where root is located
00053     F f // the function that is performing on the source algebraic numbers
00054 )
00055 {
00056     // Implementation of this function is based on Loos, 1973. Source: Buhberger
00057 
00058     ARAGELI_ASSERT_0(polyvec.size() == segvec.size());
00059 
00060     //std::cout << "\n++++++++++ algebraic_func_rslt +++++++++++++\n";
00061 
00062     //typedef vector<Rslt, false> Rslt_factors;
00063     //typedef Rslt_factors::size_type size_type;
00064 
00065     //std::cout << "\nrslt = " << rslt;
00066 
00067     // Make squre-free resultant.   // WARNING! Is it needed? See strurm specification.
00068     Rslt gcd_rslt_df = gcd(rslt, diff(rslt));
00069     gcd_rslt_df /= gcd_rslt_df.leading_coef_cpy();  // WARNING! Is it needed?
00070     rslt /= gcd_rslt_df;
00071 
00072     //std::cout << "\nsf rslt = " << rslt;
00073 
00074     rslt = polynom_primpart(rslt);
00075 
00076     //std::cout << "\nprimpart rslt = " << rslt;
00077 
00078     vector<Rslt, false> ss;
00079     sturm_diff_sys(rslt, ss);
00080     typedef typename vector<Rslt, false>::size_type size_type;
00081 
00082     //output_aligned(std::cout << "\nrslt Sturm system =\n", ss);
00083 
00084     for(;;)
00085     {
00086         seg = f(segvec);
00087 
00088         //output_aligned(std::cout << "\nsegvec =\n", segvec);
00089         //std::cout << "seg = " << seg;
00090 
00091         size_type snr = sturm_number_roots(ss, seg);
00092 
00093         if(snr == 0)
00094             throw invalid_argument
00095             (/*
00096                 "The operation cannot be performed on the specified "
00097                 "arguments in algebraic number field"
00098             */);
00099         else if(snr == 1)   // Congratulations! The interval is found.
00100             break;
00101         else    // Make intervals more precise.
00102             for(size_type i = 0; i < polyvec.size(); ++i)
00103                 if(!segvec[i].is_negligible())
00104                     interval_root_dichotomy
00105                     (
00106                         polyvec[i],
00107                         sign(polyvec[i].subs(segvec[i].first())),
00108                         segvec[i]
00109                     );
00110     }
00111 
00112     p = rslt;
00113 
00114     //std::cout << "\np = " << p;
00115 
00116     //std::cout << "\nprimpart p = " << p;
00117     //std::cout << "\n++++++++ END algebraic_func_rslt +++++++++++\n";
00118 }
00119 
00120 
00121 namespace _Internal
00122 {
00123 
00124 template <typename T>
00125 struct vector_2_plus_algebraic_helper
00126 {
00127     typename T::value_type operator() (const T& x) const
00128     {
00129         ARAGELI_ASSERT_0(x.size() == 2);
00130         return x.front() + x.back();
00131     }
00132 };
00133 
00134 
00135 template <typename T>
00136 struct vector_2_minus_algebraic_helper
00137 {
00138     typename T::value_type operator() (const T& x) const
00139     {
00140         ARAGELI_ASSERT_0(x.size() == 2);
00141         return x.front() - x.back();
00142     }
00143 };
00144 
00145 
00146 template <typename T>
00147 struct vector_2_multiplies_algebraic_helper
00148 {
00149     typename T::value_type operator() (const T& x) const
00150     {
00151         ARAGELI_ASSERT_0(x.size() == 2);
00152         return x.front() * x.back();
00153     }
00154 };
00155 
00156 
00157 template <typename T>
00158 struct vector_2_divides_algebraic_helper
00159 {
00160     typename T::value_type operator() (const T& x) const
00161     {
00162         ARAGELI_ASSERT_0(x.size() == 2);
00163         return x.front() / x.back();
00164     }
00165 };
00166 
00167 
00168 } // namespace _Internal
00169 
00170 
00171 template
00172 <
00173     typename P1, typename Seg1,
00174     typename P2, typename Seg2,
00175     typename P3, typename Seg3
00176 >
00177 void algebraic_plus
00178 (
00179     const P1& p1, const Seg1& seg1,
00180     const P2& p2, const Seg2& seg2,
00181     P3& p3, Seg3& seg3
00182 )
00183 {
00184     typedef sparse_polynom<P1> Pxy;
00185     typedef vector<P1, false> Polyvec;
00186     typedef vector<Seg1, false> Segvec;
00187 
00188     //std::cout << "\np1 = " << p1 << "\nseg1 = " << seg1;
00189     //std::cout << "\np2 = " << p2 << "\nseg2 = " << seg2;
00190 
00191     Polyvec polyvec;
00192     polyvec.push_back(p1);
00193     polyvec.push_back(p2);
00194     
00195     Segvec segvec;
00196     segvec.push_back(seg1);
00197     segvec.push_back(seg2);
00198     
00199     P1 rslt = resultant(p1.subs(Pxy("((x)-x)")), p2);
00200 
00201     algebraic_func_rslt
00202     (
00203         polyvec, segvec, rslt, p3, seg3,
00204         _Internal::vector_2_plus_algebraic_helper<Segvec>()
00205     );
00206 }
00207 
00208 
00209 // WARNING! TEMPORARY.
00210 template
00211 <
00212     typename P1, typename Seg1,
00213     typename P2, typename Seg2,
00214     typename P3, typename Seg3
00215 >
00216 void algebraic_minus
00217 (
00218     const P1& p1, const Seg1& seg1,
00219     const P2& p2, const Seg2& seg2,
00220     P3& p3, Seg3& seg3
00221 )
00222 {
00223     typedef sparse_polynom<P1> Pxy;
00224     typedef vector<P1, false> Polyvec;
00225     typedef vector<Seg1, false> Segvec;
00226 
00227     //std::cout << "\np1 = " << p1 << "\nseg1 = " << seg1;
00228     //std::cout << "\np2 = " << p2 << "\nseg2 = " << seg2;
00229 
00230     Polyvec polyvec;
00231     polyvec.push_back(p1);
00232     polyvec.push_back(p2);
00233     
00234     Segvec segvec;
00235     segvec.push_back(seg1);
00236     segvec.push_back(seg2);
00237     
00238     P1 rslt = resultant(p1.subs(Pxy("((x)+x)")), p2);
00239 
00240     algebraic_func_rslt
00241     (
00242         polyvec, segvec, rslt, p3, seg3,
00243         _Internal::vector_2_minus_algebraic_helper<Segvec>()
00244     );
00245 }
00246 
00247 
00248 // WARNING! TEMPORARY.
00249 template
00250 <
00251     typename P1, typename Seg1,
00252     typename P2, typename Seg2,
00253     typename P3, typename Seg3
00254 >
00255 void algebraic_multiplies
00256 (
00257     const P1& p1, const Seg1& seg1,
00258     const P2& p2, const Seg2& seg2,
00259     P3& p3, Seg3& seg3
00260 )
00261 {
00262     typedef sparse_polynom<P1> Pxy;
00263     typedef vector<P1, false> Polyvec;
00264     typedef vector<Seg1, false> Segvec;
00265 
00266     //std::cout << "\np1 = " << p1 << "\nseg1 = " << seg1;
00267     //std::cout << "\np2 = " << p2 << "\nseg2 = " << seg2;
00268 
00269     Polyvec polyvec;
00270     polyvec.push_back(p1);
00271     polyvec.push_back(p2);
00272     
00273     Segvec segvec;
00274     segvec.push_back(seg1);
00275     segvec.push_back(seg2);
00276     
00277     Pxy p1n = reciprocal_poly(p1).subs(Pxy("x"));
00278     typedef typename P1::monom monom;
00279     for(typename Pxy::monom_iterator i = p1n.monoms_begin(); i != p1n.monoms_end(); ++i)
00280         i->coef() *= monom(unit<typename monom::coef_type>(), p1n.degree() - i->degree());
00281     //std::cout << "\np1n = " << p1n;
00282     
00283     P1 rslt = resultant(p1n, p2);
00284 
00285     algebraic_func_rslt
00286     (
00287         polyvec, segvec, rslt, p3, seg3,
00288         _Internal::vector_2_multiplies_algebraic_helper<Segvec>()
00289     );
00290 }
00291 
00292 
00293 // WARNING! TEMPORARY.
00294 template
00295 <
00296     typename P1, typename Seg1,
00297     typename P2, typename Seg2,
00298     typename P3, typename Seg3
00299 >
00300 void algebraic_divides
00301 (
00302     const P1& p1, const Seg1& seg1,
00303     const P2& p2, Seg2 seg2,
00304     P3& p3, Seg3& seg3
00305 )
00306 {
00307     typedef sparse_polynom<P1> Pxy;
00308     typedef vector<P1, false> Polyvec;
00309     typedef vector<Seg1, false> Segvec;
00310 
00311     //std::cout << "\np1 = " << p1 << "\nseg1 = " << seg1;
00312     //std::cout << "\np2 = " << p2 << "\nseg2 = " << seg2;
00313 
00314     Polyvec polyvec;
00315     polyvec.push_back(p1);
00316     polyvec.push_back(p2);
00317 
00318     if(sign(seg2.first())*sign(seg2.second()) <= 0)
00319     {
00320         ARAGELI_ASSERT_0(!is_null(p2.subs(null<typename Seg2::value_type>())));
00321         int lsign = sign(p2.subs(seg2.first()));
00322         
00323         do
00324         {
00325             interval_root_dichotomy(p2, lsign, seg2);
00326         }while(sign(seg2.first())*sign(seg2.second()) <= 0);
00327     }
00328     
00329     Segvec segvec;
00330     segvec.push_back(seg1);
00331     segvec.push_back(seg2);
00332     
00333     P1 rslt = resultant(p1.subs(Pxy("((x)*x)")), p2);
00334 
00335     algebraic_func_rslt
00336     (
00337         polyvec, segvec, rslt, p3, seg3,
00338         _Internal::vector_2_divides_algebraic_helper<Segvec>()
00339     );
00340 }
00341 
00342 
00343 
00344 }
00345 
00346 
00347 #endif  // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...

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