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.

 Print view Previous topic | Next topic
Author Message
 Post subject: Nonlinear Fit for Gaussian Surface [SOLVED] Posted: Tue Sep 18, 2018 3:12 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
I would like to use free alglib in C# to fit surfaces with various 2-D functions. I can read all of your code and definitions just fine, but it is not clear how one would define things for a multivariate multidimensional problem. (Multivariate in a single dimension is of course described in the documentation.)

The function to fit to data would be a simple Gaussian for example:

G(x,y|p) = p(0)*exp(-((x-p(1))^2 + (y - p(3))^2)/(2*p(4)^2)) + p(5)

- 'x & y' are in principle a grid and G is the surface value at the grid coordinates. 'p' are the parameters to fit. Obviously the Gaussian could be generalized to be elliptical and have independent x,y sigma's, etc. The actual data and their x,y coordinates would of course be supplied. It is no problem to supply the gradient, etc.

So, I can read c# just fine and have used it extensively, but after reading the documentation for a few days and through the forum, I do not understand how to implement things for this type of problem.

Right now I use the Matlab builder for .Net and interface my c++ .net code to the Matlab Component Runtime, and of course Matlab is great for function fitting, but it does cost a license fee even for academic aerospace work, and it takes maybe 5 seconds to initialize the Matlab MCR the first time it is called. And so using alglib in c# would be fast, and free, and awesome. I've already switched my Matlab 1-D spline calls to the alglib spline library and this works great and is much faster! If I can do surface fitting then I can remove dependence on Matlab even more.

Thanks for the help. Perhaps it would be good to add such an example problem to the documentation since this is a fairly common problem.

Last edited by fatalfitter on Tue Sep 18, 2018 8:48 pm, edited 1 time in total.

