pyvale 2025.5.3__cp311-cp311-macosx_14_0_arm64.whl → 2025.7.0__cp311-cp311-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyvale might be problematic. Click here for more details.
- pyvale/.dylibs/libomp.dylib +0 -0
- pyvale/.dylibs/libunwind.1.0.dylib +0 -0
- pyvale/__init__.py +12 -0
- pyvale/blendercalibrationdata.py +3 -1
- pyvale/blenderscene.py +7 -5
- pyvale/blendertools.py +27 -5
- pyvale/camera.py +1 -0
- pyvale/cameradata.py +3 -0
- pyvale/camerasensor.py +147 -0
- pyvale/camerastereo.py +4 -4
- pyvale/cameratools.py +23 -61
- pyvale/cython/rastercyth.c +1657 -1352
- pyvale/cython/rastercyth.cpython-311-darwin.so +0 -0
- pyvale/cython/rastercyth.py +71 -26
- pyvale/data/plate_hole_def0000.tiff +0 -0
- pyvale/data/plate_hole_def0001.tiff +0 -0
- pyvale/data/plate_hole_ref0000.tiff +0 -0
- pyvale/data/plate_rigid_def0000.tiff +0 -0
- pyvale/data/plate_rigid_def0001.tiff +0 -0
- pyvale/data/plate_rigid_ref0000.tiff +0 -0
- pyvale/dataset.py +96 -6
- pyvale/dic/cpp/dicbruteforce.cpp +370 -0
- pyvale/dic/cpp/dicfourier.cpp +648 -0
- pyvale/dic/cpp/dicinterpolator.cpp +559 -0
- pyvale/dic/cpp/dicmain.cpp +215 -0
- pyvale/dic/cpp/dicoptimizer.cpp +675 -0
- pyvale/dic/cpp/dicrg.cpp +137 -0
- pyvale/dic/cpp/dicscanmethod.cpp +677 -0
- pyvale/dic/cpp/dicsmooth.cpp +138 -0
- pyvale/dic/cpp/dicstrain.cpp +383 -0
- pyvale/dic/cpp/dicutil.cpp +563 -0
- pyvale/dic2d.py +164 -0
- pyvale/dic2dcpp.cpython-311-darwin.so +0 -0
- pyvale/dicchecks.py +476 -0
- pyvale/dicdataimport.py +247 -0
- pyvale/dicregionofinterest.py +887 -0
- pyvale/dicresults.py +55 -0
- pyvale/dicspecklegenerator.py +238 -0
- pyvale/dicspecklequality.py +305 -0
- pyvale/dicstrain.py +387 -0
- pyvale/dicstrainresults.py +37 -0
- pyvale/errorintegrator.py +10 -8
- pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +124 -113
- pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +124 -132
- pyvale/examples/basics/ex1_3_customsens_therm3d.py +199 -195
- pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +125 -121
- pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +145 -141
- pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +96 -101
- pyvale/examples/basics/ex1_7_spatavg_therm2d.py +109 -105
- pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +92 -91
- pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +96 -90
- pyvale/examples/basics/ex2_3_sensangle_disp2d.py +88 -89
- pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +172 -171
- pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +88 -86
- pyvale/examples/basics/ex3_1_basictensors_strain2d.py +90 -90
- pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +93 -91
- pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +172 -160
- pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +154 -148
- pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +249 -231
- pyvale/examples/dic/ex1_region_of_interest.py +98 -0
- pyvale/examples/dic/ex2_plate_with_hole.py +149 -0
- pyvale/examples/dic/ex3_plate_with_hole_strain.py +93 -0
- pyvale/examples/dic/ex4_dic_blender.py +95 -0
- pyvale/examples/dic/ex5_dic_challenge.py +102 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +4 -2
- pyvale/examples/renderblender/ex1_1_blenderscene.py +152 -105
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +151 -100
- pyvale/examples/renderblender/ex2_1_stereoscene.py +183 -116
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +185 -112
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +164 -109
- pyvale/examples/renderrasterisation/ex_rastenp.py +74 -35
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +6 -13
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +2 -2
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +2 -4
- pyvale/imagedef2d.py +3 -2
- pyvale/imagetools.py +137 -0
- pyvale/rastercy.py +34 -4
- pyvale/rasternp.py +300 -276
- pyvale/rasteropts.py +58 -0
- pyvale/renderer.py +47 -0
- pyvale/rendermesh.py +52 -62
- pyvale/renderscene.py +51 -0
- pyvale/sensorarrayfactory.py +2 -2
- pyvale/sensortools.py +19 -35
- pyvale/simcases/case21.i +1 -1
- pyvale/simcases/run_1case.py +8 -0
- pyvale/simtools.py +2 -2
- pyvale/visualsimplotter.py +180 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/METADATA +11 -57
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/RECORD +93 -57
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/WHEEL +1 -1
- pyvale/examples/visualisation/ex1_1_plot_traces.py +0 -102
- pyvale/examples/visualisation/ex2_1_animate_sim.py +0 -89
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
// ================================================================================
|
|
2
|
+
// pyvale: the python validation engine
|
|
3
|
+
// License: MIT
|
|
4
|
+
// Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
// ================================================================================
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// STD library Header files
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <iostream>
|
|
11
|
+
|
|
12
|
+
// Program Header files
|
|
13
|
+
#include "./dicinterpolator.hpp"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
inline int idx_from_2d(const int x, const int y, const int length){
|
|
18
|
+
return y*length+x;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Interpolator::Interpolator(double*img, int px_hori, int px_vert){
|
|
24
|
+
|
|
25
|
+
//util::Timer timer("interpolator initialisation");
|
|
26
|
+
|
|
27
|
+
// intitialise vars used globally within Interpolator.
|
|
28
|
+
this->image = img;
|
|
29
|
+
this->px_vert = px_vert;
|
|
30
|
+
this->px_hori = px_hori;
|
|
31
|
+
|
|
32
|
+
// allocate memory for pixel coordinate arrays
|
|
33
|
+
px_y.resize(px_vert);
|
|
34
|
+
px_x.resize(px_hori);
|
|
35
|
+
|
|
36
|
+
// allocate memory for image derivatives
|
|
37
|
+
dx.resize(px_vert*px_hori);
|
|
38
|
+
dy.resize(px_vert*px_hori);
|
|
39
|
+
dxy.resize(px_vert*px_hori);
|
|
40
|
+
|
|
41
|
+
// setting pixel values for internal vectors
|
|
42
|
+
for (int i = 0; i < px_hori; i++) {
|
|
43
|
+
px_x[i] = i;
|
|
44
|
+
}
|
|
45
|
+
for (int j = 0; j < px_vert; j++) {
|
|
46
|
+
px_y[j] = j;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//interpolator data
|
|
51
|
+
std::vector<double> data(px_hori,0);
|
|
52
|
+
|
|
53
|
+
//#pragma omp parallel for
|
|
54
|
+
for (int j = 0; j < px_vert; j++){
|
|
55
|
+
|
|
56
|
+
// get 1D data
|
|
57
|
+
for (int i = 0; i < px_hori; i++) {
|
|
58
|
+
data[i] = image[j*px_hori + i];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
cspline_init(px_x, data);
|
|
62
|
+
for (int i = 0; i < px_hori; i++){
|
|
63
|
+
dx[j*px_hori + i] = cspline_eval_deriv(px_x, data, px_x[i], px_hori);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
data.resize(px_vert,0);
|
|
68
|
+
|
|
69
|
+
//#pragma omp parallel for
|
|
70
|
+
for (int i = 0; i < px_hori; ++i) {
|
|
71
|
+
|
|
72
|
+
// get 1D data
|
|
73
|
+
for (int j = 0; j < px_vert; j++){
|
|
74
|
+
data[j] = image[j*px_hori + i];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
cspline_init(px_y, data);
|
|
78
|
+
for (int j = 0; j < px_vert; j++){
|
|
79
|
+
dy[j*px_hori + i] = cspline_eval_deriv(px_y, data, px_y[j], px_vert);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
data.resize(px_hori,0);
|
|
85
|
+
|
|
86
|
+
//#pragma omp parallel for
|
|
87
|
+
for (int j = 0; j < px_vert; j++){
|
|
88
|
+
|
|
89
|
+
// get 1D data
|
|
90
|
+
for (int i = 0; i < px_hori; i++) {
|
|
91
|
+
data[i] = dy[j*px_hori + i];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
cspline_init(px_x, data);
|
|
95
|
+
for (int i = 0; i < px_hori; i++){
|
|
96
|
+
dxy[j*px_hori + i] = cspline_eval_deriv(px_x, data, px_x[i], px_hori);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
double Interpolator::eval_bicubic(const int ss_x, const int ss_y, const double subpx_x, const double subpx_y) const {
|
|
102
|
+
|
|
103
|
+
// get indices
|
|
104
|
+
size_t xi,yi;
|
|
105
|
+
index_lookup_xy(ss_x, ss_y, xi, yi, subpx_x, subpx_y);
|
|
106
|
+
|
|
107
|
+
// 4 neighbouring grid points
|
|
108
|
+
int idx00 = idx_from_2d(xi, yi, px_hori);
|
|
109
|
+
int idx01 = idx_from_2d(xi, yi + 1, px_hori);
|
|
110
|
+
int idx10 = idx_from_2d(xi + 1, yi, px_hori);
|
|
111
|
+
int idx11 = idx_from_2d(xi + 1, yi + 1, px_hori);
|
|
112
|
+
|
|
113
|
+
double d00 = image[idx00];
|
|
114
|
+
double d01 = image[idx01];
|
|
115
|
+
double d10 = image[idx10];
|
|
116
|
+
double d11 = image[idx11];
|
|
117
|
+
|
|
118
|
+
double dx00 = dx[idx00];
|
|
119
|
+
double dx01 = dx[idx01];
|
|
120
|
+
double dx10 = dx[idx10];
|
|
121
|
+
double dx11 = dx[idx11];
|
|
122
|
+
|
|
123
|
+
double dy00 = dy[idx00];
|
|
124
|
+
double dy01 = dy[idx01];
|
|
125
|
+
double dy10 = dy[idx10];
|
|
126
|
+
double dy11 = dy[idx11];
|
|
127
|
+
|
|
128
|
+
double dxy00 = dxy[idx00];
|
|
129
|
+
double dxy01 = dxy[idx01];
|
|
130
|
+
double dxy10 = dxy[idx10];
|
|
131
|
+
double dxy11 = dxy[idx11];
|
|
132
|
+
|
|
133
|
+
// polynomial terms
|
|
134
|
+
double t0 = 1;
|
|
135
|
+
double u0 = 1;
|
|
136
|
+
double t1 = (subpx_x - px_x[xi]);
|
|
137
|
+
double u1 = (subpx_y - px_y[yi]);
|
|
138
|
+
double t2 = t1*t1;
|
|
139
|
+
double u2 = u1*u1;
|
|
140
|
+
double t3 = t1*t2;
|
|
141
|
+
double u3 = u1*u2;
|
|
142
|
+
|
|
143
|
+
/* Perform bicubic interpolation */
|
|
144
|
+
double result = 0.0;
|
|
145
|
+
result += d00*t0*u0;
|
|
146
|
+
result += dy00*t0*u1;
|
|
147
|
+
result += (-3*d00 + 3*d01 - 2*dy00 - dy01)*t0*u2;
|
|
148
|
+
result += (2*d00 - 2*d01 + dy00 + dy01)*t0*u3;
|
|
149
|
+
|
|
150
|
+
result += dx00*t1*u0;
|
|
151
|
+
result += dxy00*t1*u1;
|
|
152
|
+
result += (-3*dx00 + 3*dx01 - 2*dxy00 - dxy01)*t1*u2;
|
|
153
|
+
result += (2*dx00 - 2*dx01 + dxy00 + dxy01)*t1*u3;
|
|
154
|
+
|
|
155
|
+
result += (-3*d00 + 3*d10 - 2*dx00 - dx10)*t2*u0;
|
|
156
|
+
result += (-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t2*u1;
|
|
157
|
+
result += (9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t2*u2;
|
|
158
|
+
result += (-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t2*u3;
|
|
159
|
+
|
|
160
|
+
result += (2*d00 - 2*d10 + dx00 + dx10)*t3*u0;
|
|
161
|
+
result += (2*dy00 - 2*dy10 + dxy00 + dxy10)*t3*u1;
|
|
162
|
+
result += (-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t3*u2;
|
|
163
|
+
result += (4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t3*u3;
|
|
164
|
+
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
double Interpolator::eval_bicubic_dx(const int ss_x, const int ss_y, const double subpx_x, const double subpx_y) const{
|
|
172
|
+
|
|
173
|
+
/* first compute the indices into the data arrays where we are interpolating */
|
|
174
|
+
size_t xi,yi;
|
|
175
|
+
index_lookup_xy(ss_x, ss_y, xi, yi, subpx_x, subpx_y);
|
|
176
|
+
|
|
177
|
+
int idx00 = idx_from_2d(xi, yi, px_hori);
|
|
178
|
+
int idx01 = idx_from_2d(xi, yi + 1, px_hori);
|
|
179
|
+
int idx10 = idx_from_2d(xi + 1, yi, px_hori);
|
|
180
|
+
int idx11 = idx_from_2d(xi + 1, yi + 1, px_hori);
|
|
181
|
+
|
|
182
|
+
double d00 = image[idx00];
|
|
183
|
+
double d01 = image[idx01];
|
|
184
|
+
double d10 = image[idx10];
|
|
185
|
+
double d11 = image[idx11];
|
|
186
|
+
|
|
187
|
+
double dx00 = dx[idx00];
|
|
188
|
+
double dx01 = dx[idx01];
|
|
189
|
+
double dx10 = dx[idx10];
|
|
190
|
+
double dx11 = dx[idx11];
|
|
191
|
+
double dy00 = dy[idx00];
|
|
192
|
+
double dy01 = dy[idx01];
|
|
193
|
+
double dy10 = dy[idx10];
|
|
194
|
+
double dy11 = dy[idx11];
|
|
195
|
+
double dxy00 = dxy[idx00];
|
|
196
|
+
double dxy01 = dxy[idx01];
|
|
197
|
+
double dxy10 = dxy[idx10];
|
|
198
|
+
double dxy11 = dxy[idx11];
|
|
199
|
+
|
|
200
|
+
// polynomial terms
|
|
201
|
+
double t0 = 1;
|
|
202
|
+
double u0 = 1;
|
|
203
|
+
double t1 = (subpx_x - px_x[xi]);
|
|
204
|
+
double u1 = (subpx_y - px_y[yi]);
|
|
205
|
+
double t2 = t1*t1;
|
|
206
|
+
double u2 = u1*u1;
|
|
207
|
+
double u3 = u1*u2;
|
|
208
|
+
|
|
209
|
+
double result = 0.0;
|
|
210
|
+
result += dx00 *t0*u0;
|
|
211
|
+
result += dxy00*t0*u1;
|
|
212
|
+
result += (-3*dx00 + 3*dx01 - 2*dxy00 - dxy01) *t0*u2;
|
|
213
|
+
result += (2*dx00 - 2*dx01 + dxy00 + dxy01)*t0*u3;
|
|
214
|
+
result += 2*(-3*d00 + 3*d10 - 2*dx00 - dx10)*t1*u0;
|
|
215
|
+
result += 2*(-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t1*u1;
|
|
216
|
+
result += 2*(9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t1*u2;
|
|
217
|
+
result += 2*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t1*u3;
|
|
218
|
+
result += 3*(2*d00 - 2*d10 + dx00 + dx10)*t2 *u0;
|
|
219
|
+
result += 3*(2*dy00 - 2*dy10 + dxy00 + dxy10)*t2*u1;
|
|
220
|
+
result += 3*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t2*u2;
|
|
221
|
+
result += 3*(4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t2*u3;
|
|
222
|
+
return result;
|
|
223
|
+
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
double Interpolator::eval_bicubic_dy(const int ss_x, const int ss_y, const double subpx_x, const double subpx_y) const{
|
|
228
|
+
|
|
229
|
+
size_t xi,yi;
|
|
230
|
+
index_lookup_xy(ss_x, ss_y, xi, yi, subpx_x, subpx_y);
|
|
231
|
+
|
|
232
|
+
// precompute indices of surrounding pixel values
|
|
233
|
+
size_t idx00 = idx_from_2d(xi, yi, px_hori);
|
|
234
|
+
size_t idx01 = idx_from_2d(xi, yi + 1, px_hori);
|
|
235
|
+
size_t idx10 = idx_from_2d(xi + 1, yi, px_hori);
|
|
236
|
+
size_t idx11 = idx_from_2d(xi + 1, yi + 1, px_hori);
|
|
237
|
+
|
|
238
|
+
double d00 = image[idx00];
|
|
239
|
+
double d01 = image[idx01];
|
|
240
|
+
double d10 = image[idx10];
|
|
241
|
+
double d11 = image[idx11];
|
|
242
|
+
|
|
243
|
+
double dx00 = dx[idx00];
|
|
244
|
+
double dx01 = dx[idx01];
|
|
245
|
+
double dx10 = dx[idx10];
|
|
246
|
+
double dx11 = dx[idx11];
|
|
247
|
+
double dy00 = dy[idx00];
|
|
248
|
+
double dy01 = dy[idx01];
|
|
249
|
+
double dy10 = dy[idx10];
|
|
250
|
+
double dy11 = dy[idx11];
|
|
251
|
+
double dxy00 = dxy[idx00];
|
|
252
|
+
double dxy01 = dxy[idx01];
|
|
253
|
+
double dxy10 = dxy[idx10];
|
|
254
|
+
double dxy11 = dxy[idx11];
|
|
255
|
+
|
|
256
|
+
// polynomial terms
|
|
257
|
+
double t0 = 1;
|
|
258
|
+
double u0 = 1;
|
|
259
|
+
double t1 = (subpx_x - px_x[xi]);
|
|
260
|
+
double u1 = (subpx_y - px_y[yi]);
|
|
261
|
+
double t2 = t1*t1;
|
|
262
|
+
double u2 = u1*u1;
|
|
263
|
+
double t3 = t1*t2;
|
|
264
|
+
|
|
265
|
+
double result = 0.0;
|
|
266
|
+
result += dy00*t0*u0;
|
|
267
|
+
result += 2*(-3*d00 + 3*d01 - 2*dy00 - dy01)*t0*u1;
|
|
268
|
+
result += 3*(2*d00-2*d01 + dy00 + dy01)*t0*u2;
|
|
269
|
+
result += dxy00*t1*u0;
|
|
270
|
+
result += 2*(-3*dx00 + 3*dx01 - 2*dxy00 - dxy01)*t1*u1;
|
|
271
|
+
result += 3*(2*dx00 - 2*dx01 + dxy00 + dxy01)*t1*u2;
|
|
272
|
+
result += (-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t2*u0;
|
|
273
|
+
result += 2*(9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t2*u1;
|
|
274
|
+
result += 3*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t2*u2;
|
|
275
|
+
result += (2*dy00 - 2*dy10 + dxy00 + dxy10)*t3*u0;
|
|
276
|
+
result += 2*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t3*u1;
|
|
277
|
+
result += 3*(4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t3*u2;
|
|
278
|
+
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
InterpVals Interpolator::eval_bicubic_and_derivs(const int ss_x, const int ss_y, const double subpx_x, const double subpx_y) const{
|
|
284
|
+
|
|
285
|
+
// pixel floor of x and y
|
|
286
|
+
size_t xi,yi;
|
|
287
|
+
index_lookup_xy(ss_x, ss_y, xi, yi, subpx_x, subpx_y);
|
|
288
|
+
|
|
289
|
+
// precompute indices of surrounding pixel values
|
|
290
|
+
size_t idx00 = idx_from_2d(xi, yi, px_hori);
|
|
291
|
+
size_t idx01 = idx_from_2d(xi, yi + 1, px_hori);
|
|
292
|
+
size_t idx10 = idx_from_2d(xi + 1, yi, px_hori);
|
|
293
|
+
size_t idx11 = idx_from_2d(xi + 1, yi + 1, px_hori);
|
|
294
|
+
|
|
295
|
+
double d00 = image[idx00];
|
|
296
|
+
double d01 = image[idx01];
|
|
297
|
+
double d10 = image[idx10];
|
|
298
|
+
double d11 = image[idx11];
|
|
299
|
+
|
|
300
|
+
double dx00 = dx[idx00];
|
|
301
|
+
double dx01 = dx[idx01];
|
|
302
|
+
double dx10 = dx[idx10];
|
|
303
|
+
double dx11 = dx[idx11];
|
|
304
|
+
double dy00 = dy[idx00];
|
|
305
|
+
double dy01 = dy[idx01];
|
|
306
|
+
double dy10 = dy[idx10];
|
|
307
|
+
double dy11 = dy[idx11];
|
|
308
|
+
double dxy00 = dxy[idx00];
|
|
309
|
+
double dxy01 = dxy[idx01];
|
|
310
|
+
double dxy10 = dxy[idx10];
|
|
311
|
+
double dxy11 = dxy[idx11];
|
|
312
|
+
|
|
313
|
+
// polynomial terms
|
|
314
|
+
double t0 = 1;
|
|
315
|
+
double u0 = 1;
|
|
316
|
+
double t1 = (subpx_x - px_x[xi]);
|
|
317
|
+
double u1 = (subpx_y - px_y[yi]);
|
|
318
|
+
double t2 = t1*t1;
|
|
319
|
+
double u2 = u1*u1;
|
|
320
|
+
double t3 = t1*t2;
|
|
321
|
+
double u3 = u1*u2;
|
|
322
|
+
|
|
323
|
+
double result = 0.0;
|
|
324
|
+
double result_dx = 0.0;
|
|
325
|
+
double result_dy = 0.0;
|
|
326
|
+
|
|
327
|
+
result += d00*t0*u0;
|
|
328
|
+
result += dy00*t0*u1;
|
|
329
|
+
result += (-3*d00 + 3*d01 - 2*dy00 - dy01)*t0*u2;
|
|
330
|
+
result += (2*d00 - 2*d01 + dy00 + dy01)*t0*u3;
|
|
331
|
+
result += dx00*t1*u0;
|
|
332
|
+
result += dxy00*t1*u1;
|
|
333
|
+
result += (-3*dx00 + 3*dx01 - 2*dxy00 - dxy01)*t1*u2;
|
|
334
|
+
result += (2*dx00 - 2*dx01 + dxy00 + dxy01)*t1*u3;
|
|
335
|
+
result += (-3*d00 + 3*d10 - 2*dx00 - dx10)*t2*u0;
|
|
336
|
+
result += (-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t2*u1;
|
|
337
|
+
result += (9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t2*u2;
|
|
338
|
+
result += (-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t2*u3;
|
|
339
|
+
result += (2*d00 - 2*d10 + dx00 + dx10)*t3*u0;
|
|
340
|
+
result += (2*dy00 - 2*dy10 + dxy00 + dxy10)*t3*u1;
|
|
341
|
+
result += (-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t3*u2;
|
|
342
|
+
result += (4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t3*u3;
|
|
343
|
+
|
|
344
|
+
result_dx += dx00 *t0*u0;
|
|
345
|
+
result_dx += dxy00*t0*u1;
|
|
346
|
+
result_dx += (-3*dx00 + 3*dx01 - 2*dxy00 - dxy01) *t0*u2;
|
|
347
|
+
result_dx += (2*dx00 - 2*dx01 + dxy00 + dxy01)*t0*u3;
|
|
348
|
+
result_dx += 2*(-3*d00 + 3*d10 - 2*dx00 - dx10)*t1*u0;
|
|
349
|
+
result_dx += 2*(-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t1*u1;
|
|
350
|
+
result_dx += 2*(9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t1*u2;
|
|
351
|
+
result_dx += 2*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t1*u3;
|
|
352
|
+
result_dx += 3*(2*d00 - 2*d10 + dx00 + dx10)*t2 *u0;
|
|
353
|
+
result_dx += 3*(2*dy00 - 2*dy10 + dxy00 + dxy10)*t2*u1;
|
|
354
|
+
result_dx += 3*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t2*u2;
|
|
355
|
+
result_dx += 3*(4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t2*u3;
|
|
356
|
+
|
|
357
|
+
result_dy += dy00*t0*u0;
|
|
358
|
+
result_dy += 2*(-3*d00 + 3*d01 - 2*dy00 - dy01)*t0*u1;
|
|
359
|
+
result_dy += 3*(2*d00-2*d01 + dy00 + dy01)*t0*u2;
|
|
360
|
+
result_dy += dxy00*t1*u0;
|
|
361
|
+
result_dy += 2*(-3*dx00 + 3*dx01 - 2*dxy00 - dxy01)*t1*u1;
|
|
362
|
+
result_dy += 3*(2*dx00 - 2*dx01 + dxy00 + dxy01)*t1*u2;
|
|
363
|
+
result_dy += (-3*dy00 + 3*dy10 - 2*dxy00 - dxy10)*t2*u0;
|
|
364
|
+
result_dy += 2*(9*d00 - 9*d10 + 9*d11 - 9*d01 + 6*dx00 + 3*dx10 - 3*dx11 - 6*dx01 + 6*dy00 - 6*dy10 - 3*dy11 + 3*dy01 + 4*dxy00 + 2*dxy10 + dxy11 + 2*dxy01)*t2*u1;
|
|
365
|
+
result_dy += 3*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 4*dx00 - 2*dx10 + 2*dx11 + 4*dx01 - 3*dy00 + 3*dy10 + 3*dy11 - 3*dy01 - 2*dxy00 - dxy10 - dxy11 - 2*dxy01)*t2*u2;
|
|
366
|
+
result_dy += (2*dy00 - 2*dy10 + dxy00 + dxy10)*t3*u0;
|
|
367
|
+
result_dy += 2*(-6*d00 + 6*d10 - 6*d11 + 6*d01 - 3*dx00 - 3*dx10 + 3*dx11 + 3*dx01 - 4*dy00 + 4*dy10 + 2*dy11 - 2*dy01 - 2*dxy00 - 2*dxy10 - dxy11 - dxy01)*t3*u1;
|
|
368
|
+
result_dy += 3*(4*d00 - 4*d10 + 4*d11 - 4*d01 + 2*dx00 + 2*dx10 - 2*dx11 - 2*dx01 + 2*dy00 - 2*dy10 - 2*dy11 + 2*dy01 + dxy00 + dxy10 + dxy11 + dxy01)*t3*u2;
|
|
369
|
+
|
|
370
|
+
return {result, result_dx, result_dy};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
inline void Interpolator::coeff_calc(std::vector<double> &tridiag_solution, double dy, double dx, size_t i, double *b, double *c, double *d) {
|
|
377
|
+
|
|
378
|
+
const double s_i = tridiag_solution[i];
|
|
379
|
+
const double s_ip1 = tridiag_solution[i + 1];
|
|
380
|
+
const double dx_inv = 1.0 / dx;
|
|
381
|
+
|
|
382
|
+
*b = (dy*dx_inv) - dx*(s_ip1 + 2.0*s_i) / 3.0;
|
|
383
|
+
*c = s_i;
|
|
384
|
+
*d = (s_ip1 - s_i) / (3.0*dx);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
inline void Interpolator::index_lookup_xy(const int ss_x, const int ss_y, size_t &xi, size_t &yi, const double subpx_x, const double subpx_y) const {
|
|
389
|
+
|
|
390
|
+
if (subpx_x < px_x[0])
|
|
391
|
+
xi = 0;
|
|
392
|
+
else if (subpx_x > px_x[px_hori - 2])
|
|
393
|
+
xi = px_hori - 2;
|
|
394
|
+
else
|
|
395
|
+
xi = static_cast<size_t>(subpx_x);
|
|
396
|
+
|
|
397
|
+
if (subpx_y < px_y[0])
|
|
398
|
+
yi = 0;
|
|
399
|
+
else if (subpx_y > px_y[px_vert - 2])
|
|
400
|
+
yi = px_vert - 2;
|
|
401
|
+
else
|
|
402
|
+
yi = static_cast<size_t>(subpx_y);
|
|
403
|
+
|
|
404
|
+
//if (subpx_x >= px_x[0] && subpx_x <= px_x[px_hori-1]) {
|
|
405
|
+
// xi = static_cast<size_t>(subpx_x); // Return x as the index
|
|
406
|
+
//}
|
|
407
|
+
//else {
|
|
408
|
+
// std::cerr << "ERROR in \'" << __FILE__ << "\' at line \'" << __LINE__ << "\' \n";
|
|
409
|
+
// std::cerr << "Interpolator went out of bounds for subset (" << ss_x << ", " << ss_y << ")" << std::endl;
|
|
410
|
+
// std::cerr << "value is out of bounds: (" << subpx_x << ", " << subpx_y << ")" << std::endl;
|
|
411
|
+
// std::cerr << "Image bounds: (0,0) to (" << px_hori-1 << ", " << px_vert-1 << ")" << std::endl;
|
|
412
|
+
// exit(EXIT_FAILURE);
|
|
413
|
+
//}
|
|
414
|
+
|
|
415
|
+
//if (subpx_y >= px_y[0] && subpx_y <= px_y[px_vert-1]) {
|
|
416
|
+
// yi = static_cast<size_t>(subpx_y); // Return x as the index
|
|
417
|
+
//}
|
|
418
|
+
//else {
|
|
419
|
+
// std::cerr << "ERROR in \'" << __FILE__ << "\' at line \'" << __LINE__ << "\' \n";
|
|
420
|
+
// std::cerr << "Interpolator went out of bounds for subset (" << ss_x << ", " << ss_y << ")" << std::endl;
|
|
421
|
+
// std::cerr << "value is out of bounds: (" << subpx_x << ", " << subpx_y << ")" << std::endl;
|
|
422
|
+
// std::cerr << "Image bounds: (0,0) to (" << px_hori-1 << ", " << px_vert-1 << ")" << std::endl;
|
|
423
|
+
// exit(EXIT_FAILURE);
|
|
424
|
+
//}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
inline int Interpolator::index_lookup(const std::vector<double> &px, double x) const {
|
|
429
|
+
|
|
430
|
+
// Clamp coordinates to valid range
|
|
431
|
+
// double clamped_x = std::max(static_cast<double>(index_lo), std::min(static_cast<double>(index_hi), x));
|
|
432
|
+
|
|
433
|
+
// if (x >= px[index_lo] && x <= px[index_hi]) {
|
|
434
|
+
// // return static_cast<int>(x); // Return x as the index
|
|
435
|
+
// }
|
|
436
|
+
// else {
|
|
437
|
+
// // std::cout << "ERROR in \'" << __FILE__ << "\' at line \'" << __LINE__ << "\' \n";
|
|
438
|
+
// // std::cout << "value is out of bounds. value = " << x << std::endl;
|
|
439
|
+
// // exit(EXIT_FAILURE);
|
|
440
|
+
// }
|
|
441
|
+
// return static_cast<int>(clamped_x);
|
|
442
|
+
|
|
443
|
+
if (x >= px.front() && x <= px.back()) {
|
|
444
|
+
return static_cast<int>(x); // Return x as the index
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
std::cerr << "ERROR in \'" << __FILE__ << "\' at line \'" << __LINE__ << "\' \n";
|
|
448
|
+
std::cerr << "value is out of bounds. value = " << x << std::endl;
|
|
449
|
+
exit(EXIT_FAILURE);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
void Interpolator::cspline_init(std::vector<double> &px, std::vector<double> &data){
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
int num_points = px.size();
|
|
460
|
+
int max_index = num_points - 1;
|
|
461
|
+
int sys_size = max_index - 1;
|
|
462
|
+
|
|
463
|
+
std::vector<double> diagonal(num_points);
|
|
464
|
+
std::vector<double> off_diagonal(num_points);
|
|
465
|
+
std::vector<double> rhs(num_points);
|
|
466
|
+
tridiag_solution.resize(num_points,0.0);
|
|
467
|
+
|
|
468
|
+
for (int i = 0; i < sys_size; i++)
|
|
469
|
+
{
|
|
470
|
+
const double h_i = px[i + 1] - px[i];
|
|
471
|
+
const double h_ip1 = px[i + 2] - px[i + 1];
|
|
472
|
+
const double ydiff_i = data[i + 1] - data[i];
|
|
473
|
+
const double ydiff_ip1 = data[i + 2] - data[i + 1];
|
|
474
|
+
const double g_i = (h_i != 0.0) ? 1.0 / h_i : 0.0;
|
|
475
|
+
const double g_ip1 = (h_ip1 != 0.0) ? 1.0 / h_ip1 : 0.0;
|
|
476
|
+
off_diagonal[i] = h_ip1;
|
|
477
|
+
diagonal[i] = 2.0*(h_ip1 + h_i);
|
|
478
|
+
rhs[i] = 3.0*(ydiff_ip1*g_ip1 - ydiff_i*g_i);
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
std::vector<double> gamma(sys_size);
|
|
483
|
+
std::vector<double> alpha(sys_size);
|
|
484
|
+
std::vector<double> c(sys_size);
|
|
485
|
+
std::vector<double> z(sys_size);
|
|
486
|
+
alpha[0] = diagonal[0];
|
|
487
|
+
gamma[0] = off_diagonal[0] / alpha[0];
|
|
488
|
+
|
|
489
|
+
if (alpha[0] == 0) {
|
|
490
|
+
std::cerr << __FILE__ << " " << __LINE__ << "ERROR: div by zero" << std::endl;
|
|
491
|
+
exit(1);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
for (int i = 1; i < sys_size - 1; i++) {
|
|
495
|
+
|
|
496
|
+
alpha[i] = diagonal[i] - off_diagonal[i - 1]*gamma[i - 1];
|
|
497
|
+
gamma[i] = off_diagonal[i] / alpha[i];
|
|
498
|
+
if (alpha[i] == 0) {
|
|
499
|
+
std::cerr << __FILE__ << " " << __LINE__ << "ERROR: div by zero" << std::endl;
|
|
500
|
+
exit(1);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (sys_size > 1) {
|
|
506
|
+
alpha[sys_size - 1] = diagonal[(sys_size - 1)] - off_diagonal[(sys_size - 2)]*gamma[sys_size - 2];
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// RHS of equation
|
|
510
|
+
z[0] = rhs[0];
|
|
511
|
+
for (int i = 1; i < sys_size; i++) {
|
|
512
|
+
z[i] = rhs[i] - gamma[i - 1]*z[i - 1];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
for (int i = 0; i < sys_size; i++){
|
|
516
|
+
c[i] = z[i] / alpha[i];
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// back substitution
|
|
520
|
+
tridiag_solution[sys_size] = c[sys_size - 1];
|
|
521
|
+
if (sys_size >= 2) {
|
|
522
|
+
for (int i = sys_size - 2; i >= 0; i--) {
|
|
523
|
+
tridiag_solution[i+1] = c[i] - gamma[i]*tridiag_solution[i + 2];
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
double Interpolator::cspline_eval_deriv(std::vector<double> &px, std::vector<double> &data, double value, int length) {
|
|
529
|
+
|
|
530
|
+
// Find the interval containing the evaluation point
|
|
531
|
+
int index = index_lookup(px, value);
|
|
532
|
+
|
|
533
|
+
// Get interval boundaries
|
|
534
|
+
double px_min = px[index];
|
|
535
|
+
double px_max = px[index + 1];
|
|
536
|
+
double dx = px_max - px_min;
|
|
537
|
+
|
|
538
|
+
// Handle degenerate case where interval has zero width
|
|
539
|
+
if (dx <= 0.0) {
|
|
540
|
+
return 0.0;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Get y-values at interval endpoints
|
|
544
|
+
double y_lo = data[index];
|
|
545
|
+
double y_hi = data[index + 1];
|
|
546
|
+
double dy = y_hi - y_lo;
|
|
547
|
+
|
|
548
|
+
// Calculate distance from left endpoint
|
|
549
|
+
double delx = value - px_min;
|
|
550
|
+
|
|
551
|
+
// Calculate cubic spline coefficients for this interval
|
|
552
|
+
double b_i, c_i, d_i;
|
|
553
|
+
coeff_calc(tridiag_solution, dy, dx, index, &b_i, &c_i, &d_i);
|
|
554
|
+
|
|
555
|
+
// Evaluate derivative: dy/dx = b + 2c*delx + 3d*delx^2
|
|
556
|
+
double dydx = b_i + delx*(2.0*c_i + 3.0*d_i*delx);
|
|
557
|
+
|
|
558
|
+
return dydx;
|
|
559
|
+
}
|