00001
00002
00003
00004
00005
00006
00007
00008
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
00088
00089
00090 typedef typename SRChain::difference_type index;
00091 typedef typename SRChain::element_type P;
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();
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
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
00143
00144
00145 vector<P1, false> s;
00146 subresultants_nonmodular(p1, p2, s, fctr);
00147
00148 ARAGELI_ASSERT_2(s[0].degree() <= 0);
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
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) || ...