CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
interpolate.cpp
Go to the documentation of this file.
1
11
12/* ===============================================================================================================================
13
14 This file is part of CoastalME, the Coastal Modelling Environment.
15
16 CoastalME 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.
17
18 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.
19
20 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22===============================================================================================================================*/
23#include <assert.h>
24#include <cfloat>
25#include <iostream>
26#include <iomanip>
27#include <vector>
28using namespace std;
29
30#include "cme.h"
31
32//===============================================================================================================================
35//===============================================================================================================================
36double dGetInterpolatedValue(vector<double> const* pVdXdata, vector<double> const* pVdYdata, double dX, bool bExtrapolate)
37{
38 int size = static_cast<int>(pVdXdata->size());
39
40 int i = 0; // Find left end of interval for interpolation
41
42 if (dX >= pVdXdata->at(size - 2)) // Special case: beyond right end
43 {
44 i = size - 2;
45 }
46
47 else
48 {
49 while (dX > pVdXdata->at(i + 1))
50 i++;
51 }
52
53 double dXL = pVdXdata->at(i);
54 double dYL = pVdYdata->at(i);
55 double dXR = pVdXdata->at(i + 1);
56 double dYR = pVdYdata->at(i + 1); // Points on either side (unless beyond ends)
57
58 if (! bExtrapolate) // If beyond ends of array and not extrapolating
59 {
60 if (dX < dXL)
61 dYR = dYL;
62
63 if (dX > dXR)
64 dYL = dYR;
65 }
66
67 double ddYdX = (dYR - dYL) / (dXR - dXL); // Gradient
68
69 return (dYL + ddYdX * (dX - dXL)); // Linear interpolation
70}
71
72//===============================================================================================================================
75//===============================================================================================================================
76double dGetInterpolatedValue(vector<int> const* pVnXdata, vector<double> const* pVdYdata, int nX, bool bExtrapolate )
77{
78 unsigned int nSize = static_cast<unsigned int>(pVnXdata->size());
79
80 int i = 0; // Find left end of interval for interpolation
81
82 if (nX >= pVnXdata->at(nSize - 2)) // Special case: beyond right end
83 {
84 i = nSize - 2;
85 }
86
87 else
88 {
89 while (nX > pVnXdata->at(i + 1))
90 i++;
91 }
92
93 int nXL = pVnXdata->at(i);
94 int nXR = pVnXdata->at(i + 1);
95
96 double dYL = pVdYdata->at(i);
97 double dYR = pVdYdata->at(i + 1); // Points on either side (unless beyond ends)
98
99 if (! bExtrapolate) // If beyond ends of array and not extrapolating
100 {
101 if (nX < nXL)
102 dYR = dYL;
103
104 if (nX > nXR)
105 dYL = dYR;
106 }
107
108 double ddYdX = (dYR - dYL) / static_cast<double>(nXR - nXL); // Gradient
109
110 return dYL + ddYdX * static_cast<double>(nX - nXL); // Linear interpolation
111}
112
113//===============================================================================================================================
115//===============================================================================================================================
116int nFindIndex(vector<double> const* pVdX, double const dValueIn)
117{
118 double dLastValue = DBL_MAX;
119 int nIndexFound = 0;
120
121 for (unsigned int i = 0; i < pVdX->size(); ++i)
122 {
123 double dThisValue = tAbs(dValueIn - pVdX->at(i));
124
125 if (dThisValue <= dLastValue)
126 {
127 dLastValue = dThisValue;
128 nIndexFound = i;
129 }
130 }
131
132 return nIndexFound;
133}
134
135//===============================================================================================================================
137//===============================================================================================================================
138vector<double> VdInterpolateCShoreProfileOutput(vector<double> const* pVdX, vector<double> const* pVdY, vector<double> const* pVdXNew)
139{
140 int nXSize = static_cast<int>(pVdX->size());
141 int nXNewSize = static_cast<int>(pVdXNew->size());
142
143 // assert(nXSize > 0);
144 // assert(nXNewSize > 0);
145
146 double dX;
147 double dY;
148 vector<double> VdYNew(nXNewSize, 0.0);
149
150 for (int i = 0; i < nXNewSize; ++i)
151 {
152 int idx = nFindIndex(pVdX, pVdXNew->at(i));
153
154 if (pVdX->at(idx) > pVdXNew->at(i))
155 {
156 if (idx > 0)
157 {
158 dX = pVdX->at(idx) - pVdX->at(idx - 1);
159 dY = pVdY->at(idx) - pVdY->at(idx - 1);
160 }
161
162 else
163 {
164 dX = pVdX->at(idx + 1) - pVdX->at(idx);
165 dY = pVdY->at(idx + 1) - pVdY->at(idx);
166 }
167 }
168
169 else
170 {
171 if (idx < nXSize - 1)
172 {
173 dX = pVdX->at(idx + 1) - pVdX->at(idx);
174 dY = pVdY->at(idx + 1) - pVdY->at(idx);
175 }
176
177 else
178 {
179 dX = pVdX->at(idx) - pVdX->at(idx - 1);
180 dY = pVdY->at(idx) - pVdY->at(idx - 1);
181 }
182 }
183
184 // Safety check: this crashes (divide by zero) if there are identical consecutive values in pVdX, and thus if dX becomes 0. To prevent this, if dX is near zero, set to a small non-zero number
185 if (bFPIsEqual(dX, 0.0, TOLERANCE))
186 dX = 1e-10;
187
188 double dM = dY / dX;
189 double dB = pVdY->at(idx) - pVdX->at(idx) * dM;
190
191 // VdYNew[i] = (pVdXNew->at(i) * dM) + dB;
192 VdYNew[nXNewSize - 1 - i] = (pVdXNew->at(i) * dM) + dB;
193 }
194
195 return VdYNew;
196}
This file contains global definitions for CoastalME.
double const TOLERANCE
Definition cme.h:811
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1284
T tAbs(T a)
Definition cme.h:1261
int nFindIndex(vector< double > const *pVdX, double const dValueIn)
This is used by VdInterpolateCShoreProfileOutput, it returns the index of the value in pVdX which is ...
vector< double > VdInterpolateCShoreProfileOutput(vector< double > const *pVdX, vector< double > const *pVdY, vector< double > const *pVdXNew)
Returns a linearly interpolated vector of doubles, to make CShore profile output compatible with CME....
double dGetInterpolatedValue(vector< double > const *pVdXdata, vector< double > const *pVdYdata, double dX, bool bExtrapolate)