forum.alglib.net
http://forum.alglib.net/

Coordinate transformation using ALGlib
http://forum.alglib.net/viewtopic.php?f=2&t=4591
Page 1 of 1

Author:  xiaoxiao [ Sat Jan 27, 2024 12:19 pm ]
Post subject:  Coordinate transformation using ALGlib

Hello, everyone.
I am using the ALGlib to calculate the transformation parameters between two coordinate system,
with equations like:
x2 =dx+ k * Cos(alp) * x1 - k*Sin(alp) * y1
y2 =dy+ k * sin(alp) * x1 + k*cos(alp) * y1

where, (x1,y1) and (x2,y2) are the coordinates of the same point in system 1 and 2, respectively.
the parameters including dx, dy, alp and k.
There are six data points with coordinates in the two system. The task is to fit the parameters.
This is a multi-dimensional non-linear problem. So I using functions in the lsfit subpackage.
However, the result is not correct (see c# code below).
Would you tell me how to fix the problem?

public static void ne2ne(double[] p, double [] x, ref double func, object obj)
{
//The actual value is : dn=-11.3387, de =116.3029, alp =5.236*1e-7, k-1= 3.517*1e-6
var dn = p[0]; //parameters
var de = p[1];
var alp = p[2];
double k = 1 + p[3];

double n1 = x[0]; //x1
double e1 = x[1]; //y1
double n2 = x[2]; //x2
double e2 = x[3]; //y2

double t1 = dn + k * (Math.Cos(alp) * n1 - Math.Sin(alp) * e1)-n2;
double t2 = de + k * (Math.Sin(alp) * n1 + Math.Cos(alp) * e1)-e2;
func =t1 + t2;
}

int main()
{
var infile = new StreamReader("input.txt"); //please find the file in the attachment
var x0 = new List<double>();
var y0 = new List<double>();
int i = 0;
while (!infile.EndOfStream)
{
string str = infile.ReadLine();
string[] temp = str.Split(new char[] { '\t'});
x0.Add(double.Parse(temp[0]));
x0.Add(double.Parse(temp[1]));
y0.Add(double.Parse(temp[2]));
y0.Add(double.Parse(temp[3]));
i++;
}
var xData = (x0.ToArray());
var yData = (y0.ToArray());

int num = xData.Length / 2;

double n_1 = 0, n_2 = 0, e_1 = 0, e_2 = 0;
double[,] xy_xy = new double[num, 4];
double[] v = new double[num * 2];

for (i = 0; i < num; i++)
{
n_1 += xData[2 * i];
e_1 += xData[2 * i + 1];
n_2 += yData[2 * i];
e_2 += yData[2 * i + 1];
xy_xy[i,0] = xData[2 * i];
xy_xy[i,1] = xData[2 * i+1];
xy_xy[i,2] = yData[2 * i];
xy_xy[i,3] = yData[2 * i + 1];
}
double dn0 = (n_2 - n_1) / num, de0 = (e_2 - e_1) / num; //initial value

double[] paras = new double[] { dn0, de0,0,0 };
double epsx = 0.000001;
int maxits = 0;
var state =new lsfitstate();
lsfitreport rep;
var _params= new xparams(4);
double diffstep = 1e-4;
lsfitcreatef(xy_xy, v, paras, num, 4, 4, diffstep, out state);
double nlthreshold = 1e-12;
lsfitsetcond(state, nlthreshold, 0, _params);
lsfitfit(state, coordTranTool.ne2ne, null, null);
int info = 1;
lsfitresults(state,out info, out paras, out rep);

return 0;
}

Author:  Sergey.Bochkanov [ Mon Jan 29, 2024 11:20 pm ]
Post subject:  Re: Coordinate transformation using ALGlib

Hi!

The problem is that you choose the wrong subpackage. It must be MINLM (general nonlinear least squares), not LSFIT (curve fitting). The key point is that curve fitting is about fitting the same function (curve) computed at different locations, and you have TWO functions to fit, not one:

Quote:
x2 =dx+ k * Cos(alp) * x1 - k*Sin(alp) * y1
y2 =dy+ k * sin(alp) * x1 + k*cos(alp) * y1


In theory, it is possible to convert your expressions for x2 and y2 to some common form which can be processed by LSFIT, so it will see x2 and y2 as the same function computed with different values of some additional "flag variable". However, in my opinion, it is better to switch to MINLM, which performs nonlinear least squares minimization of arbitrary (even very different) squared functions.

Sergei.

Page 1 of 1 All times are UTC
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/