Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInference 4.1.9.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cubic_interp.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015-2017 Leo Singer
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19
20
21#include "cubic_interp.h"
22#include <math.h>
23#include <stdlib.h>
24#include <string.h>
25
26
27static int clip_int(int t, int min, int max)
28{
29 if (t < min)
30 return min;
31 else if (t > max)
32 return max;
33 else
34 return t;
35}
36
37
38static double clip_double(double t, double min, double max)
39{
40 if (t < min)
41 return min;
42 else if (t > max)
43 return max;
44 else
45 return t;
46}
47
48
49/*
50 * Calculate coefficients of the interpolating polynomial in the form
51 * a[0] * t^3 + a[1] * t^2 + a[2] * t + a[3]
52 */
54 double *a, const double *z, const double *z1)
55{
56 if (!isfinite(z1[1] + z1[2]))
57 {
58 /* If either of the inner grid points are NaN or infinite,
59 * then fall back to nearest-neighbor interpolation. */
60 a[0] = 0;
61 a[1] = 0;
62 a[2] = 0;
63 a[3] = z[1];
64 } else if (!isfinite(z1[0] + z1[3])) {
65 /* If either of the outer grid points are NaN or infinite,
66 * then fall back to linear interpolation. */
67 a[0] = 0;
68 a[1] = 0;
69 a[2] = z[2] - z[1];
70 a[3] = z[1];
71 } else {
72 /* Otherwise, all of the grid points are finite.
73 * Use cubic interpolation. */
74 a[0] = 1.5 * (z[1] - z[2]) + 0.5 * (z[3] - z[0]);
75 a[1] = z[0] - 2.5 * z[1] + 2 * z[2] - 0.5 * z[3];
76 a[2] = 0.5 * (z[2] - z[0]);
77 a[3] = z[1];
78 }
79}
80
81
82static double cubic_eval(const double *a, double t)
83{
84 return ((a[0] * t + a[1]) * t + a[2]) * t + a[3];
85}
86
87
89 double f, double t0, double length, double *t, double *i)
90{
91 *t = modf(clip_double(*t * f + t0, 0, length), i);
92}
93
94
96 const double *data, int n, double tmin, double dt)
97{
98 cubic_interp *interp;
99 const int length = n + 6;
100 interp = malloc(sizeof(*interp) + length * sizeof(*interp->a));
101 if (interp)
102 {
103 interp->f = 1 / dt;
104 interp->t0 = 3 - interp->f * tmin;
105 interp->length = length;
106 for (int i = 0; i < length; i ++)
107 {
108 double z[4];
109 for (int j = 0; j < 4; j ++)
110 {
111 z[j] = data[clip_int(i + j - 4, 0, n - 1)];
112 }
113 cubic_interp_init_coefficients(interp->a[i], z, z);
114 }
115 }
116 return interp;
117}
118
119
121{
122 free(interp);
123}
124
125
126double cubic_interp_eval(const cubic_interp *interp, double t)
127{
128 double i;
129 if (isnan(t))
130 return t;
131 cubic_interp_index(interp->f, interp->t0, interp->length, &t, &i);
132 return cubic_eval(interp->a[(int) i], t);
133}
134
135
137 const double *data, int ns, int nt,
138 double smin, double tmin, double ds, double dt)
139{
140 bicubic_interp *interp;
141 const int slength = ns + 6;
142 const int tlength = nt + 6;
143 interp = malloc(sizeof(*interp) + slength * tlength * sizeof(*interp->a));
144 if (interp)
145 {
146 interp->fs = 1 / ds;
147 interp->ft = 1 / dt;
148 interp->s0 = 3 - interp->fs * smin;
149 interp->t0 = 3 - interp->ft * tmin;
150 interp->slength = slength;
151 interp->tlength = tlength;
152 for (int is = 0; is < slength; is ++)
153 {
154 for (int it = 0; it < tlength; it ++)
155 {
156 double a[4][4], a1[4][4];
157 for (int js = 0; js < 4; js ++)
158 {
159 double z[4];
160 int ks = clip_int(is + js - 4, 0, ns - 1);
161 for (int jt = 0; jt < 4; jt ++)
162 {
163 int kt = clip_int(it + jt - 4, 0, nt - 1);
164 z[jt] = data[ks * ns + kt];
165 }
167 }
168 for (int js = 0; js < 4; js ++)
169 {
170 for (int jt = 0; jt < 4; jt ++)
171 {
172 a1[js][jt] = a[jt][js];
173 }
174 }
175 for (int js = 0; js < 4; js ++)
176 {
177 cubic_interp_init_coefficients(a[js], a1[js], a1[3]);
178 }
179 memcpy(interp->a[is * slength + it], a, sizeof(a));
180 }
181 }
182 }
183 return interp;
184}
185
186
188{
189 free(interp);
190}
191
192
193double bicubic_interp_eval(const bicubic_interp *interp, double s, double t)
194{
195 const double (*a)[4];
196 double b[4];
197 double is, it;
198
199 if (isnan(s) || isnan(t))
200 return s + t;
201 cubic_interp_index(interp->fs, interp->s0, interp->slength, &s, &is);
202 cubic_interp_index(interp->ft, interp->t0, interp->tlength, &t, &it);
203 a = interp->a[(int) (is * interp->slength + it)];
204 for (int i = 0; i < 4; i ++)
205 b[i] = cubic_eval(a[i], s);
206 return cubic_eval(b, t);
207}
#define max(a, b)
int j
int s
static double clip_double(double t, double min, double max)
Definition: cubic_interp.c:38
bicubic_interp * bicubic_interp_init(const double *data, int ns, int nt, double smin, double tmin, double ds, double dt)
Definition: cubic_interp.c:136
void cubic_interp_free(cubic_interp *interp)
Definition: cubic_interp.c:120
void bicubic_interp_free(bicubic_interp *interp)
Definition: cubic_interp.c:187
static int clip_int(int t, int min, int max)
Definition: cubic_interp.c:27
double bicubic_interp_eval(const bicubic_interp *interp, double s, double t)
Definition: cubic_interp.c:193
static double cubic_eval(const double *a, double t)
Definition: cubic_interp.c:82
static void cubic_interp_index(double f, double t0, double length, double *t, double *i)
Definition: cubic_interp.c:88
static void cubic_interp_init_coefficients(double *a, const double *z, const double *z1)
Definition: cubic_interp.c:53
cubic_interp * cubic_interp_init(const double *data, int n, double tmin, double dt)
Definition: cubic_interp.c:95
double cubic_interp_eval(const cubic_interp *interp, double t)
Definition: cubic_interp.c:126
sigmaKerr data[0]
static const INT4 a
ns
double t0
double a[][4][4]
Definition: cubic_interp.h:46
double a[][4]
Definition: cubic_interp.h:41
double length
Definition: cubic_interp.h:40