Grid 0.7.0
Remez.h
Go to the documentation of this file.
1/*
2
3 Mike Clark - 25th May 2005
4
5 alg_remez.h
6
7 AlgRemez is an implementation of the Remez algorithm, which in this
8 case is used for generating the optimal nth root rational
9 approximation.
10
11 Note this class requires the gnu multiprecision (GNU MP) library.
12
13*/
14
15#ifndef INCLUDED_ALG_REMEZ_H
16#define INCLUDED_ALG_REMEZ_H
17
18#include <stddef.h>
19#include <Grid/GridStd.h>
20
21#ifdef HAVE_LIBGMP
22#include "bigfloat.h"
23#else
24#include "bigfloat_double.h"
25#endif
26
27#define JMAX 10000 //Maximum number of iterations of Newton's approximation
28#define SUM_MAX 10 // Maximum number of terms in exponential
29
30/*
31 *Usage examples
32 AlgRemez remez(lambda_low,lambda_high,precision);
33 error = remez.generateApprox(n,d,y,z);
34 remez.getPFE(res,pole,&norm);
35 remez.getIPFE(res,pole,&norm);
36 remez.csv(ostream &os);
37 */
38
40{
41 private:
42 char *cname;
43
44 // The approximation parameters
47
48 // The numerator and denominator degree (n=d)
49 int n, d;
50
51 // The bounds of the approximation
53
54 // the numerator and denominator of the power we are approximating
55 unsigned long power_num;
56 unsigned long power_den;
57
58 // Flag to determine whether the arrays have been allocated
59 int alloc;
60
61 // Flag to determine whether the roots have been found
63
64 // Variables used to calculate the approximation
65 int nd1, iter;
68
69 // The exponential summation coefficients
71 int *a_power;
73
74 // The number of equations we must solve at each iteration (n+d+1)
75 int neq;
76
77 // The precision of the GNU MP library
78 long prec;
79
80 // Initial values of maximal and minmal errors
81 void initialGuess();
82
83 // Solve the equations
84 void equations();
85
86 // Search for error maxima and minima
87 void search(bigfloat *step);
88
89 // Initialise step sizes
90 void stpini(bigfloat *step);
91
92 // Calculate the roots of the approximation
93 int root();
94
95 // Evaluate the polynomial
96 bigfloat polyEval(bigfloat x, bigfloat *poly, long size);
97 //complex_bf polyEval(complex_bf x, complex_bf *poly, long size);
98
99 // Evaluate the differential of the polynomial
100 bigfloat polyDiff(bigfloat x, bigfloat *poly, long size);
101 //complex_bf polyDiff(complex_bf x, complex_bf *poly, long size);
102
103 // Newton's method to calculate roots
104 bigfloat rtnewt(bigfloat *poly, long i, bigfloat x1, bigfloat x2, bigfloat xacc);
105 //complex_bf rtnewt(complex_bf *poly, long i, bigfloat x1, bigfloat x2, bigfloat xacc);
106
107 // Evaluate the partial fraction expansion of the rational function
108 // with res roots and poles poles. Result is overwritten on input
109 // arrays.
110 void pfe(bigfloat *res, bigfloat* poles, bigfloat norm);
111
112 // Calculate function required for the approximation
114
115 // Compute size and sign of the approximation error at x
116 bigfloat getErr(bigfloat x, int *sign);
117
118 // Solve the system AX=B
119 int simq(bigfloat *A, bigfloat *B, bigfloat *X, int n);
120
121 // Free memory and reallocate as necessary
122 void allocate(int num_degree, int den_degree);
123
124 // Evaluate the rational form P(x)/Q(x) using coefficients from the
125 // solution vector param
127
128 public:
129
130 // Constructor
131 AlgRemez(double lower, double upper, long prec);
132
133 // Destructor
134 virtual ~AlgRemez();
135
136 int getDegree(void){
137 assert(n==d);
138 return n;
139 }
140 // Reset the bounds of the approximation
141 void setBounds(double lower, double upper);
142 // Reset the bounds of the approximation
143 void getBounds(double &lower, double &upper) {
144 lower=(double)apstrt;
145 upper=(double)apend;
146 }
147
148 // Generate the rational approximation x^(pnum/pden)
149 double generateApprox(int num_degree, int den_degree,
150 unsigned long power_num, unsigned long power_den,
151 int a_len, double* a_param, int* a_pow);
152 double generateApprox(int num_degree, int den_degree,
153 unsigned long power_num, unsigned long power_den);
154 double generateApprox(int degree, unsigned long power_num,
155 unsigned long power_den);
156
157 // Return the partial fraction expansion of the approximation x^(pnum/pden)
158 int getPFE(double *res, double *pole, double *norm);
159
160 // Return the partial fraction expansion of the approximation x^(-pnum/pden)
161 int getIPFE(double *res, double *pole, double *norm);
162
163 // Evaluate the rational form P(x)/Q(x) using coefficients from the
164 // solution vector param
165 double evaluateApprox(double x);
166
167 // Evaluate the rational form Q(x)/P(x) using coefficients from the
168 // solution vector param
169 double evaluateInverseApprox(double x);
170
171 // Calculate function required for the approximation
172 double evaluateFunc(double x);
173
174 // Calculate inverse function required for the approximation
175 double evaluateInverseFunc(double x);
176
177 // Dump csv of function, approx and error
178 void csv(std::ostream &os);
179};
180
181#endif // Include guard
182
183
184
B
void initialGuess()
Definition Remez.cc:262
bigfloat func(bigfloat x)
Definition Remez.cc:453
int getDegree(void)
Definition Remez.h:136
void pfe(bigfloat *res, bigfloat *poles, bigfloat norm)
Definition Remez.cc:666
int getPFE(double *res, double *pole, double *norm)
Definition Remez.cc:179
bigfloat tolerance
Definition Remez.h:67
unsigned long power_num
Definition Remez.h:55
bigfloat apend
Definition Remez.h:52
int iter
Definition Remez.h:65
int alloc
Definition Remez.h:59
int root()
Definition Remez.cc:587
bigfloat apwidt
Definition Remez.h:52
void allocate(int num_degree, int den_degree)
Definition Remez.cc:63
int n
Definition Remez.h:49
int d
Definition Remez.h:49
bigfloat * xx
Definition Remez.h:66
void getBounds(double &lower, double &upper)
Definition Remez.h:143
bigfloat norm
Definition Remez.h:46
void csv(std::ostream &os)
Definition Remez.cc:748
void equations()
Definition Remez.cc:382
bigfloat delta
Definition Remez.h:67
int foundRoots
Definition Remez.h:62
void search(bigfloat *step)
Definition Remez.cc:299
bigfloat polyDiff(bigfloat x, bigfloat *poly, long size)
Definition Remez.cc:638
bigfloat * a
Definition Remez.h:70
AlgRemez(double lower, double upper, long prec)
Definition Remez.cc:26
bigfloat * param
Definition Remez.h:45
double evaluateApprox(double x)
Definition Remez.cc:732
int a_length
Definition Remez.h:72
unsigned long power_den
Definition Remez.h:56
int nd1
Definition Remez.h:65
bigfloat rtnewt(bigfloat *poly, long i, bigfloat x1, bigfloat x2, bigfloat xacc)
Definition Remez.cc:646
int neq
Definition Remez.h:75
double evaluateInverseFunc(double x)
Definition Remez.cc:744
double generateApprox(int num_degree, int den_degree, unsigned long power_num, unsigned long power_den, int a_len, double *a_param, int *a_pow)
Definition Remez.cc:114
bigfloat * step
Definition Remez.h:66
bigfloat apstrt
Definition Remez.h:52
char * cname
Definition Remez.h:42
double evaluateFunc(double x)
Definition Remez.cc:740
virtual ~AlgRemez()
Definition Remez.cc:49
int getIPFE(double *res, double *pole, double *norm)
Definition Remez.cc:218
int simq(bigfloat *A, bigfloat *B, bigfloat *X, int n)
Definition Remez.cc:472
bigfloat polyEval(bigfloat x, bigfloat *poly, long size)
Definition Remez.cc:631
long prec
Definition Remez.h:78
bigfloat spread
Definition Remez.h:67
int * a_power
Definition Remez.h:71
bigfloat * roots
Definition Remez.h:45
bigfloat * mm
Definition Remez.h:66
void setBounds(double lower, double upper)
Definition Remez.cc:91
bigfloat getErr(bigfloat x, int *sign)
Definition Remez.cc:437
void stpini(bigfloat *step)
Definition Remez.cc:290
double evaluateInverseApprox(double x)
Definition Remez.cc:736
bigfloat approx(bigfloat x)
Definition Remez.cc:423
bigfloat * poles
Definition Remez.h:45