/*
*ExponentialCoreNotNorm .java
*
* Created on September 6, 2002, 3:28 PM
*/
package hep.aida.ref.function;
import jas.hist.Handle;
import java.awt.Cursor;
import org.freehep.util.images.ImageHandler;
/**
*
* @author serbo
*/
/**
* Not normalised Exponential (E) distribution in the form:
* f = amplitude*exp((x-origin)/exponent) has 3 parameters
*/
public class ExponentialCoreNotNorm extends FunctionCore {
protected boolean providesNormalization;
public ExponentialCoreNotNorm(String str) {
super(1, 2, new double[] {1., 1.});
setTitle("ExponentialCoreNotNorm::"+str);
providesNormalization = false;
String[] names = new String[] { "amplitude","exponent" };
setParameterNames(names);
}
public ExponentialCoreNotNorm(String str, double[] pVal) {
super(1, 2, pVal);
setTitle("ExponentialCoreNotNorm::"+str);
providesNormalization = false;
String[] names = new String[] { "amplitude","exponent" };
setParameterNames(names);
}
// Value of the function WITHOUT Normalization factor (as if N=1)
public double functionValue(double[] var) {
return p[0]*Math.exp(var[0]*p[1]);
}
// Each concrete FunctionCore has to implement those methods that deal with Gradients and Normalization
public boolean providesGradient() { return true; }
public double[] gradient(double[] var) {
double[] tmp = new double[] {0.};
return new double[] { functionValue(var)*p[1] };
}
public boolean providesParameterGradient() { return true; }
public double[] parameterGradient(double[] var) {
double y = functionValue(var);
return new double[] { y/p[0] , y*var[0] };
}
public boolean providesNormalization() { return providesNormalization; }
public double normalizationAmplitude(double[] xMin, double[] xMax) {
throw new UnsupportedOperationException(title() + " ***** Can not calculate normalization for a not normalized function");
}
public Handle[] getHandles(double xLow, double xHigh, double yLow, double yHigh) {
Handle[] result = new Handle[2];
final double xmin = xLow;
final double xmax = xHigh;
final double ymin = yLow;
final double ymax = yHigh;
result[0] = new MyHandle(xmin, xmax, ymin, ymax)
// Reciprocal exponent
{
double tmpY = Double.NaN;
public void moveTo(double x, double y) {
tmpY = y;
double x0 = handle().getX();
double y0 = handle().getY();
if ( y != 0 ) {
p[1] = Math.log(y0/y)/(x0-x);
p[0] = y/(Math.exp(x*p[1]));
} else
p[0] = 0;
if ( ! isInPlot( x, y ) )
tmpY = Double.NaN;
notifyCoreChanged();
}
public double getY() {
if ( Double.isNaN(tmpY) ) {
calculateIntersections();
tmpY = 0.8*y0()+0.2*y1();
}
return tmpY;
}
public double getX() {
return Math.log(getY()/p[0])/p[1];
}
public Cursor cursor() {
return ImageHandler.getBestCursor("rotateCursor.png",ExponentialCoreNotNorm.class,0,0);
}
};
result[1] = new MyHandle(xmin, xmax, ymin, ymax) {
double tmpY = Double.NaN;
public void moveTo(double x, double y) {
tmpY = y;
p[1] = Math.log(y/p[0])/x;
if ( ! isInPlot( x, y ) )
tmpY = Double.NaN;
notifyCoreChanged();
}
public double getY() {
if ( Double.isNaN(tmpY) ) {
calculateIntersections();
tmpY = 0.2*y0()+0.8*y1();
}
return tmpY;
}
public double getX() {
return Math.log(getY()/p[0])/p[1];
}
public Cursor cursor() {
return ImageHandler.getBestCursor("moveCursor.png",ExponentialCoreNotNorm.class,0,0);
}
};
((MyHandle) result[0]).setHandle( result[1] );
return result;
}
private abstract class MyHandle extends Handle {
private Handle handle = null;
double x0, y0, x1, y1;
double xmin, xmax, ymin, ymax;
MyHandle( double xmin, double xmax, double ymin, double ymax ) {
super();
this.xmin = xmin;
this.xmax = xmax;
this.ymin = ymin;
this.ymax = ymax;
calculateIntersections();
}
void setHandle( Handle handle ) {
this.handle = handle;
}
Handle handle() {
return handle;
}
boolean isInPlot(double x, double y) {
if ( x > xmax || x < xmin )
return false;
if ( y > ymax || y < ymin )
return false;
return true;
}
void calculateIntersections() {
x0 = xmin;
y0 = p[0]*Math.exp(x0*p[1]);
if ( y0 > ymax )
y0 = ymax;
if ( y0 < ymin )
y0 = ymin;
x0 = Math.log(y0/p[0])/p[1];
x1 = xmax;
y1 = p[0]*Math.exp(x1*p[1]);
if ( y1 > ymax )
y1 = ymax;
if ( y1 < ymin )
y1 = ymin;
x1 = Math.log(y1/p[0])/p[1];
}
double x0() {
return x0;
}
double x1() {
return x1;
}
double y0() {
return y0;
}
double y1() {
return y1;
}
}
}