Hello,
i am implementing curve fitting in C# and i tried curve fitting by function values, gradient and i am trying Hessian right now. But i am not really sure about Hessian values, I am not so good in math and this is the first time for me implementing some huge math problem.
My function is:
y = s*(1-exp(-a*pow(x,n)))
where s, a, n are unknown variables which i am looking for.
Could someone check my Hessian, please? I hope it is correct, but i need to be sure. Also i have question about tweaking the calculation, by which parameters i can influence precision of the results? Thank you very much!
Code:
private void button2_Click(object sender, EventArgs e)
{
double[,] x = new double[,] { { 0.0000 }, { 0.4900 }, { 1.0000 }, { 1.4700 }, { 1.9600 }, { 2.4500 }, { 2.9400 }, { 3.4300 }, { 3.9200 }, { 4.4100 }, { 4.9000 } };
double[] y = new double[] { 0.0000, 0.1003, 0.1375, 0.1581, 0.1743, 0.1856, 0.1952, 0.2027, 0.2096, 0.2147, 0.2213, };
double[] c = new double[] { 0.2, 0.5, 0.7 };
double epsf = 0;
double epsx = 0.000001;
int maxits = 0;
int info;
alglib.lsfitstate state;
alglib.lsfitreport rep;
double diffstep = 0.0001;
// Fitting without weights
// X - array[0..N-1,0..M-1], points (one row = one point)
// Y - array[0..N-1], function values.
// C - array[0..K-1], initial approximation to the solution,
// N - number of points, N>1
// M - dimension of space
// K - number of parameters being fitted
// DiffStep- numerical differentiation step; should not be very small or large; large = loss of accuracy small = growth of round-off errors
alglib.lsfitcreatef(x, y, c, diffstep, out state);
alglib.lsfitsetcond(state, epsf, epsx, maxits);
//alglib.lsfitfit(state, function_cx_1_func, null, null); // using function values only
//alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null); // Gradient
alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, function_cx_1_hess, null, null); // Gradient + Hessian
alglib.lsfitresults(state, out info, out c, out rep);
label2.Text = alglib.ap.format(c, 7);
label3.Text = info.ToString();
}
public static void function_cx_1_func(double[] c, double[] x, ref double func, object obj)
{
////c[0] == s
////c[1] == a
////c[2] == n
////y = (s (1-exp(-a x^n)))
//func = (1 - Math.Exp(-c[0] * Math.Pow(x[0], c[1]))); //(1-exp(-a x^n))
func = c[0] * (1 - Math.Exp(-c[1] * Math.Pow(x[0], c[2]))); // s*(1-exp(-a*pow(x,n)))
}
public static void function_cx_1_grad(double[] c, double[] x, ref double func, double[] grad, object obj)
{
////c[0] == s
////c[1] == a
////c[2] == n
////(d)/(ds) (s (1-exp(-a x^n))) = 1-e^(-a x^n)
////(d)/(da) (s (1-exp(-a x^n))) = s x^n e^(-a x^n)
////(d)/(dn) (s (1-exp(-a x^n))) = a s x^n log(x) e^(-a x^n)
grad[0] = 1 - Math.Exp(-c[1] * Math.Pow(x[0],c[2]));//1-e^(-a x^n)
grad[1] = c[0] * Math.Pow(x[0],c[2]) * Math.Exp(-c[1] * Math.Pow(x[0],c[2])); //s x^n e^(-a x^n)
grad[2] = c[1] * c[0] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2])); //a s x^n log(x) e^(-a x^n)
}
public static void function_cx_1_hess(double[] c, double[] x, ref double func, double[] grad, double[,] hess, object obj)
{
////c[0] == s
////c[1] == a
////c[2] == n
////(d^2)/(ds^2) (s (1-exp(-a x^n))) = 0
////(d^2)/(da^2) (s (1-exp(-a x^n))) = s x^(2 n) (-e^(-a x^n))
////(d^2)/(dn^2) (s (1-exp(-a x^n))) = -a s x^n log^2(x) e^(-a x^n) (a x^n-1)
func = c[0] * (1 - Math.Exp(-c[1] * Math.Pow(x[0], c[2])));
grad[0] = 1 - Math.Exp(-c[1] * Math.Pow(x[0], c[2]));//1-e^(-a x^n)
grad[1] = c[0] * Math.Pow(x[0], c[2]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2])); //s x^n e^(-a x^n)
grad[2] = c[1] * c[0] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2])); //a s x^n log(x) e^(-a x^n)
// [c0,c0]...[c0,c2]
//(d^2)/(ds^2) (s (1-exp(-a x^n))) = 0
//(d)/(ds)(d)/(da) (s (1-exp(-a x^n))) = x^n e^(-a x^n)
//(d)/(ds)(d)/(dn) (s (1-exp(-a x^n))) = a x^n log(x) e^(-a x^n)
hess[0,0] = 0;
hess[0, 1] = Math.Pow(x[0], c[2]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2]));
hess[0, 2] = c[1] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2]));
//[c1,c0]...[c1,c2]
//(d)/(da)(d)/(ds) (s (1-exp(-a x^n))) = x^n e^(-a x^n)
//(d^2)/(da^2) (s (1-exp(-a x^n))) = s x^(2 n) (-e^(-a x^n))
//(d)/(da)(d)/(dn) (s (1-exp(-a x^n))) = s x^n log(x) (-e^(-a x^n)) (a x^n-1)
hess[1, 0] = Math.Pow(x[0], c[2]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2]));
hess[1, 1] = c[0] * Math.Pow(x[0],(2 * c[2])) * (-Math.Exp(-c[1] * Math.Pow(x[0], c[2])));
hess[1, 2] = c[0] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * (-Math.Exp(-c[1] * Math.Pow(x[0], c[2]))) * (c[1] * Math.Pow(x[0],(c[2] - 1)));
//[c2,c0]...[c2,c2]
//(d)/(dn)(d)/(ds) (s (1-exp(-a x^n))) = a x^n log(x) e^(-a x^n)
//(d)/(dn)(d)/(da) (s (1-exp(-a x^n))) = s x^n log(x) (-e^(-a x^n)) (a x^n-1)
//(d^2)/(dn^2) (s (1-exp(-a x^n))) = -a s x^n log^2(x) e^(-a x^n) (a x^n-1)
hess[2, 0] = c[1] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * Math.Exp(-c[1] * Math.Pow(x[0], c[2]));
hess[2, 1] = c[0] * Math.Pow(x[0], c[2]) * Math.Log10(x[0]) * (-Math.Exp(-c[1] * Math.Pow(x[0], c[2]))) * (c[1] * Math.Pow(x[0], (c[2] - 1)));
hess[2, 2] = -c[1] * c[0] * Math.Pow(x[0], c[2]) * Math.Pow(Math.Log10(x[0]),2) * (-Math.Exp(-c[1] * Math.Pow(x[0], c[2]))) * (c[1] * Math.Pow(x[0], (c[2] - 1)));
}
Thank you for this library, I found it as the easiest to understand and implement unlike other ones. So as a student i am considering small donation to this project (via paypal if it is possible).