BilinearInterpolatingFunction.java
- /*
- * Licensed to the Hipparchus project under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.hipparchus.analysis.interpolation;
- import java.io.Serializable;
- import org.hipparchus.CalculusFieldElement;
- import org.hipparchus.analysis.BivariateFunction;
- import org.hipparchus.analysis.FieldBivariateFunction;
- import org.hipparchus.exception.MathIllegalArgumentException;
- /**
- * Interpolate grid data using bi-linear interpolation.
- * <p>
- * This interpolator is thread-safe.
- * </p>
- * @since 1.4
- */
- public class BilinearInterpolatingFunction implements BivariateFunction, FieldBivariateFunction, Serializable {
- /** Serializable UID. */
- private static final long serialVersionUID = 20180926L;
- /** Grid along the x axis. */
- private final GridAxis xGrid;
- /** Grid along the y axis. */
- private final GridAxis yGrid;
- /** Grid size along the y axis. */
- private final int ySize;
- /** Values of the interpolation points on all the grid knots (in a flatten array). */
- private final double[] fVal;
- /** Simple constructor.
- * @param xVal All the x-coordinates of the interpolation points, sorted
- * in increasing order.
- * @param yVal All the y-coordinates of the interpolation points, sorted
- * in increasing order.
- * @param fVal The values of the interpolation points on all the grid knots:
- * {@code fVal[i][j] = f(xVal[i], yVal[j])}.
- * @exception MathIllegalArgumentException if grid size is smaller than 2
- * or if the grid is not sorted in strict increasing order
- */
- public BilinearInterpolatingFunction(final double[] xVal, final double[] yVal,
- final double[][] fVal)
- throws MathIllegalArgumentException {
- this.xGrid = new GridAxis(xVal, 2);
- this.yGrid = new GridAxis(yVal, 2);
- this.ySize = yVal.length;
- this.fVal = new double[xVal.length * ySize];
- int k = 0;
- for (int i = 0; i < xVal.length; ++i) {
- final double[] fi = fVal[i];
- for (int j = 0; j < ySize; ++j) {
- this.fVal[k++] = fi[j];
- }
- }
- }
- /** Get the lowest grid x coordinate.
- * @return lowest grid x coordinate
- */
- public double getXInf() {
- return xGrid.node(0);
- }
- /** Get the highest grid x coordinate.
- * @return highest grid x coordinate
- */
- public double getXSup() {
- return xGrid.node(xGrid.size() - 1);
- }
- /** Get the lowest grid y coordinate.
- * @return lowest grid y coordinate
- */
- public double getYInf() {
- return yGrid.node(0);
- }
- /** Get the highest grid y coordinate.
- * @return highest grid y coordinate
- */
- public double getYSup() {
- return yGrid.node(yGrid.size() - 1);
- }
- /** {@inheritDoc} */
- @Override
- public double value(final double x, final double y) {
- // get the interpolation nodes
- final int i = xGrid.interpolationIndex(x);
- final int j = yGrid.interpolationIndex(y);
- final double x0 = xGrid.node(i);
- final double x1 = xGrid.node(i + 1);
- final double y0 = yGrid.node(j);
- final double y1 = yGrid.node(j + 1);
- // get the function values at interpolation nodes
- final int k0 = i * ySize + j;
- final int k1 = k0 + ySize;
- final double z00 = fVal[k0];
- final double z01 = fVal[k0 + 1];
- final double z10 = fVal[k1];
- final double z11 = fVal[k1 + 1];
- // interpolate
- final double dx0 = x - x0;
- final double dx1 = x1 - x;
- final double dx10 = x1 - x0;
- final double dy0 = y - y0;
- final double dy1 = y1 - y;
- final double dy10 = y1 - y0;
- return (dx0 * (dy0 * z11 + dy1 * z10) + dx1 * (dy0 * z01 + dy1 * z00)) /
- (dx10 * dy10);
- }
- /** {@inheritDoc}
- * @since 1.5
- */
- @Override
- public <T extends CalculusFieldElement<T>> T value(T x, T y) {
- // get the interpolation nodes
- final int i = xGrid.interpolationIndex(x.getReal());
- final int j = yGrid.interpolationIndex(y.getReal());
- final double x0 = xGrid.node(i);
- final double x1 = xGrid.node(i + 1);
- final double y0 = yGrid.node(j);
- final double y1 = yGrid.node(j + 1);
- // get the function values at interpolation nodes
- final int k0 = i * ySize + j;
- final int k1 = k0 + ySize;
- final double z00 = fVal[k0];
- final double z01 = fVal[k0 + 1];
- final double z10 = fVal[k1];
- final double z11 = fVal[k1 + 1];
- // interpolate
- final T dx0 = x.subtract(x0);
- final T mdx1 = x.subtract(x1);
- final double dx10 = x1 - x0;
- final T dy0 = y.subtract(y0);
- final T mdy1 = y.subtract(y1);
- final double dy10 = y1 - y0;
- return dy0.multiply(z11).subtract(mdy1.multiply(z10)).multiply(dx0).
- subtract(dy0.multiply(z01).subtract(mdy1.multiply(z00)).multiply(mdx1)).
- divide(dx10 * dy10);
- }
- }