[email protected] a écrit :
> Luc
>      Thanks for your comments. I have taken the 2DCurveExponentialX as a 
> first attempt here. The basic equation is y = a + b*e^(c*x) (is the math e, 
> natural exponential function). I have written the following implementation of 
> the of the ParametricRealFunction for this, see below. Not having any 
> experience with this type a implementation I did the best I could. However, I 
> am getting this exception:
> 
> org.apache.commons.math.optimization.OptimizationException: unable to compute 
> covariances: singular problem
> I unfortunately do not have any idea what this means or how to remedy it. 
> Your help is appreciated
> 
> Thanks
> Roger
> 
> /**
>     * implementation of ParametricRealFunction clase for
>     *    y = a + be^(cx)
>     */
>    public static class TwoDCurveNaturalLogX implements ParametricRealFunction
>    {
>        /*
>         *"double[] coeffs = must include at least 1 but not more than 3 
> coefficients."
>         */
>         @Override
>         public double value(double x, double[] coeffs) throws 
> FunctionEvaluationException
>         {
>            if(coeffs == null || coeffs.length == 0 || coeffs.length > 3)
>            {
>                 if (coeffs != null)
>                 {
>                     for (int ii=0; ii < coeffs.length; ii++)
>                     {
>                         //System.out.println("\t coeffs ["+ii+"]"+coeffs[ii]);
>                     }
>                 }
>                 else
>                 {
>                    //System.out.println("No coeffs were passed in");
>                 }
>                 throw new FunctionEvaluationException(coeffs);
>            }
>            double a = coeffs[0];
>            double b = 0;
>            double c = 0;
>            if(coeffs.length >= 2)
>                b = coeffs[1];
>            if(coeffs.length >= 3)
>                c = coeffs[2];
>           double value = a + b*Math.pow(Math.E, (c*x));
>           //System.out.println("\t value ["+value+"]");
>           return value;
>         }
>         /*
>          * derivative: y = b*c*e^(c*x)
>          * double[] coeffs = must include at least 1 but not more than 3 
> coefficients."
>          */
>         @Override
>         public double[] gradient(double x, double[] coeffs) throws 
> FunctionEvaluationException {
>            if(coeffs == null || coeffs.length ==0 || coeffs.length > 3)
>            {
>                 throw new FunctionEvaluationException(coeffs);
>            }
>            System.out.println("\t coeffs length = ["+coeffs.length+"]");
>            double a = coeffs[0];
>            double b = 0;
>            double c = 0;
>            if(coeffs.length >= 2)
>                b = coeffs[1];
>            if(coeffs.length >= 3)
>                c = coeffs[2];
>            double gradient = b*c*Math.pow(Math.E, (c*x));
>            double[] gradientVector = new double[3];
>            gradientVector[0] = gradient;
>            gradientVector[1] = 0;
>            gradientVector[2] = 0;

The gradient is computed with respect to the coefficients (i.e. a, b and
c here), not with respect to the independant variable x. It also *must*
have the same length as the parameters array. So you should probably use:

public double[] gradient(double x, double[] coeffs)
  throws FunctionEvaluationException {
    final n = coeffs.length;
    final double b = (n > 1) ? coeffs[1] : 0;
    final double c = (n > 2) ? coeffs[2] : 0;
    double[] gradient = new double[n];
    gradient[0] = 1.0; // this is dy/da
    if (n > 1) {
       final double exp = Math.exp(c * x);
       gradient[1] = exp; // this is dy/db
       if (n > 2) {
         gradient[2] = b * x * exp; // this is dy/dc
      }
    }
    return gradient;
}

The reason you get a singular problem is proably because of your wrong
gradient, the optimizer thinks the problem does not depend on b and c
(you tell it dy/db = 0 and dy/dc = 0), so it has no way to know how to
choose b and c. The jacobian matrix has too many zeroes.

I also suggest to use Math.exp(c * x) rather than Math.pow(Math.E, c *
x), it is more stable numerically and probably faster.

hope this helps
Luc


>            System.out.println("\t gradient ["+gradient+"]");
>            return gradientVector;
>         }
>    }
> 
> 
> Luc
> ________________________________
> From: [email protected]
> Sent: Thursday, January 21, 2010 11:46 AM
> To: [email protected]
> Subject: [MATH] Need help on math libraries for curve generation
> 
> 
> We are evaluating the apache math library 
> (http://commons.apache.org/math/index.html) for use on one of projects. In 
> this project we need to generate curves based on the following functions:
> 
> 2DCurve3rdOrderXPolynomial
> 2DCurveExponentialX
> 2DCurveNaturalLogX
> 2DCurveSquareRootX
> 2DCurveTimeConstantX
> 2DCurveExponentialDecayX
> 2DCurveLogarithmicDecayX
> 3DCurve4thOrderXPolynomial
> 3DCurveExponentialX
> 3DCurveNaturalLogX
> 3DCurveSquareRootX
> 3DCurveTimeConstantX
> 3DCurve3rdOrderZTimes4thOrderX
> 3DCurveExponentialDecayX
> 3DCurveLogarithmicDecayX
> 3DCurveExponentialDecayZ
> 3DCurveLogarithmicDecayZ
> 3DCurveHyprebolicDecayX
> 
> For each function generated from data we also need:
> 
> Coefficient of Determination
> Sum of Squares
> Standard Error of Regression
> 
> Does anyone have experience with this library to direct us to which classes 
> can be used to handle these requirements?
> 
> Thanks
> Roger Ball
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to