-
Notifications
You must be signed in to change notification settings - Fork 3
/
gdatav4.cpp
109 lines (95 loc) · 2.71 KB
/
gdatav4.cpp
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
/*************************************************
Function: gdatav4
Description: Interpolation using value or
gradient of value in any dimension.
Reference: David T. Sandwell, Biharmonic spline
interpolation of GEOS-3 and SEASAT altimeter
data, Geophtsical Research Letters, 2, 139-142,
1987.
Author:Ryan
Date:2017-08-28
*************************************************/
#include "BiharmonicSplineInterp.h"
bool gdatav4(vector<double> &x, vector<double> &y, vector<double> &v, vector<vector<double> > &xq, vector<vector<double> > &yq, vector<vector<double> > &vq)
{
// Check to make sure sizes of input arguments are correct/consistent.
if(v.size() != x.size() || v.size() != y.size())
{
printf("%s", "Length of x, y, and v must be equal!");
return false;
}
if(xq.size() != yq.size() || xq[0].size() != yq[0].size())
{
printf("%s", "Size of xq and yq must be equal!");
return false;
}
// Initialize Output.
// vector<vector<double>> vq;
vq.resize(xq.size());
for(int i = 0; i < xq.size(); i++)
vq[i].resize(xq[0].size());
for(int i = 0; i < xq.size(); i++)
for(int j = 0; j < xq[0].size(); j++)
vq[i][j] = 0.0;
vector<vector<double> > G;
G.resize(v.size());
for(int i = 0; i < v.size(); i++)
G[i].resize(v.size());
for(int i = 0; i < v.size(); i++)
for(int j = 0; j < v.size(); j++)
G[i][j] = 0.0;
double d = 0.0;
for(int i = 0; i < v.size(); i++)
{
for(int j = 0; j < v.size(); j++)
{
d = 0.0;
if(i != j)
d = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
if(d >= 1.0e-7)
G[i][j] = (d * d) * (log(d) - 1.0);//Green's function.
}
}
// Compute weights, especially G * weights = v.
vector<double> weights;
weights.resize(v.size());
//weights = G \ v;
vector<vector<double> > inverseG;
inverseG.resize(G.size());
for(int i = 0; i < G.size(); i++)
inverseG[i].resize(G[0].size());
inverse(G, inverseG);
for(int i = 0; i < inverseG.size(); i++)
{
for(int j =0; j < v.size(); j++)
weights[i] += inverseG[i][j] * v[j];
}
// Find 2D interpolated surface through irregular/regular x, y grid points
vector<double> g;
g.resize(weights.size());
for(int i = 0; i < weights.size(); i++)
g[i] = 0;
for(int i = 0; i < vq.size(); i++)
{
for(int j = 0; j < vq[0].size(); j++)
{
double sum = 0.0;
for(int k = 0; k < v.size(); k++)
{
d = 0.0;
d = sqrt((xq[i][j] - x[k]) * (xq[i][j] - x[k]) + (yq[i][j] - y[k]) * (yq[i][j] - y[k]));
if(d >= 1.0e-7)
g[k] = (d * d) * (log(d) - 1.0);//Green's function
else
g[k] = (d * d) * (-100.0); // g[k] = 0;
sum += g[k] * weights[k];
}
vq[i][j] = sum;
}
}
G.clear();
g.clear();
weights.clear();
return true;
}
/*************************************************/