Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added LINEARFIT SPLINELINEARFIT AKIMASPLINEFIT #1

Merged
merged 32 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
49c0b27
added LINEARFIT SPLINELINEARFIT AKIMASPLINEFIT
pi-r-p Sep 9, 2022
03e85ee
added small grid for 2D and 3D interpolator
pi-r-p Sep 13, 2022
05ca4ba
fix style
randomboolean Sep 26, 2023
980871d
update build
randomboolean Sep 26, 2023
2ff6a7e
year
randomboolean Sep 26, 2023
c23d23a
comment
randomboolean Sep 26, 2023
f5a5b60
renaming
randomboolean Sep 26, 2023
b5dddb4
style
randomboolean Sep 26, 2023
0f6f04b
style
randomboolean Sep 26, 2023
3ce8307
renaming
randomboolean Sep 26, 2023
92b0966
nit
randomboolean Sep 26, 2023
4a5c706
mention source and describe changes
randomboolean Sep 26, 2023
5f9c94e
style
randomboolean Sep 26, 2023
61d420b
tick instead of max long
randomboolean Sep 26, 2023
92ee804
year
randomboolean Sep 26, 2023
67ed91a
style
randomboolean Sep 26, 2023
d3ce715
precision
randomboolean Sep 26, 2023
1b86458
renaming
randomboolean Sep 26, 2023
cb3cc07
style
randomboolean Sep 26, 2023
4eafd73
test
randomboolean Sep 26, 2023
d93cb95
simplifies boundaries treatment in bicubic case
randomboolean Sep 26, 2023
7f33429
simplifies boundaries treatment in tricubic case
randomboolean Sep 26, 2023
7ce1241
renaming
randomboolean Sep 26, 2023
cee1adc
related
randomboolean Sep 26, 2023
88f3fb0
doc linear
randomboolean Sep 26, 2023
42609ba
doc spline
randomboolean Sep 26, 2023
4183a18
doc akima
randomboolean Sep 26, 2023
023b553
doc adjustments
randomboolean Sep 26, 2023
985bc26
readme
randomboolean Sep 26, 2023
7e8d986
doc fix
randomboolean Sep 26, 2023
4700ca3
renaming
randomboolean Sep 26, 2023
78eed46
year
randomboolean Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//
// Copyright 2022 SenX S.A.S.
//
// Licensed 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
//
// http://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.
//
// This class is a variant of org.apache.commons.math3.analysis.interpolation.BicubicInterpolator
// with local slope at the cube edges computed with current point and next point (instead of 0)
// This make the algorithm usable even with a very small input grid.


randomboolean marked this conversation as resolved.
Show resolved Hide resolved
package io.warp10.ext.interpolation;

import org.apache.commons.math3.analysis.interpolation.BicubicInterpolatingFunction;
import org.apache.commons.math3.analysis.interpolation.BivariateGridInterpolator;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.NoDataException;
import org.apache.commons.math3.exception.NonMonotonicSequenceException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.util.MathArrays;

