-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathinterp2d_spline.h
306 lines (282 loc) · 14.1 KB
/
interp2d_spline.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
* This file is part of interp2d, a GSL-compatible two-dimensional
* interpolation library. <http://www.ellipsix.net/interp2d.html>
*
* Copyright 2013 David Zaslavsky
* Portions based on GNU GSL interpolation code,
* copyright 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file interp2d_spline.h
* @brief Public interface for high-level 2D interpolation functions
*
* This is the public interface to the high-level functions of the
* `%interp2d` library, the ones that _do_ store the data arrays.
* If you're using the high-level interface, you only use the functions in
* this file, unless you're creating a new interpolation type.
*
* The typical workflow is
*
* 1. create an interpolation spline object using interp2d_spline_alloc()
* 2. initialize it using interp2d_spline_init()
* 3. evaluate the interpolating function or its derivatives using
* interp2d_spline_eval() or its counterparts, possibly many times
* 4. free the memory using interp2d_spline_free()
*
* @see interp2d.h
*/
#ifndef __INTERP_2D_SPLINE_H__
#define __INTERP_2D_SPLINE_H__
#include <gsl/gsl_interp.h>
#include "interp2d.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* A 2D interpolation object which stores the arrays defining the function.
* In all other respects, this is just like an interp2d object.
* Instances should be obtained from interp2d_spline_alloc().
*/
typedef struct {
/** The low-level interpolation object */
interp2d interp_object;
/** The x data array */
double* xarr;
/** The y data array */
double* yarr;
/** The z data array */
double* zarr;
} interp2d_spline;
/**
* Allocate a new interpolation spline object. When you want to do an
* interpolation using the high-level interface, you start by calling
* this function. Don't forget to free the memory using
* interp2d_spline_free() when you're done with it.
*
* @param[in] T the `const struct` representing the interpolation algorithm
* you want to use. This should be one of the predefined types provided
* in this library, like interp2d_bilinear or interp2d_bicubic, unless you
* have your own interpolation type you want to use.
* @param[in] xsize the size in the x direction of the grid that will
* specify the function being interpolated
* @param[in] ysize the size in the y direction of the grid that will
* specify the function being interpolated
* @return the newly allocated interpolation object
*/
interp2d_spline* interp2d_spline_alloc(const interp2d_type* T, size_t xsize, size_t ysize);
/**
* Initialize an interpolation spline object with data points that define
* the function being interpolated. This method stores the sizes of the
* arrays and possibly other relevant data in the interp2d_spline object,
* but unlike the low-level equivalent interp2d_init(), it also stores
* the data arrays `xa`, `ya`, and `za`. The content of the arrays is copied,
* so if you change the array elements after calling this, it won't affect
* the interpolation spline object.
*
* This completely resets the state of the object, so it is safe to reuse an
* existing object to interpolate a new function by simply calling
* interp2d_spline_init() on the object with the new arrays. The new arrays
* must be the same size as the old arrays in both dimensions, otherwise this
* function returns an error code.
*
* @param[in] interp the interpolation object, previously initialized
* @param[in] xa the x coordinates of the data, of length `xsize`
* @param[in] ya the y coordinates of the data, of length `ysize`
* @param[in] za the z coordinates of the data, of length `xsize*ysize`
* @param[in] xsize the length of the array `xa`
* @param[in] ysize the length of the array `ya`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_init(interp2d_spline* interp, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize);
/**
* Free the interpolation spline object.
*
* @param[in] interp an interpolation spline object previously allocated
* with interp2d_spline_alloc()
*/
void interp2d_spline_free(interp2d_spline* interp);
/**
* Evaluate the interpolating function at the point `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the value of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the interpolating function at the point `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the value of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Evaluate the x derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the x derivative of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval_deriv_x(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the x derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the x derivative of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_deriv_x_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Evaluate the y derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the y derivative of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval_deriv_y(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the y derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the y derivative of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_deriv_y_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Evaluate the second x derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the second x derivative of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval_deriv_xx(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the second x derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the second x derivative of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_deriv_xx_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Evaluate the second y derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the second y derivative of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval_deriv_yy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the second y derivative of the interpolating function at `(x,y)`.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the second y derivative of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_deriv_yy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Evaluate the cross derivative of the interpolating function at `(x,y)`.
* This is \f$\partial_{xy}f(x,y)\f$.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @return the cross derivative of the interpolating function at `(x,y)`
*/
double interp2d_spline_eval_deriv_xy(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya);
/**
* Evaluate the cross derivative of the interpolating function at `(x,y)`.
* This is \f$\partial_{xy}f(x,y)\f$.
*
* @param[in] interp the interpolation spline object, already initialized
* using interp2d_spline_init()
* @param[in] x the x coordinate at which to evaluate the interpolation
* @param[in] y the y coordinate at which to evaluate the interpolation
* @param[in] xa the accelerator object for the x direction (may be NULL)
* @param[in] ya the accelerator object for the y direction (may be NULL)
* @param[out] z the cross derivative of the interpolating function at `(x,y)`
* @return a status code, either `GSL_SUCCESS` or an error code indicating
* what went wrong
*/
int interp2d_spline_eval_deriv_xy_e(const interp2d_spline* interp, const double x, const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, double* z);
/**
* Return the minimum number of points in each dimension needed by the
* type of the given interpolation object. This just accesses the type
* from `interp` and calls interp2d_type_min_size() on it.
*/
size_t interp2d_spline_min_size(const interp2d_spline* interp);
/**
* Return the type name of the given interpolation. This just accesses
* the type object from `interp` and returns its name.
*/
const char* interp2d_spline_name(const interp2d_spline* interp);
#ifdef __cplusplus
}
#endif
#endif