# forum.alglib.net

ALGLIB forum
 It is currently Sat Sep 23, 2017 2:39 pm

 All times are UTC

### Forum rules

1. This forum can be used for discussion of both ALGLIB-related and general numerical analysis questions
2. This forum is English-only - postings in other languages will be removed.

 Page 1 of 1 [ 5 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Least Squares for Non-Linear Curve fitting in C#Posted: Sun Feb 26, 2017 10:27 am

Joined: Sun Feb 26, 2017 9:39 am
Posts: 6
I was using Math.Numerics in C# for my coding purposes but now I am learning Alglib since it has cross platform universal implementations. I am moving my Non-Linear curve fitting for the assumed equation and with sample generated data and upon successful i can fit my own data.
Curve Equation is : y = a * cos(b * x + c) + d * sin(e * x + f)

and C# code is :
Code:
class Program
{

public static int Main(string[] args)
{

GetRawDataXY(fileName);*/
double[] coeffs=InitalizeSampleData(1000);
System.Console.WriteLine("Curve original Coeffs are : {0}", alglib.ap.format(coeffs, 10));
Random randNum = new Random();
// Random randInt = new Random();
double[] c = Enumerable.Repeat(0, 5 + 1)
.Select(i => randNum.NextDouble() + 1).ToArray();
double epsf = 0;
double epsx = 0.000001;
int maxits = 0;
int info;
alglib.lsfitstate state;
alglib.lsfitreport rep;

//
// Fitting without weights
//
alglib.lsfitcreatefgh(Curve.Xdata, Curve.Ydata, c, out state);
alglib.lsfitsetcond(state, epsf, epsx, maxits);
alglib.lsfitfit(state, ModelValue, ModelGradient, ModelHessian, null, null);
alglib.lsfitresults(state, out info, out c, out rep);
System.Console.WriteLine("{0}", info); // EXPECTED: 2
System.Console.WriteLine("Curve Generated coeffs without weights are : {0}", alglib.ap.format(c, 10)); // EXPECTED: [1.5]

return 0;
}

private static double[] InitalizeSampleData(int sampleSize)
{
int count = 0;
Random randNum = new Random();
// Random randInt = new Random();
double[] coeffs = Enumerable.Repeat(0, 5 + 1)
.Select(j => randNum.NextDouble() + 1).ToArray();

Curve.Xdata = new double[sampleSize, 1];
Curve.Ydata = new double[sampleSize];
for (int i=0;i<sampleSize;i++)
{

Curve.Xdata[count, 0] = Convert.ToDouble(i+1);

double[] xData =new double[1] { Curve.Xdata[count,0] };
ModelValue(coeffs, xData, ref Curve.Ydata[count], null);

count++;

}
return coeffs;
}

protected static void ModelValue(double[] parameters, double[] x, ref double func, object obj)
{
func = parameters[0] * Math.Cos(parameters[1] * x[0] + parameters[2]) + parameters[3] * Math.Sin(parameters[4] * x[0] + parameters[5]);
}

protected static void ModelGradient(double[] parameters, double[] x, ref double func, double[] gradient, object obj)
{
ModelValue(parameters, x, ref func, obj);
gradient[0] = Math.Cos(parameters[1] * x[0] + parameters[2]);
gradient[1] = -parameters[0] * Math.Sin(parameters[1] * x[0] + parameters[2]) * x[0];
gradient[2] = -parameters[0] * Math.Sin(parameters[1] * x[0] + parameters[2]);
gradient[3] = Math.Sin(parameters[4] * x[0] + parameters[5]);
gradient[4] = parameters[3] * Math.Cos(parameters[4] * x[0] + parameters[5]) * x[0];
gradient[5] = parameters[3] * Math.Cos(parameters[4] * x[0] + parameters[5]);
}

protected static void ModelHessian(double[] c, double[] x, ref double func, double[] grad, double[,] hess, object obj)
{
ModelValue(c, x, ref func, obj);
Hessian(x[0], c, ref hess);
}

private static void Hessian(double x, double[] parameters, ref double[,] hess)
{

hess[0, 0] = 0; //d2/du2
hess[1, 0] = -Math.Sin(parameters[1] * x + parameters[2]) * x; //d2/dvdu
hess[2, 0] = -Math.Sin(parameters[1] * x + parameters[2]); //d2/dwdu
hess[3, 0] = 0;//d2/dxdu
hess[4, 0] = 0;//d2/dydu
hess[5, 0] = 0;//d2/dydz

hess[0, 1] = -Math.Sin(parameters[1] * x + parameters[2]);//d2/dudv
hess[1, 1] = -parameters[0] * Math.Cos(parameters[1] * x + parameters[2]) * x * x; //d2/dv2
hess[2, 1] = -parameters[0] * Math.Cos(parameters[1] * x + parameters[2]) * x; //d2/dwdv
hess[3, 1] = 0;//d2/dxdv
hess[4, 1] = 0;//d2/dydv
hess[5, 1] = 0;////d2/dzdv

hess[0, 2] = -Math.Sin(parameters[1] * x + parameters[2]) * x;//d2/dudw
hess[1, 2] = -parameters[0] * Math.Cos(parameters[1] * x + parameters[2]) * x;  //d2/dvdw
hess[2, 2] = -parameters[0] * Math.Cos(parameters[1] * x + parameters[2]); //d2/dw2
hess[3, 2] = 0;//d2/dxdw
hess[4, 2] = 0;//d2/dydw
hess[5, 2] = 0;////d2/dzdw

hess[0, 3] = 0;//d2/dudx
hess[1, 3] = 0;  //d2/dvdx
hess[2, 3] = 0; //d2/dwdx
hess[3, 3] = 0; //d2/dx2
hess[4, 3] = Math.Cos(parameters[4] * x + parameters[5]) * x;//d2/dydx
hess[5, 3] = Math.Cos(parameters[4] * x + parameters[5]); ////d2/dzdx

hess[0, 4] = 0;//d2/dudy
hess[1, 4] = 0;  //d2/dvdy
hess[2, 4] = 0; //d2/dwdy
hess[3, 4] = Math.Cos(parameters[4] * x + parameters[5]) * x; //d2/dxdy
hess[4, 4] = -parameters[3] * Math.Sin(parameters[4] * x + parameters[5]) * x * x;//d2/dy2
hess[5, 4] = -parameters[3] * Math.Sin(parameters[4] * x + parameters[5]) * x; ////d2/dzdy

hess[0, 5] = 0;//d2/dudz
hess[1, 5] = 0;  //d2/dvdz
hess[2, 5] = 0; //d2/dwdz
hess[3, 5] = Math.Cos(parameters[4] * x + parameters[5]);  //d2/dxdz
hess[4, 5] = -parameters[3] * Math.Sin(parameters[4] * x + parameters[5]) * x;//d2/dydz
hess[5, 5] = -parameters[3] * Math.Sin(parameters[4] * x + parameters[5]); ////d2/dz2

}

public static void GetRawDataXY(string filename)
{

int count = 0;

Curve.Xdata = new double[lines.Count(),1];
Curve.Ydata = new double[lines.Count()];
foreach (var line in lines)
{

var elements = line.Split(';');
Curve.Xdata[count,0] = Convert.ToDouble(elements[0]);
Curve.Ydata[count] = Convert.ToDouble(elements[1]);
count++;

}
}

public class Curve
{
/*Global Variables*/
public static double[,] Xdata;
public static double[] Ydata;

}

}

Ofcourse I am getting some values for Coeffs. But I wonder whether this approach is correct. I suspect on function alglib.lsfitfit algorithm. I have hard in understanding what it does. I just followed documentation. Does it minimize on R2 basis? I want my curve fitting to stop fitting when it reached below criteria:
NewCalcR2-oldCalcR2 is <= Given delta value or
Magnitude of(OldCoffVector-NewCoeffVector) <=GivenDeltaValue or IterationCount reached maximum
Ofcourse I know this by looking at Info value. I need to make sure if this is correct.

Output from Console:

As you see from ouput, original and generated coeff no way near to the value. I want the generated coeffs to be as approximate equal to that. How could i achieve that?

Top

 Post subject: Re: Least Squares for Non-Linear Curve fitting in C#Posted: Mon Feb 27, 2017 9:21 am

Joined: Fri May 07, 2010 7:06 am
Posts: 779
Hi! I have a few thoughts:

1. You may find it easier to work with optimizer created with lsfitcreatefg (just gradient is used) or even with lsfitcreatef (you specify just function value, numerical differentiation is used, it is often convenient for fast prototyping).

2. I noticed that you use random initial point. However, your target function is notoriously hard one - sine and cosine functions result in difficult landscape with many bad local extrema. So, it is very unlikely that you will converge to the same coeffs as ones which were used to generate dataset.

If you want to solve a toy problem with aim of reproducing original coefficients used to generate dataset, it is better to distort these original coefficients a little, and pass them to lsfit optimizer as initial point. You will see whether it is able to refine them and restore original values - or not. You may start from small distortions, like 1.0E-3 in magnitude, and increase them step by step. Different coefficients will show different tolerances to distortions - ones "hidden within" sine and cosine will be most intolerable.

3. lsfit optimizer returns a lot of information in the rep parameter. Say, rep.rmserror and rep.avgerror contain different kinds of error metric on your dataset - root-mean-square and average.

Top

 Post subject: Re: Least Squares for Non-Linear Curve fitting in C#Posted: Mon Feb 27, 2017 12:02 pm

Joined: Sun Feb 26, 2017 9:39 am
Posts: 6

What do you mean by distort the orginal coefficients? Should i substract the magnitude or add the magnitude to the coeffs?

Can i Use distorted coeffs of sample generated data to my actual dataset?

Top

 Post subject: Re: Least Squares for Non-Linear Curve fitting in C#Posted: Tue Feb 28, 2017 5:06 pm

Joined: Fri May 07, 2010 7:06 am
Posts: 779
Say, generate data using coefficient vector C0. Then, generate random noise E with zero mean and unit standard deviation. Then let C1=C0 + 0.01*E, and try to solve least squares problem using C1 as initial estimate. If everything is right, it should converge to C0.

Top

 Post subject: Re: Least Squares for Non-Linear Curve fitting in C#Posted: Sun Mar 05, 2017 6:01 pm

Joined: Sun Feb 26, 2017 9:39 am
Posts: 6
Thanks, Its working..

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 5 posts ]

 All times are UTC

#### Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for: