edu.mines.jtk.interp.PolyTrend2 Maven / Gradle / Ivy
Show all versions of edu-mines-jtk Show documentation
/****************************************************************************
Copyright 2010, Colorado School of Mines and others.
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.
****************************************************************************/
package edu.mines.jtk.interp;
import edu.mines.jtk.la.DMatrix;
import edu.mines.jtk.la.DMatrixQrd;
import edu.mines.jtk.dsp.Sampling;
import edu.mines.jtk.util.Check;
/**
* A low-order polynomial trend in scattered data f(x1,x2).
* The trend is computed by least-squares fitting of the scattered
* data values. This class enables the computed trend to be easily
* removed from scattered data and restored to interpolated data.
* @author Dave Hale, Colorado School of Mines
* @version 2010.01.17
*/
public class PolyTrend2 {
/**
* Constructs a trend with specified scattered samples.
* The specified arrays are referenced; not copied.
*
* If insufficient samples are available for the specified order,
* then a fit is performed with a polynomial of lower order than
* that specified. Note that an order zero (constant) polynomial
* fit is always possible when at least one sample is specified.
* @param order order of polynomial; must be 0, 1, or 2.
* @param f array of sample values f(x1,x2).
* @param x1 array of sample x1 coordinates.
* @param x2 array of sample x2 coordinates.
*/
public PolyTrend2(int order, float[] f, float[] x1, float[] x2) {
Check.argument(0<=order,"0<=order");
Check.argument(order<=2,"order<=2");
_order = order;
setSamples(f,x1,x2);
}
/**
* Sets the known (scattered) samples to be fit.
* The specified arrays are referenced, not copied.
* @param f array of sample values f(x1,x2).
* @param x1 array of sample x1 coordinates.
* @param x2 array of sample x2 coordinates.
*/
public void setSamples(float[] f, float[] x1, float[] x2) {
_n = f.length;
_f = f;
_x1 = x1;
_x2 = x2;
if (_order>0)
initCenter();
if (_order==2 && _n>=6) {
initOrder2();
} else if (_order==1 && _n>=3) {
initOrder1();
} else {
initOrder0();
}
}
/**
* Removes this trend from its referenced scattered sample values.
* Modifies values in the array f referenced by this trend.
* @throws IllegalStateException if the trend has already been removed.
*/
public void detrend() {
Check.state(!_detrend,"trend not yet removed");
detrend(_f,_x1,_x2);
_detrend = true;
}
/**
* Restores this trend to its referenced scattered sample valuess.
* Modifies values in the array f referenced by this trend.
* @throws IllegalStateException if the trend has not yet been removed.
*/
public void restore() {
Check.state(_detrend,"trend has been removed");
restore(_f,_x1,_x2);
_detrend = false;
}
/**
* Removes this trend from the specified sample.
* @param f the sample value.
* @param x1 the sample x1 coordinate.
* @param x2 the sample x2 coordinate.
* @return the sample value with trend removed.
*/
public float detrend(float f, float x1, float x2) {
double fi = f-_f0;
if (_order>0) {
double y1 = x1-_x1c;
double y2 = x2-_x2c;
fi -= _f1*y1+_f2*y2;
if (_order>1) {
double y11 = y1*y1;
double y12 = y1*y2;
double y22 = y2*y2;
fi -= _f11*y11+_f12*y12+_f22*y22;
}
}
return (float)fi;
}
/**
* Restores this trend to the specified sample.
* @param f the sample value.
* @param x1 the sample x1 coordinate.
* @param x2 the sample x2 coordinate.
* @return the sample value with trend restored.
*/
public float restore(float f, float x1, float x2) {
double fi = f+_f0;
if (_order>0) {
double y1 = x1-_x1c;
double y2 = x2-_x2c;
fi += _f1*y1+_f2*y2;
if (_order>1) {
double y11 = y1*y1;
double y12 = y1*y2;
double y22 = y2*y2;
fi += _f11*y11+_f12*y12+_f22*y22;
}
}
return (float)fi;
}
/**
* Removes this trend from the specified samples.
* @param f array of sample values to be detrended.
* @param x1 array of sample x1 coordinates.
* @param x2 array of sample x2 coordinates.
*/
public void detrend(float[] f, float[] x1, float[] x2) {
int n = f.length;
for (int i=0; i