18 #define M_PI 4 * atan(1) 41 void cf (
int n,
double* poles_r,
double* poles_i,
double* res_r,
double* res_i ) {
49 fftw_complex *w = fftw_alloc_complex(nf);
50 for (
int i = 0; i < nf; ++i) {
51 w[i] = cexp(2.0 * I *
M_PI * (
double)i / (
double)nf);
55 double *t = (
double*) calloc (nf,
sizeof(
double));
56 for (
int i = 0; i < nf; ++i) {
64 fftw_complex *F = fftw_alloc_complex(nf);
65 for (
int i = 0; i < nf; ++i) {
66 F[i] = cexp(scl * (t[i] - 1.0) / (t[i] + 1.0 +
ATOL));
72 fftw_complex *fftF = fftw_alloc_complex(nf);
74 p = fftw_plan_dft_1d(nf, F, fftF, FFTW_FORWARD, FFTW_ESTIMATE);
77 double *c = (
double*) calloc (nf,
sizeof(
double));
78 for (
int i = 0; i < nf; ++i) {
79 c[i] = creal(fftF[i]) / (double)nf;
86 fftw_complex *f = fftw_alloc_complex(nf);
87 memset (f, 0.0, nf *
sizeof(fftw_complex));
89 for (
int i = 0; i < nf; ++i) {
90 for (
int j = K; j >= 0; --j) {
91 f[i] += c[j] * cpow(w[i], j);
96 double *S = (
double*) calloc (K,
sizeof(
double));
97 double *U = (
double*) calloc (K * K,
sizeof(
double));
98 double *V = (
double*) calloc (K * K,
sizeof(
double));
99 double *hankel = (
double*) calloc (K * K,
sizeof(
double));
101 memset (hankel, 0.0, K * K *
sizeof(
double));
103 for (
int i = 0; i < K; ++i) {
104 for (
int j = 0; j <= i; ++j) {
105 hankel[(i - j) + K * j] = c[i + 1];
108 svd (K, hankel, S, U, V);
118 fftw_complex *u = fftw_alloc_complex(nf);
119 fftw_complex *v = fftw_alloc_complex(nf);
122 memset (u, 0.0, nf *
sizeof(fftw_complex));
123 memset (v, 0.0, nf *
sizeof(fftw_complex));
125 for (
int i = 0; i < K; ++i) {
126 u[i] = U[(K - i - 1) + K * n];
135 double *v2 = (
double*) calloc (K,
sizeof(
double));
136 for (
int i = 0; i < K; ++i) {
141 fftw_complex *b1 = fftw_alloc_complex(nf);
142 fftw_complex *b2 = fftw_alloc_complex(nf);
143 fftw_complex *b = fftw_alloc_complex(nf);
145 p = fftw_plan_dft_1d(nf, u, b1, FFTW_FORWARD, FFTW_ESTIMATE);
148 p = fftw_plan_dft_1d(nf, v, b2, FFTW_FORWARD, FFTW_ESTIMATE);
151 for (
int i = 0; i < nf; ++i) {
152 b[i] = b1[i] / b2[i];
161 fftw_complex *rt = fftw_alloc_complex(nf);
162 for (
int i = 0; i < nf; ++i) {
163 rt[i] = f[i] - s_val * cpow(w[i], K) * b[i];
170 double complex *zr = (
double complex*) calloc (K - 1,
sizeof(
double complex));
177 double complex *qk = (
double complex*) calloc (n,
sizeof(
double complex));
178 memset (qk, 0.0, n *
sizeof(
double complex));
181 for (
int j = 0; j < K - 1; ++j) {
182 if (cabs(zr[j]) > 1.0) {
191 double complex *qc_i = (
double complex*) calloc (n + 1,
sizeof(
double complex));
192 memset (qc_i, 0.0, (n + 1) *
sizeof(
double complex));
195 for (
int j = 0; j < n; ++j) {
196 double complex qc_old1 = qc_i[0];
197 double complex qc_old2;
199 for (
int i = 1; i < j + 2; ++i) {
201 qc_i[i] = qc_i[i] - qk[j] * qc_old1;
207 double *qc = (
double*) calloc (n + 1,
sizeof(
double));
208 for (
int i = 0; i < n + 1; ++i) {
209 qc[i] = creal(qc_i[i]);
215 fftw_complex *pt = fftw_alloc_complex(nf);
216 memset (pt, 0.0, nf *
sizeof(fftw_complex));
217 for (
int i = 0; i < nf; ++i) {
218 for (
int j = 0; j < n + 1; ++j) {
219 pt[i] += qc[j] * cpow(w[i], n - j);
229 fftw_complex *ptc_i = fftw_alloc_complex(nf);
230 p = fftw_plan_dft_1d(nf, pt, ptc_i, FFTW_FORWARD, FFTW_ESTIMATE);
233 double *ptc = (
double*) calloc(n + 1,
sizeof(
double));
234 for (
int i = 0; i < n + 1; ++i) {
235 ptc[i] = creal(ptc_i[n - i]) / (double)nf;
238 fftw_destroy_plan(p);
243 double complex *
res = (
double complex*) calloc (n,
sizeof(
double complex));
244 memset (
res, 0.0, n *
sizeof(
double complex));
246 double complex *qk2 = (
double complex*) calloc (n - 1,
sizeof(
double complex));
247 double complex *q2 = (
double complex*) calloc (n,
sizeof(
double complex));
250 for (
int k = 0; k < n; ++k) {
251 double complex q = qk[k];
254 for (
int i = 0; i < n; ++i) {
261 memset (q2, 0.0, n *
sizeof(
double complex));
263 for (
int j = 0; j < n - 1; ++j) {
264 double complex q_old1 = q2[0];
265 double complex q_old2;
266 for (
int i = 1; i < j + 2; ++i) {
268 q2[i] = q2[i] - qk2[j] * q_old1;
273 double complex ck1 = 0.0;
274 for (
int i = 0; i < n + 1; ++i) {
275 ck1 += ptc[i] * cpow(q, n - i);
278 double complex ck2 = 0.0;
279 for (
int i = 0; i < n; ++i) {
280 ck2 += q2[i] * cpow(q, n - 1 - i);
290 double complex *
poles = (
double complex*) calloc (n,
sizeof(
double complex));
291 for (
int i = 0; i < n; ++i) {
293 poles[i] = scl * (qk[i] - 1.0) * (qk[i] - 1.0) / ((qk[i] + 1.0) * (qk[i] + 1.0));
296 res[i] = 4.0 *
res[i] *
poles[i] / (qk[i] * qk[i] - 1.0);
300 for (
int i = 0; i < n; ++i) {
301 poles_r[i] = creal(
poles[i]);
302 poles_i[i] = cimag(
poles[i]);
304 res_r[i] = creal(
res[i]);
305 res_i[i] = cimag(
res[i]);
double complex poles[N_RA]
void cf(int n, double *poles_r, double *poles_i, double *res_r, double *res_i)
Function that calculates the poles and residuals of best rational (partial fraction) approximant to t...
A file generated by Scons that specifies various options to the solvers.
void roots(int n, double *v, double complex *rt)
Polynomial root finding function.
Header definitions of linear algebra routines needed for the Carathéodory-Fejér method.
void svd(int n, double *A, double *S, double *U, double *V)
Singular value decomposition function.