/**
* Generates a {@link BicubicInterpolatingFunction bicubic interpolating
* function}.
* <p>
* Caveat: Because the interpolation scheme requires that derivatives be
* specified at the sample points, those are approximated with finite
* differences (using the 2-points symmetric formulae).
* Since their values are undefined at the borders of the provided
* interpolation ranges, the interpolated values will be wrong at the
* edges of the patch.
* The {@code interpolate} method will return a function that overrides
* {@link BicubicInterpolatingFunction#isValidPoint(double, double)} to
* indicate points where the interpolation will be inaccurate.
* </p>
*
* @since 3.4
*/
randomboolean marked this conversation as resolved.
Show resolved Hide resolved
public class BicubicInterpolatorSmallGrid
randomboolean marked this conversation as resolved.
Show resolved Hide resolved
implements BivariateGridInterpolator {
/**
* {@inheritDoc}
*/
public BicubicInterpolatingFunction interpolate(final double[] xval,
final double[] yval,
final double[][] fval)
throws NoDataException, DimensionMismatchException,
NonMonotonicSequenceException, NumberIsTooSmallException {
if (xval.length == 0 || yval.length == 0 || fval.length == 0) {
throw new NoDataException();
}
if (xval.length != fval.length) {
throw new DimensionMismatchException(xval.length, fval.length);
}

MathArrays.checkOrder(xval);
MathArrays.checkOrder(yval);

final int xLen = xval.length;
final int yLen = yval.length;

// Approximation to the partial derivatives using finite differences.
final double[][] dFdX = new double[xLen][yLen];
final double[][] dFdY = new double[xLen][yLen];
final double[][] d2FdXdY = new double[xLen][yLen];
for (int i = 0; i < xLen; i++) {
int nI, pI;
if (i > 0 && i < xLen - 1) {
nI = i + 1;
pI = i - 1;
} else if (i == 0) {
nI = 1;
pI = 0;
} else {
nI = xLen - 1; // i == xLen-1
pI = xLen - 2;
}
final double nX = xval[nI];
final double pX = xval[pI];

final double deltaX = nX - pX;

for (int j = 0; j < yLen; j++) {
int nJ, pJ;
if (j > 0 && j < yLen - 1) {
nJ = j + 1;
pJ = j - 1;
} else if (j == 0) {
nJ = 1;
pJ = 0;
} else {
nJ = yLen - 1; // j == yLen-1
pJ = yLen - 2;
}

final double nY = yval[nJ];
final double pY = yval[pJ];

final double deltaY = nY - pY;

dFdX[i][j] = (fval[nI][j] - fval[pI][j]) / deltaX;
dFdY[i][j] = (fval[i][nJ] - fval[i][pJ]) / deltaY;

final double deltaXY = deltaX * deltaY;

d2FdXdY[i][j] = (fval[nI][nJ] - fval[nI][pJ] - fval[pI][nJ] + fval[pI][pJ]) / deltaXY;
}
}

// Create the interpolating function.
return new BicubicInterpolatingFunction(xval, yval, fval, dFdX, dFdY, d2FdXdY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,27 @@ public class InterpolationWarpScriptExtension extends WarpScriptExtension {
// Functions
//

private static final Map<String,Object> functions;

public static final String INTERPOLATOR_ND_MICROSPHERE = "INTERPOLATOR.ND.MICROSPHERE";
public static final String INTERPOLATOR_ND_SMICROSPHERE = "INTERPOLATOR.ND.SMICROSPHERE"; // seeded
public static final String INTERPOLATOR_2_D_BICUBIC = "INTERPOLATOR.2D.BICUBIC";
public static final String INTERPOLATOR_3_D_TRICUBIC = "INTERPOLATOR.3D.TRICUBIC";
public static final String INTERPOLATOR_1_D_LINEAR = "INTERPOLATOR.1D.LINEAR";
public static final String INTERPOLATOR_1_D_SPLINE = "INTERPOLATOR.1D.SPLINE";
public static final String INTERPOLATOR_1_D_AKIMA = "INTERPOLATOR.1D.AKIMA";
randomboolean marked this conversation as resolved.
Show resolved Hide resolved

randomboolean marked this conversation as resolved.
Show resolved Hide resolved

randomboolean marked this conversation as resolved.
Show resolved Hide resolved
private static final Map<String, Object> functions;

static {
functions = new HashMap<String,Object>();

functions.put("MICROSPHEREFIT", new MICROSPHEREFIT("MICROSPHEREFIT", false));
functions.put("SMICROSPHEREFIT", new MICROSPHEREFIT("SMICROSPHEREFIT", true));
functions.put("BICUBICFIT", new BICUBICFIT("BICUBICFIT"));
functions.put("TRICUBICFIT", new TRICUBICFIT("TRICUBICFIT"));
functions = new HashMap<String, Object>();

functions.put(INTERPOLATOR_ND_MICROSPHERE, new InterpolatorMicrosphere(INTERPOLATOR_ND_MICROSPHERE, false));
functions.put(INTERPOLATOR_ND_SMICROSPHERE, new InterpolatorMicrosphere(INTERPOLATOR_ND_SMICROSPHERE, true));
functions.put(INTERPOLATOR_2_D_BICUBIC, new InterpolatorBicubic(INTERPOLATOR_2_D_BICUBIC));
functions.put(INTERPOLATOR_3_D_TRICUBIC, new InterpolatorTricubic(INTERPOLATOR_3_D_TRICUBIC));
functions.put(INTERPOLATOR_1_D_LINEAR, new InterpolatorLinear(INTERPOLATOR_1_D_LINEAR, InterpolatorLinear.TYPE.LINEAR));
functions.put(INTERPOLATOR_1_D_SPLINE, new InterpolatorLinear(INTERPOLATOR_1_D_SPLINE, InterpolatorLinear.TYPE.SPLINE));
functions.put(INTERPOLATOR_1_D_AKIMA, new InterpolatorLinear(INTERPOLATOR_1_D_AKIMA, InterpolatorLinear.TYPE.AKIMA));
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@
import io.warp10.script.WarpScriptReducerFunction;
import io.warp10.script.WarpScriptStack;
import io.warp10.script.WarpScriptStackFunction;
import org.apache.commons.math3.analysis.interpolation.BicubicInterpolatingFunction;
import org.apache.commons.math3.analysis.interpolation.BicubicInterpolator;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.math3.analysis.interpolation.BicubicInterpolatingFunction;

import java.util.List;

/**
* Function that implements the bicubic spline interpolation
*/
public class BICUBICFIT extends NamedWarpScriptFunction implements WarpScriptStackFunction {
public class InterpolatorBicubic extends NamedWarpScriptFunction implements WarpScriptStackFunction {

private static class BICUBE extends NamedWarpScriptFunction implements WarpScriptStackFunction, WarpScriptReducerFunction {

Expand All @@ -45,10 +44,10 @@ private BICUBE(BicubicInterpolatingFunction function, String interpolatorName) {
}

private double value(double x, double y) {
if (!func.isValidPoint(x,y)) {
return Double.NaN;
if (!func.isValidPoint(x, y)) {
return Double.NaN;
} else {
return func.value(x,y);
return func.value(x, y);
}
}

Expand All @@ -66,7 +65,7 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {

double x = ((Number) l.get(0)).doubleValue();
double y = ((Number) l.get(1)).doubleValue();
stack.push(value(x,y));
stack.push(value(x, y));

return stack;
}
Expand All @@ -84,9 +83,9 @@ public Object apply(Object[] args) throws WarpScriptException {

double x = ((Number) values[0]).doubleValue();
double y = ((Number) values[1]).doubleValue();
double res = value(x,y);
double res = value(x, y);

return new Object[] { tick, locations[0], elevations[0], res };
return new Object[] {tick, locations[0], elevations[0], res};
}

@Override
Expand Down Expand Up @@ -140,7 +139,7 @@ public String toString() {
}
}

public BICUBICFIT(String name) {
public InterpolatorBicubic(String name) {
super(name);
}

Expand Down Expand Up @@ -208,7 +207,7 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {
}
}

BicubicInterpolatingFunction function = (new BicubicInterpolator()).interpolate(xval, yval, fval);
BicubicInterpolatingFunction function = (new BicubicInterpolatorSmallGrid()).interpolate(xval, yval, fval);
randomboolean marked this conversation as resolved.
Show resolved Hide resolved
BICUBE warpscriptFunction = new BICUBE(function, getName());
stack.push(warpscriptFunction);

Expand Down
Loading