/* * Copyright (C) 2010-2014 - Andreas Maier, Andreas Keil * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.conrad.data.generic; import edu.stanford.rsl.conrad.data.generic.datatypes.Gridable; /** The collection of all interpolation operators for Grids. */ public abstract class GenericInterpolationOperators<T extends Gridable<T>> { /////////////////////////////////////////////////////////////////////// // Linear interpolation of Grids // /////////////////////////////////////////////////////////////////////// protected abstract T getDefault(); /** Linear interpolation of an ND Grid */ public T interpolateLinear(final GenericGrid<T> grid, int currDim, double... idx) { int lower = (int) Math.floor(idx[currDim]); double d = idx[currDim] - lower; // d is in [0, 1) if(currDim<=0){ int[] lowIdx = new int[idx.length]; int[] highIdx = new int[idx.length]; for (int i = 1; i < highIdx.length; i++) { lowIdx[i] = (int)idx[i]; highIdx[i] = (int)idx[i]; } lowIdx[0]=lower; highIdx[0]=lower+1; return grid.getValue(lowIdx).mul(1.0-d) .add((d != 0.0) ? grid.getValue(highIdx).mul(d) : getDefault()); } double[] lowIdx = new double[idx.length]; double[] highIdx = new double[idx.length]; System.arraycopy(idx, 0, lowIdx, 0, idx.length); System.arraycopy(idx, 0, highIdx, 0, idx.length); lowIdx[currDim]=lower; highIdx[currDim]=lower+1; return interpolateLinear(grid, currDim-1, lowIdx).mul((1.0-d)) .add((d != 0.0) ? interpolateLinear(grid, currDim-1, highIdx).mul(d) : getDefault()); } /** Linear interpolation of an ND Grid */ public T interpolateLinear(final GenericGrid<T> grid, double... idx) { return interpolateLinear(grid, idx.length-1, idx); } /** Linear interpolation of an ND Grid */ public void addInterpolateLinear(final GenericGrid<T> grid, int currDim, T val, double... idx) { int lower = (int) Math.floor(idx[currDim]); double d = idx[currDim] - lower; // d is in [0, 1) if(currDim<=0){ int[] lowIdx = new int[idx.length]; int[] highIdx = new int[idx.length]; for (int i = 1; i < highIdx.length; i++) { lowIdx[i] = (int)idx[i]; highIdx[i] = (int)idx[i]; } lowIdx[0]=lower; highIdx[0]=lower+1; grid.setValue(grid.getValue(lowIdx).add(val.mul(1.0-d)),lowIdx); if (d != 0.0) grid.setValue(grid.getValue(highIdx).add(val.mul(d))); } double[] lowIdx = new double[idx.length]; double[] highIdx = new double[idx.length]; System.arraycopy(idx, 0, lowIdx, 0, idx.length); System.arraycopy(idx, 0, highIdx, 0, idx.length); lowIdx[currDim]=lower; highIdx[currDim]=lower+1; addInterpolateLinear(grid, currDim-1, val.mul((1.0-d)), lowIdx); if (d != 0.0) addInterpolateLinear(grid, currDim-1, val.mul(d),highIdx); } /** Linear extrapolation into an ND Grid */ public void addInterpolateLinear(final GenericGrid<T> grid, T val, double... idx) { addInterpolateLinear(grid, idx.length-1, val, idx); } }