resultant.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     resultant.cpp -- See declarations in resultant.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_resultant)
00022 
00023 #include "vector.hpp"
00024 
00025 #include "resultant.hpp"
00026 
00027 
00028 namespace Arageli
00029 {
00030 
00031 
00032 template <typename P1, typename P2, typename M>
00033 M& sylvester_fill (const P1& p1, const P2& p2, M& res)
00034 {
00035     typedef typename M::size_type size_type;
00036     typedef typename P1::monom_const_iterator P1I;
00037     typedef typename P2::monom_const_iterator P2I;
00038 
00039     size_type
00040         d1 = p1.degree(),
00041         d2 = p2.degree(),
00042         s = d1 + d2;
00043 
00044     res.resize(s, s);
00045 
00046     size_type i = 0;
00047     for(; i != d2; ++i)
00048     {
00049         size_type margin = i + d1;
00050         for
00051         (
00052             P1I p1i = p1.monoms_begin(), p1end = p1.monoms_end();
00053             p1i != p1end; ++p1i
00054         )
00055             res(i, margin - p1i->degree()) = p1i->coef();
00056     }
00057 
00058     for(; i != s; ++i)
00059         for
00060         (
00061             P2I p2i = p2.monoms_begin(), p2end = p2.monoms_end();
00062             p2i != p2end; ++p2i
00063         )
00064             res(i, i - p2i->degree()) = p2i->coef();
00065 
00066     return res;
00067 }
00068 
00069 
00070 template <typename P1, typename P2, typename M, typename MTFactory>
00071 M& sylvester (const P1& p1, const P2& p2, M& res, MTFactory fctr)
00072 {
00073     res.assign
00074     (
00075         p1.degree() + p2.degree(), p1.degree() + p2.degree(),
00076         res.is_empty() ? fctr.null() : fctr.null(res(0, 0))
00077     );
00078 
00079     return sylvester_fill(p1, p2, res);
00080 }
00081 
00082 
00083 template <typename P1, typename P2, typename SRChain, typename PCFactory>
00084 void subresultants_nonmodular
00085 (const P1& p1, const P2& p2, SRChain& s, PCFactory fctr)
00086 {
00087     // Source: Buhberger and others, p. 168, alg. 4.1
00088     // We have a problem with sign of the result subresultants.
00089     
00090     typedef typename SRChain::difference_type index;
00091     typedef typename SRChain::element_type P;   // maybe there is better chose
00092     typedef typename P::coef_type Coef;
00093     typedef typename P::degree_type Degree;
00094 
00095     typename P1::degree_type m = p1.degree();
00096     typename P2::degree_type n = p2.degree();
00097 
00098     index j;
00099     if(m > n)j = m-1;
00100     else j = n;
00101 
00102     s.resize(j+2);
00103 
00104     s[j+1] = p1;
00105     s[j] = p2;
00106 
00107     vector<Coef, false> rr(j+2);
00108 
00109     rr[j+1] = fctr.unit();
00110 
00111     for(;;)
00112     {
00113         P& sj = s[j];
00114         index r = sj.degree();  // P should return -1 when polynomial is null.
00115 
00116         for(index k = j-1; k >= r+1; --k)
00117             s[k] = null(s[k]);
00118 
00119         if(j > r && r >= 0)
00120             s[r] = (sj*pow(sj.leading_coef(), j-r)) / pow(rr[j+1], j-r);
00121 
00122         if(r <= 0)break;
00123 
00124         {
00125             P pq; Coef mult;
00126             polynom_pseudodivide_simple(s[j+1], sj, pq, s[r-1], mult);
00127         }
00128 
00129         s[r-1] /= pow(-rr[j+1], j-r+2);
00130         j = r-1;
00131         rr[j+1] = s[j+1].leading_coef();
00132     }
00133 
00134     //output_aligned(std::cout << "\nSub Resultants =\n", s);
00135 }
00136 
00137 
00138 template <typename P1, typename P2, typename PCFactory>
00139 typename P1::coef_type resultant_nonmodular
00140 (const P1& p1, const P2& p2, PCFactory fctr)
00141 {
00142     // WARNING! Need to choose from P1::coef_type and P2::coef_type
00143     // insted just P1::coef_type as a type of the return value.
00144 
00145     vector<P1, false> s;    // WARNING! Need to choose from P1 and P2 insted just P1.
00146     subresultants_nonmodular(p1, p2, s, fctr);
00147     
00148     ARAGELI_ASSERT_2(s[0].degree() <= 0);
00149 
00150     //ARAGELI_DEBUG_EXEC_2(if(!is_null(s[0])))
00151     //{
00152     //  ARAGELI_DEBUG_EXEC_2(typename P1::coef_type _dres = resultant_mod1(p1, p2, fctr));
00153     //  ARAGELI_ASSERT_2(!is_null(_dres));
00154     //  ARAGELI_ASSERT_2
00155     //  (
00156     //      s[0].leading_coef()/sign(s[0].leading_coef().leading_coef()) ==
00157     //      _dres/sign(_dres.leading_coef())
00158     //  );
00159     //}
00160     //ARAGELI_DEBUG_EXEC_2(else)
00161     //{
00162     //  ARAGELI_ASSERT_2(is_null(resultant_mod1(p1, p2, fctr)));
00163     //}
00164 
00165     return s[0].leading_coef_cpy();
00166 }
00167 
00168 
00169 }
00170 
00171 
00172 #endif  // #if !defined(ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE) || ...

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