Mega Code Archive

 
Categories / Java / Collections Data Structure
 

Linear Interpolation

import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; /**  * <p>Static methods for doing useful math</p><hr>  *  * @author  : $Author: brian $  * @version : $Revision: 1.1 $  *  * <hr><p><font size="-1" color="#336699"><a href="http://www.mbari.org">  * The Monterey Bay Aquarium Research Institute (MBARI)</a> provides this  * documentation and code &quot;as is&quot;, with no warranty, express or  * implied, of its quality or consistency. It is provided without support and  * without obligation on the part of MBARI to assist in its use, correction,  * modification, or enhancement. This information should not be published or  * distributed to third parties without specific written permission from  * MBARI.</font></p><br>  *  * <font size="-1" color="#336699">Copyright 2002 MBARI.<br>  * MBARI Proprietary Information. All rights reserved.</font><br><hr><br>  *  */ public class Util{     public static final double[] interpLinear(double[] x, double[] y, double[] xi) throws IllegalArgumentException {         if (x.length != y.length) {             throw new IllegalArgumentException("X and Y must be the same length");         }         if (x.length == 1) {             throw new IllegalArgumentException("X must contain more than one value");         }         double[] dx = new double[x.length - 1];         double[] dy = new double[x.length - 1];         double[] slope = new double[x.length - 1];         double[] intercept = new double[x.length - 1];         // Calculate the line equation (i.e. slope and intercept) between each point         for (int i = 0; i < x.length - 1; i++) {             dx[i] = x[i + 1] - x[i];             if (dx[i] == 0) {                 throw new IllegalArgumentException("X must be montotonic. A duplicate " + "x-value was found");             }             if (dx[i] < 0) {                 throw new IllegalArgumentException("X must be sorted");             }             dy[i] = y[i + 1] - y[i];             slope[i] = dy[i] / dx[i];             intercept[i] = y[i] - x[i] * slope[i];         }         // Perform the interpolation here         double[] yi = new double[xi.length];         for (int i = 0; i < xi.length; i++) {             if ((xi[i] > x[x.length - 1]) || (xi[i] < x[0])) {                 yi[i] = Double.NaN;             }             else {                 int loc = Arrays.binarySearch(x, xi[i]);                 if (loc < -1) {                     loc = -loc - 2;                     yi[i] = slope[loc] * xi[i] + intercept[loc];                 }                 else {                     yi[i] = y[loc];                 }             }         }         return yi;     }          public static final BigDecimal[] interpLinear(BigDecimal[] x, BigDecimal[] y, BigDecimal[] xi) {         if (x.length != y.length) {             throw new IllegalArgumentException("X and Y must be the same length");         }         if (x.length == 1) {             throw new IllegalArgumentException("X must contain more than one value");         }         BigDecimal[] dx = new BigDecimal[x.length - 1];         BigDecimal[] dy = new BigDecimal[x.length - 1];         BigDecimal[] slope = new BigDecimal[x.length - 1];         BigDecimal[] intercept = new BigDecimal[x.length - 1];         // Calculate the line equation (i.e. slope and intercept) between each point         BigInteger zero = new BigInteger("0");         BigDecimal minusOne = new BigDecimal(-1);                   for (int i = 0; i < x.length - 1; i++) {             //dx[i] = x[i + 1] - x[i];             dx[i] = x[i + 1].subtract(x[i]);             if (dx[i].equals(new BigDecimal(zero, dx[i].scale()))) {                 throw new IllegalArgumentException("X must be montotonic. A duplicate " + "x-value was found");             }             if (dx[i].signum() < 0) {                 throw new IllegalArgumentException("X must be sorted");             }             //dy[i] = y[i + 1] - y[i];             dy[i] = y[i + 1].subtract(y[i]);             //slope[i] = dy[i] / dx[i];             slope[i] = dy[i].divide(dx[i]);             //intercept[i] = y[i] - x[i] * slope[i];             intercept[i] = x[i].multiply(slope[i]).subtract(y[i]).multiply(minusOne);             //intercept[i] = y[i].subtract(x[i]).multiply(slope[i]);         }         // Perform the interpolation here         BigDecimal[] yi = new BigDecimal[xi.length];         for (int i = 0; i < xi.length; i++) {             //if ((xi[i] > x[x.length - 1]) || (xi[i] < x[0])) {             if (xi[i].compareTo(x[x.length - 1]) > 0 || xi[i].compareTo(x[0]) < 0) {                 yi[i] = null; // same as NaN             }             else {                 int loc = Arrays.binarySearch(x, xi[i]);                 if (loc < -1) {                     loc = -loc - 2;                     //yi[i] = slope[loc] * xi[i] + intercept[loc];                     yi[i] = slope[loc].multiply(xi[i]).add(intercept[loc]);                 }                 else {                     yi[i] = y[loc];                 }             }         }         return yi;     }     public static final double[] interpLinear(long[] x, double[] y, long[] xi) throws IllegalArgumentException {         double[] xd = new double[x.length];         for (int i = 0; i < x.length; i++) {             xd[i] = (double) x[i];         }         double[] xid = new double[xi.length];         for (int i = 0; i < xi.length; i++) {             xid[i] = (double) xi[i];         }         return interpLinear(xd, y, xid);     } }