commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Luc Maisonobe <Luc.Maison...@free.fr>
Subject Re: [MATH] Need help on math libraries for curve generation
Date Fri, 22 Jan 2010 19:45:52 GMT
roger.ball@creoss.com 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: roger.ball@creoss.com
> Sent: Thursday, January 21, 2010 11:46 AM
> To: user@commons.apache.org
> 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: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message