/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.function;
import java.io.Serializable;
import org.apache.commons.lang.Validate;
import com.opengamma.analytics.financial.interestrate.NelsonSiegelSvennsonBondCurveModel;
import com.opengamma.analytics.util.serialization.InvokedSerializedForm;
/**
* This class defines a 1-D function that takes both its argument and
* parameters inputs into the {@link #evaluate} method. The function can also
* be converted into a 1-D function of the arguments or a 1-D function of the
* parameters.
*
* For example, assume that there is a function $f(x, \overline{a})$ defined as:
* $$
* \begin{align*}
* f(x, \overline{a}) = a_0 + a_1 x + a_2 x^2 + a_3 x^6
* \end{align*}
* $$
* The {@link #evaluate} method takes the value $x$ and the parameters
* $\overline{a}$ and returns the result. If the function is converted into a
* function of the arguments, the resulting function $g(x)$ is:
* $$
* \begin{align*}
* g(x) = a_0 + a_1 x + a_2 x^2 + a_3 x^6
* \end{align*}
* $$
* with $\overline{a}$ constant. If the function is converted into a function
* of the parameters, the resulting function $h(\overline{a})$ is:
* $$
* \begin{align*}
* h(\overline{a}) = a_0 + a_1 x + a_2 x^2 + a_3 x^6
* \end{align*}
* $$
* with $x$ constant.
*
* This class is particularly useful when trying to fit the parameters of a model (as in {@link NelsonSiegelSvennsonBondCurveModel}).
*
* @param <S> Type of arguments
* @param <T> Type of parameters
* @param <U> Type of result
*/
public abstract class ParameterizedFunction<S, T, U> implements Serializable {
/**
* @param x The value at which the function is to be evaluated
* @param parameters The parameters of the function
* @return The value of the function at <i>x</i> with the parameters as input
*/
public abstract U evaluate(S x, T parameters);
/**
* @param x The value at which the function is to be evaluated, not null
* @return A function that is always evaluated at <i>x</i> for different values of the parameters
*/
public Function1D<T, U> asFunctionOfParameters(final S x) {
Validate.notNull(x);
return new Function1D<T, U>() {
@Override
public final U evaluate(final T params) {
return ParameterizedFunction.this.evaluate(x, params);
}
public Object writeReplace() {
return new InvokedSerializedForm(ParameterizedFunction.this, "asFunctionOfParameters", x);
}
};
}
/**
* @param params The parameters for which the function is to be evaluated, not null
* @return A function that can be evaluated at different <i>x</i> with the input parameters
*/
public Function1D<S, U> asFunctionOfArguments(final T params) {
Validate.notNull(params);
return new Function1D<S, U>() {
@Override
public U evaluate(final S x) {
return ParameterizedFunction.this.evaluate(x, params);
}
public Object writeReplace() {
return new InvokedSerializedForm(ParameterizedFunction.this, "asFunctionOfArguments", params);
}
};
}
/**
* Get the number of parameters
* @return the number of parameters
*/
public abstract int getNumberOfParameters();
}