0

I have the following data.

x = [10
     20
     30 
     40
     50
     60
     70
     80
     90
     100
     110
     120
     130
     140
     150
     160]

and

y = [86.5
     43.9
     25.4
     17.2
     12
     10.5
     8
     7.8
     6.5
     6.8
     6.1
     6.1
     6
     5.4
     5.7
     5.2]

An exponential in the form of:

y = A + Be(cx).

How to find coefficients for a possible exponential approximation

Least squares Levenburg Marquardt with Apache commons

I would like to find the coefficients of this function. The links mentioned above have lead me to the conclusion that I need to linearise the function and use a PolynomialCurveFitter to determine the coefficients. I performed a test with the function below and backtracked to determine if this procedure would be applicable to my data by using the values of x from 10 to 70 and taking it's respective log(y-16).

y = 16 + 200e-x/14

import java.util.Arrays;

import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;

public class CurveFitting {
    public static void main(String[] args) {
        final WeightedObservedPoints obs = new WeightedObservedPoints();
        obs.add(10, 4.58);
        obs.add(20, 3.87);
        obs.add(30, 3.16);
        obs.add(40, 2.44);
        obs.add(50, 1.73);
        obs.add(60, 1.01);
        obs.add(70, 0.29);

        // Instantiate a first-degree polynomial fitter.
        final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(1);

        // Retrieve fitted parameters (coefficients of the polynomial function).
        final double[] coeff = fitter.fit(obs.toList());
        System.out.println(Arrays.toString(coeff));
    }
}

Producing the following values : [5.299999999999998, -0.07149999999999994]. That is B = exp5.3 = 200 and C = -1/14. This was only possible because I had prior knowledge of A, How would I calculate these coefficients if I had no prior knowledge of the constant?

Using wolfram mathematica, the values of for A, B and C are 6.381, 161.144 and -0.0706. I was hoping I could get some guidance in obtaining these values in java. Thanks.

Community
  • 1
  • 1
J Doe
  • 1
  • 2
  • Update I was able to calculate the coefficients of y = A + Becx using Jacquelin's method mentioned below: http://math.stackexchange.com/questions/1337601/fit-exponential-with-constant The coefficients provided from this method was close to those provided from Mathematica. – J Doe Jan 27 '17 at 03:13

1 Answers1

2

The constant A is irrelevant.

You can rearrange your function:

y = A + Be(cx)

to look like this:

z = y-A = B*exp(c*x)

Taking the natural log of both sides:

ln(z) = ln(B) + c*x

You'll do the least squares fit to calculate ln(B) and c using pairs of (x, ln(z)).

You can set A arbitrarily to zero for the fit.

When you have the coefficients you can rewrite the function to get the value of y back.

You can see that all A does is move the curve up and down. My advice would be to extrapolate back to calculate the value of the function at x = 0 and set the value of A from that:

y(0) = A + B => A = B - y(0)

Your data gives you a slope at x = 10:

y'(x = 10) ~ (43.9 - 86.5)/(20 - 10) = -4.26

Extrapolate back to x = 0 using that.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Hi Duffy Thanks for answering. I'm not completely sure so I'm hoping you could clarify any of my mistakes. – J Doe Jan 23 '17 at 05:10
  • This is all you get, short of me doing it for you. – duffymo Jan 23 '17 at 10:10
  • Just out of curiosity, do the coefficients `B` and `c` have a special name? Like "exponential prefactor" or something like that? – Tropilio Feb 19 '21 at 14:37
  • Special names? A is a scale factor - just moves the axis up and down vertically. B would be the coefficient for the exponential term. C*x is the exponent. If you're doing transient problems you can think of 1/C as the time constant. – duffymo Feb 19 '21 at 14:46