Print

Print


Commit in lcsim/src/org/lcsim/math/interpolation on MAIN
BilinearInterpolator.java+134added 1.1
Class to provide bilinear interpolation.

lcsim/src/org/lcsim/math/interpolation
BilinearInterpolator.java added at 1.1
diff -N BilinearInterpolator.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ BilinearInterpolator.java	4 Jun 2008 05:16:09 -0000	1.1
@@ -0,0 +1,134 @@
+/*
+ * BilinearInterpolator.java
+ *
+ * Created on June 3, 2008, 4:04 PM
+ *
+ * $Id: BilinearInterpolator.java,v 1.1 2008/06/04 05:16:09 ngraf Exp $
+ */
+//
+package org.lcsim.math.interpolation;
+
+import static java.lang.Math.abs;
+
+/**
+ * A class to provide interpolated values for values determined at discrete points 
+ * on a 2D grid
+ *
+ * @author Norman Graf
+ */
+public class BilinearInterpolator
+{
+    private double[] _x;
+    private double[] _y;
+    private double[][] _val;
+    /**
+     * Creates a new instance of BilinearInterpolator
+     * @param x Array of first independent variable at which values are known
+     * @param y Array of second independent variable at which values are known
+     * @param z Array of values at the (x,y) points
+     */
+    public BilinearInterpolator(double[] x, double[] y, double[][] z)
+    {
+        _x = x;
+        _y = y;
+        _val = z;
+    }
+    
+    //TODO add protection for values out of range
+    /**
+     * Return the value at an arbitrary x,y point, using bilinear interpolation
+     * @param x the first independent variable
+     * @param y the second independent variable
+     * @return the interpolated value at (x,y)
+     */
+    public double interpolateValueAt(double x, double y)
+    {
+        return polin2(_x, _y, _val, x, y);
+    }
+    
+    /*
+     * Given arrays x1a[1..m] and x2a[1..n] of independent variables, and a submatrix of function
+     *  values ya[1..m][1..n], tabulated at the grid points defined by x1a and x2a; and given values
+     * x1 and x2 of the independent variables; this routine returns an interpolated function value y.
+     */
+    double  polin2(double[] x1a, double[] x2a, double[][] ya, double x1, double x2)
+    {
+        int m = x1a.length;
+        int n = x2a.length;
+        double[] ymtmp = new double[m];
+        double[] yntmp = new double[n];
+        for (int j=0; j<m; ++j) //Loop over rows.
+        {
+            // copy the row into temporary storage
+            for(int k = 0; k<n; ++k)
+            {
+                yntmp[k] = ya[j][k];
+            }
+            ymtmp[j] = polint(x2a, yntmp, x2 ); //Interpolate answer into temporary storage.
+        }
+        return polint(x1a, ymtmp, x1); //Do the final interpolation.
+    }
+    
+    /*
+     * Given arrays xa[1..n] and ya[1..n], and given a value x, this routine returns a value y.
+     * If P(x) is the polynomial of degree N -1 such that P(xai) = ya,  i ; i = 1... n, then
+     * the returned value y = P(x).
+     */
+    double polint( double[] xa, double[] ya, double x)
+    {
+        int ns=0;
+        int n = xa.length;
+        double den,dif,dift,ho,hp,w;
+        double dy;
+        double[] c = new double[n];
+        double[] d = new double[n];
+        dif=abs(x-xa[1]);
+        
+        for (int i=0;i<n;++i)
+        {	//Here we find the index ns of the closest table entry,
+            dift = abs(x-xa[i]);
+            if ( dift < dif)
+            {
+                ns=i;
+                dif=dift;
+            }
+            c[i]=ya[i];	// and initialize the table of c's and d's.
+            d[i]=ya[i];
+        }
+        double y = ya[ns];	// This is the initial approximation to y.
+        ns = ns-1;
+        for (int m=1; m<n ; ++m)
+        {
+            //For each column of the table,
+            for (int i=0; i<n-m;++i)
+            {	//we loop over the current c's and d's and update them.
+                ho=xa[i]-x;
+                hp=xa[i+m]-x;
+                w=c[i+1]-d[i];
+                den = ho-hp;
+                if (den == 0.0) System.err.println("Error in routine polint");
+                //This error can occur only if two input xa's are (to within roundo) identical.
+                den=w/den;
+                d[i]=hp*den;	//Here the c's and d's are updated.
+                c[i]=ho*den;
+            }
+            if(2*ns < (n-m))
+            {
+                dy = c[ns+1];
+            }
+            else
+            {
+                dy = d[ns];
+                ns = ns-1;
+            }
+            y += dy;
+            //After each column in the tableau is completed, we decide which correction, c or d,
+            //we want to add to our accumulating value of y, i.e., which path to take through the
+            //tableau|forking up or down. We do this in such a way as to take the most \straight
+            //line" route through the tableau to its apex, updating ns accordingly to keep track of
+            //where we are. This route keeps the partial approximations centered (insofar as possible)
+            //on the target x. The last dy added is thus the error indication.
+        }
+        return y;
+    }
+}
\ No newline at end of file
CVSspam 0.2.8