Basic Polynomial Algebra Subprograms (BPAS)  v. 1.791
unumericalpolynomial.h
1 #ifndef _UNUMERICALPOLYNOMIAL
2 #define _UNUMERICALPOLYNOMIAL
3 #include <complex>
4 #include "../RingPolynomial/upolynomial.h"
5 #include "../ring.h"
6 #include "urationalfunction.h"
7 
8 /**
9  * A univariate polynomial with numerical coefficients represented sparsely.
10  * The template determines the type of the numerical coefficients.
11  */
12 template<class NumericalType>
14 {
15  private:
16  std::vector<NumericalType> coef;
17  std::vector<int> degs;
18 
19  template<class UnivariatePolynomialOverRealField>
20  NumericalType evaluateRealPolynomial(UnivariatePolynomialOverRealField& A, NumericalType& a) {
21  // need a check here that input is a real field
22  NumericalType out;
23  out = NumericalType(A.leadingCoefficient().get_d());
24  for (int i=A.degree().get_si()-1; i>-1; i--){
25  out *= a;
26  if (A.coefficient(i) != 0){
27  out += NumericalType(A.coefficient(i).get_d());
28  }
29  }
30  return out;
31  }
32  std::complex<double> evaluateComplexPolynomial(SparseUnivariatePolynomial<ComplexRationalNumber>& A, std::complex<double>& a) {
34  value = A.leadingCoefficient();
35  std::complex<double> out(value.realPart().get_d(),value.imaginaryPart().get_d());
36  for (int i=A.degree().get_si()-1; i>-1; i--){
37  out *= a;
38  if (!A.coefficient(i).isZero()){
39  value = A.coefficient(i);
40  out += std::complex<double>(value.realPart().get_d(),value.imaginaryPart().get_d());
41  }
42  }
43  return out;
44  }
45 
46  public:
48  // need a check here that input is a real field
49  NumericalType value(0);
50  for (int i=0; i<A.degree().get_si()+1; i++) {
51  value = A.coefficient(i).get_d();
52  if (!(value == 0.0)){
53  coef.push_back(value);
54  degs.push_back(i);
55  }
56  }
57  }
59  // need a check here that input is a real field
60  NumericalType value(0);
61  for (int i=0; i<A.degree().get_si()+1; i++) {
62  value = A.coefficient(i).get_d();
63  if (!(value == 0.0)){
64  coef.push_back(value);
65  degs.push_back(i);
66  }
67  }
68  }
69  // construct a SUNP by evaluating the coefficients of an SUP<DUQP> at a NumericalType
71  // need a check here that input is a real field
73  NumericalType value(0);
74  for (int i=0; i<A.degree().get_si()+1; i++) {
75  term = A.coefficient(i);
76  if (!term.isZero()){
77  value = evaluateRealPolynomial<DenseUnivariateRationalPolynomial>(term,a);
78  coef.push_back(value);
79  degs.push_back(i);
80  }
81  }
82  }
83  // construct a SUNP by evaluating the coefficients of an SUP<SUP<RN>> at a NumericalType
85  // need a check here that input is a real field
87  NumericalType value(0);
88  for (int i=0; i<A.degree().get_si()+1; i++) {
89  term = A.coefficient(i);
90  if (!term.isZero()){
91  value = evaluateRealPolynomial< SparseUnivariatePolynomial<RationalNumber> >(term,a);
92  coef.push_back(value);
93  degs.push_back(i);
94  }
95  }
96  }
98  NumericalType value(0);
100  for (int i=0; i<A.degree().get_si()+1; i++) {
101  cTemp = A.coefficient(i);
102  value = NumericalType(cTemp.realPart().get_d(),cTemp.imaginaryPart().get_d());
103  if (!(value == std::complex<double>(0))){
104  coef.push_back(value);
105  degs.push_back(i);
106  }
107  }
108  }
109  // construct a SUNP by evaluating the coefficients of an SUP<SUP<CRN>> at a complex<double>
112  NumericalType value(0);
113  for (int i=0; i<A.degree().get_si()+1; i++) {
114  term = A.coefficient(i);
115  if (!term.isZero()){
116  value = evaluateComplexPolynomial(term,a);
117  coef.push_back(value);
118  degs.push_back(i);
119  }
120  }
121  }
123  int degree() {
124  int out(degs.back());
125  return out;
126  }
127  NumericalType leadingCoefficient() {
128  NumericalType out(coef.back());
129  return out;
130  }
131  NumericalType evaluate(double t){
132  NumericalType out;
133  int d = coef.size() - 1;
134  if (d < 0) { return out; }
135  int e = degs.at(d) - 1;
136  out = coef.at(d);
137  d--;
138  for (int i = e; i > -1; --i) {
139  out *= NumericalType(t);
140  if (d > -1){
141  if (i == degs.at(d)) {
142  out += coef.at(d);
143  d--;
144  }
145  }
146  }
147  return out;
148  }
149  std::complex<double> evaluate(std::complex<double> t){
150  std::complex<double> out;
151  int d = coef.size() - 1;
152  if (d < 0) { return out; }
153  int e = degs.at(d) - 1;
154  out = std::complex<double>(coef.at(d));
155  d--;
156  for (int i = e; i > -1; --i) {
157  out *= t;
158  if (d > -1){
159  if (i == degs.at(d)) {
160  out += std::complex<double>(coef.at(d));
161  d--;
162  }
163  }
164  }
165  return out;
166  }
167 };
168 
169 // this should be redone with complexMPF converted into a class, so that it can have nice constructors and behave
170 // like a number not a struct.
171 /**
172  * A univariate polynomial with multi-precision complex coefficients represented sparsely.
173  */
175 {
176  private:
177  std::vector<complexMPF> coef;
178  std::vector<int> degs;
179 
180  public:
182  complexMPF value;
183  mpc_init2(value.c,4*prec);
184  mpq_t zero;
185  mpq_init(zero);
186  for (int i=0; i<A.degree().get_si()+1; i++) {
187  mpc_set_q(value.c,A.coefficient(i).get_mpq_t(),zero);
188  if (!(mpc_eq_zero(value.c))){
189  coef.push_back(value);
190  degs.push_back(i);
191  }
192  }
193  }
195  complexMPF value;
196  mpc_init2(value.c,4*prec);
197  mpq_t zero;
198  mpq_init(zero);
199  for (int i=0; i<A.degree().get_si()+1; i++) {
200  mpc_set_q(value.c,A.coefficient(i).get_mpq_t(),zero);
201  if (!(mpc_eq_zero(value.c))){
202  coef.push_back(value);
203  degs.push_back(i);
204  }
205  }
206  }
207 
208  complexMPF evaluate(complexMPF t, int prec){
209  complexMPF out;
210  mpc_init2(out.c,4*prec);
211  int d = coef.size() - 1;
212  if (d >= 0) {
213  int e = degs.at(d) - 1;
214  mpc_set(out.c,coef.at(d).c);
215  d--;
216  for (int i = e; i > -1; --i) {
217  mpc_mul(out.c,out.c,t.c);
218  if (d > -1){
219  if (i == degs.at(d)) {
220  mpc_add(out.c,out.c,coef.at(d).c);
221  d--;
222  }
223  }
224  }
225  }
226  return out;
227  }
228 };
229 
230 #endif
A sparsely represented univariate polynomial over an arbitrary ring.
Definition: BigPrimeField.hpp:21
An arbitrary-precision complex rational number.
Definition: ComplexRationalNumber.hpp:23
RationalNumber coefficient(int k) const
Get a coefficient of the polynomial.
Definition: urpolynomial.h:199
Integer degree() const
Get degree of the polynomial.
Definition: urpolynomial.h:149
bool isZero() const
Is zero polynomial.
Definition: urpolynomial.h:302
A univariate polynomial with RationalNumber coefficients represented densely.
Definition: urpolynomial.h:16
A univariate polynomial with multi-precision complex coefficients represented sparsely.
Definition: unumericalpolynomial.h:174
A univariate polynomial with numerical coefficients represented sparsely.
Definition: unumericalpolynomial.h:13