Top Post subject: Re: Nonlinear Fit for Gaussian Surface Posted: Tue Sep 18, 2018 4:41 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
Going off of this example (http://www.alglib.net/translator/man/manual.csharp.html#example_lsfit_d_nlf), and having read through the forum, it seems that the function variable x[] can be interpreted as multidimensional if x = x-axis and x = yaxis. Thus:

public static void function_Gauss_2_func(double[] p, double[] x, ref double func, object obj)
{
// this callback calculates a 2-d Gaussian surface G(x,y|p) = p(0)*exp(-((x-p(1))^2 + (y - p(2))^2)/(2*p(3)^2)) + p(4)
// where x is a position on X-axis and x is a position on Y-axis and p is adjustable parameter, and G is the value of the surface at the position.
func = p * System.Math.Exp(-((x-p(1))^2 + (x - p(2))^2)/(2*p(3)^2)) + p;
}

Okay, so that would work fine for computing single scalar values. But then how would you construct things after that?
In the example below (from the above link) it is not clear why you are using a 2-d array for x when you are fitting only a 1-d array of y values. Obviously c should be a 1-d array if it has multiple parameters.
In general the 2-d Gaussian surface would have independent grid position coordinates and then a 2-d array of values at those coordinates. So how would one alglib.lsfitcreatef for such a problem?

public static int Main(string[] args)
{
double[,] x = new double[,]{{-1},{-0.8},{-0.6},{-0.4},{-0.2},{0},{0.2},{0.4},{0.6},{0.8},{1.0}};
double[] y = new double[]{0.223130,0.382893,0.582748,0.786628,0.941765,1.000000,0.941765,0.786628,0.582748,0.382893,0.223130};
double[] c = new double[]{0.3};
double epsx = 0.000001;
int maxits = 0;
int info;
alglib.lsfitstate state;
alglib.lsfitreport rep;
double diffstep = 0.0001;

alglib.lsfitcreatef(x, y, c, diffstep, out state);
alglib.lsfitsetcond(state, epsx, maxits);
alglib.lsfitfit(state, function_cx_1_func, null, null);
alglib.lsfitresults(state, out info, out c, out rep);
}

Top Post subject: Re: Nonlinear Fit for Gaussian Surface Posted: Tue Sep 18, 2018 5:03 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
In

public static int Main(string[] args)
{
double[,] x = new double[,]{{-1},{-0.8},{-0.6},{-0.4},{-0.2},{0},{0.2},{0.4},{0.6},{0.8},{1.0}};
double[] y = new double[]{0.223130,0.382893,0.582748,0.786628,0.941765,1.000000,0.941765,0.786628,0.582748,0.382893,0.223130};
double[] c = new double[]{0.3};
...

is the idea to make x[,] a column array/table of x,y points, and then 'y' (from above) is the corresponding value at the point? As in (using c++ .net code):
Code:
int N = Gaussian_Data->Length();//the total number of data points in the Gaussian surface data to fit
array<double,2>^ x = gcnew array<double,2>(2, N);
array<double>^ y = gcnew array<double>(N);

int i = 0;
for (int xaxis = 0; xaxis = Gaussian_Data->GetLength(0); xaxis++)
for (int yaxis = 0; yaxis = Gaussian_Data->GetLength(1); yaxis++)
{
x[0, i] = (double)xaxis;
x[1, i] = (double)yaxis;
y[i] = Gaussian_Data[xaxis, yaxis];
i++;
}

So is that the idea for doing multidimensional fitting?

I guess I can just try coding it this way and see what happens.

Top Post subject: Re: Nonlinear Fit for Gaussian Surface Posted: Tue Sep 18, 2018 5:55 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
So, this:

Code:
static void function_Gauss_2d(array<double>^ p, array<double>^ x, double &val)
{
// this callback calculates a 2-d Gaussian surface G(x,y|p) = p(0)*exp(-((x-p(1))^2 + (y - p(2))^2)/(2*p(3)^2)) + p(4)
// where x is a position on X-axis and x is a position on Y-axis, p is adjustable parameters, val is the value of the surface at the position.
val = p * Math::Exp(-((x - p)*(x - p) + (x - p)*(x - p)) / (2 * p * p)) + p;
}

Code:
array<double>^ Fit_Gaussian(array<double, 2>^ xdata, array<double, 2>^ ydata, array<double, 2>^ G_xy, array<double>^ p0)
{
int N = G_xy->Length;
array<double, 2>^ x = gcnew array<double, 2>(2, N);
array<double>^ y = gcnew array<double>(N);

int i = 0;
for (int xaxis = 0; xaxis = G_xy->GetLength(0); xaxis++)
for (int yaxis = 0; yaxis = G_xy->GetLength(1); yaxis++)
{
x[0, i] = xdata[xaxis, yaxis];
x[1, i] = ydata[xaxis, yaxis];
y[i] = G_xy[xaxis, yaxis];
i++;
}

alglib::lsfitstate^ state;
alglib::lsfitreport^ rep;
double diffstep = 0.0001;
double epsx = 0.000001;
int maxits = 0;
int info;

alglib::lsfitcreatef(x, y, p0, diffstep, state);
alglib::lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, function_Gauss_2d, nullptr, nullptr);
alglib::lsfitresults(state, info, p0, rep);
return p0;
}

However this gives a compile error:

error C3374: can't take address of 'function_Gauss_2d' unless creating delegate instance

All of this code exists inside a ref class.

Some input would be appreciated.

Top Post subject: Re: Nonlinear Fit for Gaussian Surface Posted: Tue Sep 18, 2018 6:41 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
This code compiles, but I am not sure if it actually does what it is supposed to yet:

Code:
public ref class JPMath
{
array<double>^ Fit_Gaussian(array<double, 2>^ xdata, array<double, 2>^ ydata, array<double, 2>^ G_xy, array<double>^ p0)
{
int N = G_xy->Length;
array<double, 2>^ x = gcnew array<double, 2>(2, N);
array<double>^ y = gcnew array<double>(N);

int i = 0;
for (int xaxis = 0; xaxis = G_xy->GetLength(0); xaxis++)
for (int yaxis = 0; yaxis = G_xy->GetLength(1); yaxis++)
{
x[0, i] = xdata[xaxis, yaxis];
x[1, i] = ydata[xaxis, yaxis];
y[i] = G_xy[xaxis, yaxis];
i++;
}

function_Gauss_2d_delegate^ del = gcnew function_Gauss_2d_delegate(function_Gauss_2d);
alglib::ndimensional_rep^ rep;
Object^ obj;
alglib::lsfitstate^ state;
alglib::lsfitreport^ report;
double diffstep = 0.0001;
double epsx = 0.000001;
int maxits = 0;
int info;

alglib::lsfitcreatef(x, y, p0, diffstep, state);
alglib::lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, (alglib::ndimensional_pfunc^)del, rep, obj);
alglib::lsfitresults(state, info, p0, report);
return p0;
}
static void function_Gauss_2d(array<double>^ p, array<double>^ x, double &val)
{
// this callback calculates a 2-d Gaussian surface G(x,y|p) = p(0)*exp(-((x-p(1))^2 + (y - p(2))^2)/(2*p(3)^2)) + p(4)
// where x is a position on X-axis and x is a position on Y-axis, p is adjustable parameters, val is the value of the surface at the position.
val = p * Math::Exp(-((x - p)*(x - p) + (x - p)*(x - p)) / (2 * p * p)) + p;
}
delegate void function_Gauss_2d_delegate(array<double>^ p, array<double>^ x, double &val);
};

