/* * AbstractDevModelFunction.java * * Created on September 1, 2002, 4:07 AM */ package hep.aida.ref.function; import hep.aida.IAnnotation; import hep.aida.IFunction; import hep.aida.IRangeSet; import hep.aida.ref.Annotation; import java.util.ArrayList; /** * * @author serbo */ public abstract class AbstractDevModelFunction implements hep.aida.dev.IDevModelFunction { protected int dimension; //private int numberOfParameters; protected double[] x; protected double[] p; protected String[] varNames; protected String[] parNames; protected IAnnotation annotation; protected String codeletString; protected String title; protected IFunction function; protected ArrayList[] min; protected ArrayList[] max; private boolean providesGradient; private double[] gradient; private boolean providesParameterGradient; private double[] parameterGradient; private boolean providesNormalization; private boolean isNormalized; private boolean normalizationValid; private double normalizationAmplitude; protected IRangeSet[] rangeSet; public AbstractDevModelFunction() { init(); } public String normalizationParameter() { throw new UnsupportedOperationException("The normalizationParameter() method has not been implemented yet"); } public abstract int dimension(); public abstract int numberOfParameters(); public abstract double functionValue(double[] var); private void init() { dimension = -1; x = null; p = null; varNames = new String[] {"x0"}; parNames = new String[] {"p0"}; annotation = null; codeletString = null; function = null; min = null; max = null; gradient = null; parameterGradient = null; providesGradient = false; providesParameterGradient = false; providesNormalization = false; isNormalized = false; normalizationValid = false; normalizationAmplitude = Double.NaN; annotation = new Annotation(); rangeSet = new RangeSet[dimension]; rangeSet[0] = new RangeSet(); } public final double value(double[] var) { if (normalizationValid) return normalizationAmplitude * functionValue(var); else { normalizationAmplitude = normalizationAmplitude(); normalizationValid = true; return normalizationAmplitude * functionValue(var); } } public IAnnotation annotation() { return annotation; } public String variableName(int i) { return varNames[i]; } public String[] variableNames() { return varNames; } public String[] parameterNames() { return parNames; } public int indexOfParameter(String name) { for (int i=0; i<numberOfParameters(); i++) { if (name.equals(parNames[i])) return i; } throw new IllegalArgumentException("Function does not have variable named \"" + name + "\""); } public void setParameters(double[] params) { normalizationValid = false; for (int i=0; i<numberOfParameters(); i++) p[i] = params[i]; } public void setParameter(String name, double x) throws IllegalArgumentException { normalizationValid = false; p[indexOfParameter(name)] = x; } public double[] parameters() { return p; } public double parameter(String name) { return p[indexOfParameter(name)]; } public boolean isEqual(IFunction f) { throw new UnsupportedOperationException("This method is not implemented yet"); } public boolean providesGradient() { return providesGradient; } public double[] gradient(double[] x) { return gradient; } public String codeletString() { return codeletString; } // IDevFunction methods public void setCodeletString(String codelet) { codeletString = codelet; } public void setDimension(int dim) { dimension = dim; x = new double[dim]; if (dim != varNames.length) { varNames = new String[dim]; min = new ArrayList[dim]; max = new ArrayList[dim]; for (int i=0; i<dim; i++) { min[i] = new ArrayList(); max[i] = new ArrayList(); varNames[i] = "x" + i; } } } public void setProvidesGradient(boolean yes) { providesGradient = yes; } public boolean setVariableNames(String[] names) { if (dimension != names.length) throw new IllegalArgumentException("Number of parameters in the function (" + dimension + ") is not equal to the number of elements in array (" + names.length + ")."); for (int i=0; i<dimension; i++) { varNames[i] = names[i]; } return true; } public void setNumberOfParameters(int parnum) { p = new double[parnum]; if (parnum != parNames.length) parNames = new String[parnum]; for (int i=0; i<numberOfParameters(); i++) { parNames[i] = "p" + i; } } public boolean setParameterNames(String[] names) { if (numberOfParameters() != names.length) throw new IllegalArgumentException("Number of parameters in the function (" + numberOfParameters() + ") is not equal to the number of elements in array (" + names.length + ")."); for (int i=0; i<numberOfParameters(); i++) { parNames[i] = names[i]; } return true; } public void setAnnotation(IAnnotation ptr) { annotation = ptr; } // IModelFunction methods public boolean providesNormalization() { return providesNormalization; } public void normalize(boolean on) { if (on && !isNormalized && providesNormalization) { normalizationAmplitude = normalizationAmplitude(); isNormalized = true; } } public boolean isNormalized() { return isNormalized; } public double[] parameterGradient(double[] x) { return parameterGradient; } public boolean providesParameterGradient() { return providesParameterGradient; } public void setNormalizationRange(double rMin, double rMax, int iAxis) { normalizationValid = false; min = new ArrayList[dimension]; max = new ArrayList[dimension]; for (int i=0; i<dimension; i++) { min[i] = new ArrayList(); max[i] = new ArrayList(); } min[iAxis].add(new Double(rMin)); max[iAxis].add(new Double(rMax)); } public void includeNormalizationRange(double xMin, double xMax, int iAxis) { normalizationValid = false; min[iAxis].add(new Double(xMin)); max[iAxis].add(new Double(xMax)); } public void excludeNormalizationRange(double xMin, double xMax, int iAxis) { normalizationValid = false; } public void includeNormalizationAll(int iAxis) { normalizationValid = false; } public void excludeNormalizationAll(int iAxis) { normalizationValid = false; } public void includeNormalizationAll() { normalizationValid = false; } public void excludeNormalizationAll() { normalizationValid = false; } public IRangeSet normalizationRange(int iAxis) { return rangeSet[iAxis]; } // IDevModelFunction methods /// Fails if you try to set (NOT provides AND is_normalized). public boolean setNormalization(boolean provides, boolean is_normalized) { if (!provides && is_normalized) throw new IllegalArgumentException("Function can not be \"normalized\" and not provide normalization at the same time"); providesNormalization = provides; isNormalized = is_normalized; return true; } public void setProvidesParameterGradient(boolean yes) { providesParameterGradient = yes; } // Extra methods public final double normalizationAmplitude() { return normalizationAmplitude(min, max); } public double normalizationAmplitude(ArrayList[] xMin, ArrayList[] xMax) { return 1; } public String title() { return title; } public void setTitle(String t) { title = t; } }