# commons-user mailing list archives

##### Site index · List index
Message view
Top
From "roger.ball@creoss.com" <roger.b...@creoss.com>
Subject RE: [MATH] Need help on math libraries for curve generation
Date Sun, 24 Jan 2010 19:54:01 GMT
```Luc
Thanks for tips on the parametric real function (see botton). Based on these changes and
a data set I am getting the following results, see below. I am not quite sure how to use this
information to compute:

Coefficient of Determination
Sum of Squares
Standard Error of Regression

Thanks

Roger

CurveFitter using LevenbergMarquardtOptimizer
function is y = a + be^(cx)
16 data points for "Trail Shaft Configuration"
best coeff [0]291.14035683044796
best coeff [1]182.57603828133813
best coeff [2]0.09714949397797856
Root Mean Square [26.34790434234611]
Covariances [0][0]8.856485460793724
Covariances [0][1]-5.701795559353768
Covariances [0][2]0.0012611571197298362
Covariances [1][0]-5.701795559353772
Covariances [1][1]3.7453325583603876
Covariances [1][2]-8.360156212815445E-4
Covariances [2][0]0.0012611571197298384
Covariances [2][1]-8.36015621281545E-4
Covariances [2][2]1.8778882839946132E-7
guessParametersError [0]86.98915260216266
guessParametersError [1]56.56914127885704
guessParametersError [2]0.012666868717084282
chi Square [11107.393011734734]
------------------------------------------------------
Function value as 5 = 587.8975295919015, Actual = 576.0
Function value as 20 = 1565.445870365208, Actual = 1590.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;
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
}
}
}

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

Roger Ball
________________________________
From: roger.ball@creoss.com
Sent: Friday, January 22, 2010 10:59 AM
To: user@commons.apache.org
Subject: RE: [MATH] Need help on math libraries for curve generation

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];
}
}

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

```
Mime
• Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message