Top Post subject: Re: Nonlinear Fit for Gaussian Surface [SOLVED] Posted: Tue Sep 18, 2018 8:52 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
Here is the solution (note that I am using c++ .net):

Code:
public ref class JPMath
{
static void function_Gauss_2d(array<double>^ p, array<double>^ x, double %val, Object^ obj)
{
val = p * Math::Exp(-((x - p)*(x - p) + (x - p)*(x - p)) / (2 * p * p)) + p;
}
delegate void function_Gauss_2d_delegate(array<double>^ p, array<double>^ x, double %val, Object^ obj);

array<double>^ Fit_Gaussian(array<double, 2>^ xdata, array<double, 2>^ ydata, array<double, 2>^ G_xy, array<double>^ p)
{
int N = G_xy->Length;
array<double, 2>^ x = gcnew array<double, 2>(N, 2);
array<double>^ y = gcnew array<double>(N);

int i = 0;
for (int xaxis = 0; xaxis < G_xy->GetLength(0); xaxis++)
for (int yaxis = 0; yaxis < G_xy->GetLength(1); yaxis++)
{
x[i, 0] = xdata[xaxis, yaxis];
x[i, 1] = ydata[xaxis, yaxis];
y[i] = G_xy[xaxis, yaxis];
i++;
}

alglib::ndimensional_pfunc^ pf = gcnew alglib::ndimensional_pfunc(function_Gauss_2d);
alglib::ndimensional_rep^ rep;
Object^ obj;
alglib::lsfitstate^ state;
alglib::lsfitreport^ report;
double diffstep = 0.0001;
double epsx = 0.000001;
int maxits = 0;
int info;

alglib::lsfitcreatef(x, y, p, diffstep, state);
alglib::lsfitsetcond(state, epsx, maxits);
alglib::lsfitfit(state, pf, rep, obj);
alglib::lsfitresults(state, info, p, report);
return p;
}

};

Top Post subject: Re: Nonlinear Fit for Gaussian Surface [SOLVED] Posted: Tue Sep 18, 2018 8:53 pm Joined: Tue Sep 18, 2018 2:51 pm
Posts: 7
Thanks for the help everybody!

In Mother Russia, the internet helps you! :-)

Top Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending

 All times are UTC

Who is online

Users browsing this forum: Bing [Bot] and 1 guest

 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: 