source: src/main/java/agents/anac/y2015/agentBuyogV2/flanagan/interpolation/TriCubicSpline.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 13.3 KB
Line 
1/**********************************************************
2*
3* TriCubicSpline.java
4*
5* Class for performing an interpolation on the tabulated
6* function y = f(x1,x2,x3) using a natural tricubic spline
7* Assumes second derivatives at end points = 0 (natural spine)
8*
9* WRITTEN BY: Dr Michael Thomas Flanagan
10*
11* DATE: May 2002
12* UPDATE: 20 May 2003, 17 February 2006, 27 July 2007, 4 December 2007, 31 October 2009, 5 January 2011
13*
14* DOCUMENTATION:
15* See Michael Thomas Flanagan's Java library on-line web page:
16* http://www.ee.ucl.ac.uk/~mflanaga/java/TriCubicSpline.html
17* http://www.ee.ucl.ac.uk/~mflanaga/java/
18*
19* Copyright (c) 2003 - 2011 Michael Thomas Flanagan
20*
21* PERMISSION TO COPY:
22* Permission to use, copy and modify this software and its documentation for
23* NON-COMMERCIAL purposes is granted, without fee, provided that an acknowledgement
24* to the author, Michael Thomas Flanagan at http:\\www.ee.ucl.ac.uk/~mflanaga, appears in all copies.
25*
26* Dr Michael Thomas Flanagan makes no representations about the suitability
27* or fitness of the software for any or for a particular purpose.
28* Michael Thomas Flanagan shall not be liable for any damages suffered
29* as a result of using, modifying or distributing this software or its derivatives.
30*
31***************************************************************************************/
32
33package agents.anac.y2015.agentBuyogV2.flanagan.interpolation;
34
35import agents.anac.y2015.agentBuyogV2.flanagan.math.Fmath;
36
37public class TriCubicSpline{
38
39 private int nPoints = 0; // no. of x1 tabulated points
40 private int mPoints = 0; // no. of x2 tabulated points
41 private int lPoints = 0; // no. of x3 tabulated points
42 private double[][][] y = null; // y=f(x1,x2) tabulated function
43 private double[] x1 = null; // x1 in tabulated function f(x1,x2,x3)
44 private double[] x2 = null; // x2 in tabulated function f(x1,x2,x3)
45 private double[] x3 = null; // x3 in tabulated function f(x1,x2,x3)
46 private double[] xMin = new double[3]; // minimum values of x1, x2 and x3
47 private double[] xMax = new double[3]; // maximum values of x1, x2 and x3
48 private BiCubicSpline[] bcsn = null; // nPoints array of BiCubicSpline instances
49 private CubicSpline csm = null; // CubicSpline instance
50 private double[][][] d2ydx2inner = null; // inner matrix of second derivatives
51 private boolean derivCalculated = false; // = true when the called bicubic spline derivatives have been calculated
52 private boolean averageIdenticalAbscissae = false; // if true: the the ordinate values for identical abscissae are averaged
53 // If false: the abscissae values are separated by 0.001 of the total abscissae range;
54 private static double potentialRoundingError = 5e-15; // potential rounding error used in checking wheter a value lies within the interpolation bounds (static value)
55 private static boolean roundingCheck = true; // = true: points outside the interpolation bounds by less than the potential rounding error rounded to the bounds limit (static value)
56
57
58 // Constructor
59 public TriCubicSpline(double[] x1, double[] x2, double[] x3, double[][][] y){
60 this.nPoints=x1.length;
61 this.mPoints=x2.length;
62 this.lPoints=x3.length;
63 if(this.nPoints!=y.length)throw new IllegalArgumentException("Arrays x1 and y-row are of different length " + this.nPoints + " " + y.length);
64 if(this.mPoints!=y[0].length)throw new IllegalArgumentException("Arrays x2 and y-column are of different length "+ this.mPoints + " " + y[0].length);
65 if(this.lPoints!=y[0][0].length)throw new IllegalArgumentException("Arrays x3 and y-column are of different length "+ this.mPoints + " " + y[0][0].length);
66 if(this.nPoints<3 || this.mPoints<3 || this.lPoints<3)throw new IllegalArgumentException("The tabulated 3D array must have a minimum size of 3 X 3 X 3");
67
68 this.csm = new CubicSpline(this.nPoints);
69 this.bcsn = BiCubicSpline.oneDarray(this.nPoints, this.mPoints, this.lPoints);
70 this.x1 = new double[this.nPoints];
71 this.x2 = new double[this.mPoints];
72 this.x3 = new double[this.lPoints];
73 this.y = new double[this.nPoints][this.mPoints][this.lPoints];
74 this.d2ydx2inner = new double[this.nPoints][this.mPoints][this.lPoints];
75 for(int i=0; i<this.nPoints; i++){
76 this.x1[i]=x1[i];
77 }
78 this.xMin[0] = Fmath.minimum(this.x1);
79 this.xMax[0] = Fmath.maximum(this.x1);
80 for(int j=0; j<this.mPoints; j++){
81 this.x2[j]=x2[j];
82 }
83 this.xMin[1] = Fmath.minimum(this.x2);
84 this.xMax[1] = Fmath.maximum(this.x2);
85 for(int j=0; j<this.lPoints; j++){
86 this.x3[j]=x3[j];
87 }
88 this.xMin[2] = Fmath.minimum(this.x3);
89 this.xMax[2] = Fmath.maximum(this.x3);
90 for(int i =0; i<this.nPoints; i++){
91 for(int j=0; j<this.mPoints; j++){
92 for(int k=0; k<this.lPoints; k++){
93 this.y[i][j][k]=y[i][j][k];
94 }
95 }
96 }
97
98 double[][] yTempml = new double[this.mPoints][this.lPoints];
99 for(int i=0; i<this.nPoints; i++){
100
101 for(int j=0; j<this.mPoints; j++){
102 for(int k=0; k<this.lPoints; k++){
103 yTempml[j][k]=y[i][j][k];
104 }
105 }
106 this.bcsn[i].resetData(x2,x3,yTempml);
107 this.d2ydx2inner[i] = this.bcsn[i].getDeriv();
108 }
109 derivCalculated = true;
110 }
111
112 // Constructor with data arrays initialised to zero
113 // Primarily for use by QuadriCubicSpline
114 public TriCubicSpline(int nP, int mP, int lP){
115 this.nPoints=nP;
116 this.mPoints=mP;
117 this.lPoints=lP;
118 if(this.nPoints<3 || this.mPoints<3 || this.lPoints<3)throw new IllegalArgumentException("The data matrix must have a minimum size of 3 X 3 X 3");
119
120 this.csm = new CubicSpline(this.nPoints);
121 this.bcsn = BiCubicSpline.oneDarray(this.nPoints, this.mPoints, this.lPoints);
122 this.x1 = new double[this.nPoints];
123 this.x2 = new double[this.mPoints];
124 this.x3 = new double[this.lPoints];
125 this.y = new double[this.nPoints][this.mPoints][this.lPoints];
126 this.d2ydx2inner = new double[this.nPoints][this.mPoints][this.lPoints];
127 }
128
129 // METHODS
130
131 // Reset rounding error check option
132 // Default option: points outside the interpolation bounds by less than the potential rounding error rounded to the bounds limit
133 // This method causes this check to be ignored and an exception to be thrown if any point lies outside the interpolation bounds
134 public static void noRoundingErrorCheck(){
135 TriCubicSpline.roundingCheck = false;
136 BiCubicSpline.noRoundingErrorCheck();
137 CubicSpline.noRoundingErrorCheck();
138 }
139
140 // Reset potential rounding error value
141 // Default option: points outside the interpolation bounds by less than the potential rounding error rounded to the bounds limit
142 // The default value for the potential rounding error is 5e-15*times the 10^exponent of the value outside the bounds
143 // This method allows the 5e-15 to be reset
144 public static void potentialRoundingError(double potentialRoundingError){
145 TriCubicSpline.potentialRoundingError = potentialRoundingError;
146 BiCubicSpline.potentialRoundingError(potentialRoundingError);
147 CubicSpline.potentialRoundingError(potentialRoundingError);
148 }
149
150 // Reset the default handing of identical abscissae with different ordinates
151 // from the default option of separating the two relevant abscissae by 0.001 of the range
152 // to avraging the relevant ordinates
153 public void averageIdenticalAbscissae(){
154 this.averageIdenticalAbscissae = true;
155 for(int i=0; i<this.bcsn.length; i++)this.bcsn[i].averageIdenticalAbscissae();
156 this.csm.averageIdenticalAbscissae();
157 }
158
159 // Returns a new TriCubicSpline setting internal array size to nP x mP x lP and all array values to zero with natural spline default
160 // Primarily for use in this.oneDarray for QuadriCubicSpline
161 public static TriCubicSpline zero(int nP, int mP, int lP){
162 if(nP<3 || mP<3 || lP<3)throw new IllegalArgumentException("A minimum of three x three x three data points is needed");
163 TriCubicSpline aa = new TriCubicSpline(nP, mP, lP);
164 return aa;
165 }
166
167 // Create a one dimensional array of TriCubicSpline objects of length nP each of internal array size mP x lP xkP
168 // Primarily for use in quadriCubicSpline
169 public static TriCubicSpline[] oneDarray(int nP, int mP, int lP, int kP){
170 if(mP<3 || lP<3 || kP<3)throw new IllegalArgumentException("A minimum of three x three x three data points is needed");
171 TriCubicSpline[] a = new TriCubicSpline[nP];
172 for(int i=0; i<nP; i++){
173 a[i]=TriCubicSpline.zero(mP, lP, kP);
174 }
175 return a;
176 }
177
178
179 // Resets the x1, x2, x3, y data arrays
180 // Primarily for use in QuadriCubicSpline
181 public void resetData(double[] x1, double[] x2, double[] x3, double[][][] y){
182 if(x1.length!=y.length)throw new IllegalArgumentException("Arrays x1 and y row are of different length");
183 if(x2.length!=y[0].length)throw new IllegalArgumentException("Arrays x2 and y column are of different length");
184 if(x3.length!=y[0][0].length)throw new IllegalArgumentException("Arrays x3 and y column are of different length");
185 if(this.nPoints!=x1.length)throw new IllegalArgumentException("Original array length not matched by new array length");
186 if(this.mPoints!=x2.length)throw new IllegalArgumentException("Original array length not matched by new array length");
187 if(this.lPoints!=x3.length)throw new IllegalArgumentException("Original array length not matched by new array length");
188
189 for(int i=0; i<this.nPoints; i++){
190 this.x1[i]=x1[i];
191 }
192 this.xMin[0] = Fmath.minimum(this.x1);
193 this.xMax[0] = Fmath.maximum(this.x1);
194
195 for(int i=0; i<this.mPoints; i++){
196 this.x2[i]=x2[i];
197 }
198 this.xMin[1] = Fmath.minimum(this.x2);
199 this.xMax[1] = Fmath.maximum(this.x2);
200
201 for(int i=0; i<this.lPoints; i++){
202 this.x3[i]=x3[i];
203 }
204 this.xMin[2] = Fmath.minimum(this.x3);
205 this.xMax[2] = Fmath.maximum(this.x3);
206
207 for(int i=0; i<this.nPoints; i++){
208 for(int j=0; j<this.mPoints; j++){
209 for(int k=0; k<this.lPoints; k++){
210 this.y[i][j][k]=y[i][j][k];
211 }
212 }
213 }
214
215 this.csm = new CubicSpline(this.nPoints);
216 this.bcsn = BiCubicSpline.oneDarray(this.nPoints, this.mPoints, this.lPoints);
217 double[][] yTempml = new double[this.mPoints][this.lPoints];
218 for(int i=0; i<this.nPoints; i++){
219
220 for(int j=0; j<this.mPoints; j++){
221 for(int k=0; k<this.lPoints; k++){
222 yTempml[j][k]=y[i][j][k];
223 }
224 }
225 this.bcsn[i].resetData(x2,x3,yTempml);
226 this.d2ydx2inner[i] = this.bcsn[i].getDeriv();
227 }
228 derivCalculated = true;
229 }
230
231 // Get minimum limits
232 public double[] getXmin(){
233 return this.xMin;
234 }
235
236 // Get maximum limits
237 public double[] getXmax(){
238 return this.xMax;
239 }
240
241 // Get limits to x
242 public double[] getLimits(){
243 double[] limits = {xMin[0], xMax[0], xMin[1], xMax[1], xMin[2], xMax[2]};
244 return limits;
245 }
246
247 // Display limits to x
248 public void displayLimits(){
249 System.out.println(" ");
250 for(int i=0; i<3; i++){
251 System.out.println("The limits to the x array " + i + " are " + xMin[i] + " and " + xMax[i]);
252 }
253 System.out.println(" ");
254 }
255
256 // Returns an interpolated value of y for values of x1, x2 and x3
257 // from a tabulated function y=f(x1,x2,x3)
258 public double interpolate(double xx1, double xx2, double xx3){
259
260 double[] yTempm = new double[nPoints];
261
262 for (int i=0;i<nPoints;i++){
263 yTempm[i]=this.bcsn[i].interpolate(xx2, xx3);
264 }
265
266 this.csm.resetData(x1,yTempm);
267 return this.csm.interpolate(xx1);
268 }
269
270 // Get inner matrix of derivatives
271 // Primarily used by QuadriCubicSpline
272 public double[][][] getDeriv(){
273 return this.d2ydx2inner;
274 }
275
276 // Set inner matrix of derivatives
277 // Primarily used by QuadriCubicSpline
278 public void setDeriv(double[][][] d2ydx2){
279 this.d2ydx2inner = d2ydx2;
280 this.derivCalculated = true;
281 }
282}
283
Note: See TracBrowser for help on using the repository browser.