1 | /**********************************************************
|
---|
2 | *
|
---|
3 | * PolyCubicSplineFast.java
|
---|
4 | *
|
---|
5 | * Class for performing an interpolation on the tabulated
|
---|
6 | * function y = f(x1,x2, x3 .... xn) using a natural cubic splines
|
---|
7 | * Assumes second derivatives at end points = 0 (natural spines)
|
---|
8 | * Stripped down version of PolyCubicSpline - all data checks have been removed for faster running
|
---|
9 | *
|
---|
10 | *
|
---|
11 | * WRITTEN BY: Dr Michael Thomas Flanagan
|
---|
12 | *
|
---|
13 | * DATE: 4 January 2010 (Stripped down version of PolyCubicSpline: 9 June 2007 - 31 October 2009)
|
---|
14 | * UPDATES:
|
---|
15 | *
|
---|
16 | * DOCUMENTATION:
|
---|
17 | * See Michael Thomas Flanagan's Java library on-line web page:
|
---|
18 | * http://www.ee.ucl.ac.uk/~mflanaga/java/PolyCubicSplineFast.html
|
---|
19 | * http://www.ee.ucl.ac.uk/~mflanaga/java/
|
---|
20 | *
|
---|
21 | * Copyright (c) 2007 - 2010 Michael Thomas Flanagan
|
---|
22 | *
|
---|
23 | * PERMISSION TO COPY:
|
---|
24 | *
|
---|
25 | * Permission to use, copy and modify this software and its documentation for NON-COMMERCIAL purposes is granted, without fee,
|
---|
26 | * provided that an acknowledgement to the author, Dr Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies
|
---|
27 | * and associated documentation or publications.
|
---|
28 | *
|
---|
29 | * Redistributions of the source code of this source code, or parts of the source codes, must retain the above copyright notice, this list of conditions
|
---|
30 | * and the following disclaimer and requires written permission from the Michael Thomas Flanagan:
|
---|
31 | *
|
---|
32 | * Redistribution in binary form of all or parts of this class must reproduce the above copyright notice, this list of conditions and
|
---|
33 | * the following disclaimer in the documentation and/or other materials provided with the distribution and requires written permission from the Michael Thomas Flanagan:
|
---|
34 | *
|
---|
35 | * Dr Michael Thomas Flanagan makes no representations about the suitability or fitness of the software for any or for a particular purpose.
|
---|
36 | * Dr Michael Thomas Flanagan shall not be liable for any damages suffered as a result of using, modifying or distributing this software
|
---|
37 | * or its derivatives.
|
---|
38 | *
|
---|
39 | ***************************************************************************************/
|
---|
40 |
|
---|
41 |
|
---|
42 | package agents.anac.y2015.agentBuyogV2.flanagan.interpolation;
|
---|
43 |
|
---|
44 | import java.lang.reflect.Array;
|
---|
45 |
|
---|
46 | import agents.anac.y2015.agentBuyogV2.flanagan.math.Fmath;
|
---|
47 |
|
---|
48 | public class PolyCubicSplineFast{
|
---|
49 |
|
---|
50 | private int nDimensions = 0; // number of the dimensions of the tabulated points array, y=f(x1,x2,x3 . . xn), i.e. n
|
---|
51 | private Object fOfX = null; // tabulated values of y = f(x1,x2,x3 . . fn)
|
---|
52 | // as a multidimensional array of double [x1 length][x2 length] ... [xn length]
|
---|
53 | private Object xArrays = null; // The variable arrays x1, x2, x3 . . . xn
|
---|
54 | // packed as an Object as a multidimensional array of double [][]
|
---|
55 | // where xArrays[0] = array of x1 values, xArrays[1] = array of x2 values etc
|
---|
56 | private Object method = null; // interpolation method
|
---|
57 | private double[][] xArray = null; // The variable arrays x1, x2, x3 . . . xn
|
---|
58 | private double[] csArray = null; // array for final cubic spline interpolation
|
---|
59 | private PolyCubicSplineFast[] pcs = null; // array of PolyCubicSplineFasts for use with recursive step
|
---|
60 | private int dimOne = 0; // xArray dimension in a recursive step
|
---|
61 |
|
---|
62 | private double yValue = 0.0D; // returned interpolated value
|
---|
63 |
|
---|
64 |
|
---|
65 | // Constructor
|
---|
66 | public PolyCubicSplineFast(Object xArrays, Object fOfX){
|
---|
67 |
|
---|
68 | this.fOfX = Fmath.copyObject(fOfX);
|
---|
69 | this.xArrays = Fmath.copyObject(xArrays);
|
---|
70 |
|
---|
71 | // Calculate fOfX array dimension number
|
---|
72 | Object internalArrays = Fmath.copyObject(fOfX);
|
---|
73 | this.nDimensions = 1;
|
---|
74 | while(!((internalArrays = Array.get(internalArrays, 0)) instanceof Double))this.nDimensions++;
|
---|
75 |
|
---|
76 | // Repack xArrays as 2 dimensional array if entered a single dimensioned array for a simple cubic spline
|
---|
77 | if(this.xArrays instanceof double[] && this.nDimensions == 1){
|
---|
78 | double[][] xArraysTemp = new double[1][];
|
---|
79 | xArraysTemp[0] = (double[])this.xArrays;
|
---|
80 | this.xArrays = (Object)xArraysTemp;
|
---|
81 | }
|
---|
82 | else{
|
---|
83 | if(!(this.xArrays instanceof double[][]))throw new IllegalArgumentException("xArrays should be a two dimensional array of doubles");
|
---|
84 | }
|
---|
85 |
|
---|
86 | // x -arrays and their limits
|
---|
87 | this.xArray = (double[][])this.xArrays;
|
---|
88 |
|
---|
89 | // Select interpolation method
|
---|
90 | switch(this.nDimensions){
|
---|
91 | case 0: throw new IllegalArgumentException("data array must have at least one dimension");
|
---|
92 | case 1: // If fOfX is one dimensional perform simple cubic spline
|
---|
93 | CubicSplineFast cs = new CubicSplineFast(this.xArray[0], (double[])this.fOfX);
|
---|
94 | this.method = (Object)cs;
|
---|
95 | break;
|
---|
96 | case 2: // If fOfX is two dimensional perform bicubic spline
|
---|
97 | BiCubicSplineFast bcs = new BiCubicSplineFast(this.xArray[0], this.xArray[1], (double[][])this.fOfX);
|
---|
98 | this.method = (Object)bcs;
|
---|
99 | break;
|
---|
100 | default: // If fOfX is greater than four dimensional, recursively call PolyCubicSplineFast
|
---|
101 | // with, as arguments, the n1 fOfX sub-arrays, each of (number of dimensions - 1) dimensions,
|
---|
102 | // where n1 is the number of x1 variables.
|
---|
103 | Object obj = fOfX;
|
---|
104 | this.dimOne = Array.getLength(obj);
|
---|
105 | this.csArray = new double [dimOne];
|
---|
106 | double[][] newXarrays= new double[this.nDimensions-1][];
|
---|
107 | for(int i=0; i<this.nDimensions-1; i++){
|
---|
108 | newXarrays[i] = xArray[i+1];
|
---|
109 | }
|
---|
110 |
|
---|
111 | this.pcs = new PolyCubicSplineFast[dimOne];
|
---|
112 | for(int i=0; i<dimOne; i++){
|
---|
113 | Object objT = (Object)Array.get(obj, i);
|
---|
114 | this.pcs[i] = new PolyCubicSplineFast(newXarrays, objT);
|
---|
115 | }
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 |
|
---|
120 | // Interpolation method
|
---|
121 | public double interpolate(double[] unknownCoord){
|
---|
122 |
|
---|
123 | int nUnknown = unknownCoord.length;
|
---|
124 | if(nUnknown!=this.nDimensions)throw new IllegalArgumentException("Number of unknown value coordinates, " + nUnknown + ", does not equal the number of tabulated data dimensions, " + this.nDimensions);
|
---|
125 |
|
---|
126 | switch(this.nDimensions){
|
---|
127 | case 0: throw new IllegalArgumentException("data array must have at least one dimension");
|
---|
128 | case 1: // If fOfX is one dimensional perform simple cubic spline
|
---|
129 | this.yValue = ((CubicSplineFast)(this.method)).interpolate(unknownCoord[0]);
|
---|
130 | break;
|
---|
131 | case 2: // If fOfX is two dimensional perform bicubic spline
|
---|
132 | this.yValue = ((BiCubicSplineFast)(this.method)).interpolate(unknownCoord[0], unknownCoord[1]);
|
---|
133 | break;
|
---|
134 | default: // If fOfX is greater than two dimensional, recursively call PolyCubicSplineFast
|
---|
135 | // with, as arguments, the n1 fOfX sub-arrays, each of (number of dimensions - 1) dimensions,
|
---|
136 | // where n1 is the number of x1 variables.
|
---|
137 | double[] newCoord = new double[this.nDimensions-1];
|
---|
138 | for(int i=0; i<this.nDimensions-1; i++){
|
---|
139 | newCoord[i] = unknownCoord[i+1];
|
---|
140 | }
|
---|
141 | for(int i=0; i<this.dimOne; i++){
|
---|
142 | csArray[i] = pcs[i].interpolate(newCoord);
|
---|
143 | }
|
---|
144 |
|
---|
145 | // Perform simple cubic spline on the array of above returned interpolates
|
---|
146 | CubicSplineFast ncs = new CubicSplineFast(this.xArray[0], this.csArray);
|
---|
147 | this.yValue = ncs.interpolate(unknownCoord[0]);
|
---|
148 | }
|
---|
149 |
|
---|
150 | return this.yValue;
|
---|
151 | }
|
---|
152 |
|
---|
153 | }
|
---|
154 |
|
---|