forum.alglib.net http://forum.alglib.net/ |
|
lsfitcreatef function with vector function http://forum.alglib.net/viewtopic.php?f=2&t=3870 |
Page 1 of 1 |
Author: | Dmitrii [ Sun Oct 28, 2018 1:29 pm ] |
Post subject: | lsfitcreatef function with vector function |
Good day all! I use C# version of ALGLIB 3.14.0. I had quite good results in working with lsfitcreatef and lsfitcreatefg. I worked with analytic functions before. Now I have to work with vectos and have to find results for such task: ------------------------------------------------------------------------------------------- v1, v2, v are vectors length N and v = a1 * v1 + a2 * 2 a1 and a2 - are unknown parameters. Need to find tallies for a1 and a2. In more general case v1,v2,..,vk (they are not orthogonal) v = a1 * v1 + a2 * 2 + .... + ak * vk. Need to find tallies for a1, a2, ..., ak. In most general case v1,v2,..,vk (they are not orthogonal) v = a1 * F(v1,ak+1,...,an) + a2 * F(v2,ak+1,...,an) + ... + ak * F(vk,ak+1,...,an), where F(vi,ak+1,...,an) = vi* - transformed vector vi. ak+1,...,an - parameters of transformation. The form of transformation is the same for all vectors. For example: vi -> vi^(ak+1) Need to find tallies for a1, a2, ..., ak, ak+1,...,an. -------------------------------------------------------------------------------------------------------------------------------------------------------- I have tried this code: Code: class Program { static void Main(string[] args) { double[] y = new double[] { 2, 2, 3, 3}; double[,] x = new double[y.Length, 1]; for (int i = 0; i < y.Length; i++) { x[i, 0] = (double)(i); } double[] s = new double[] {1, 1}; // scale double[] c = new double[] {2.2, 1}; // start values double[] bndl = new double[] {0.0, 0.0}; // lower bound double[] bndu = new double[] {4.0, 4.0}; // upper bound double epsx = 0.0001; int maxits = 0; int info; alglib.lsfitstate state; alglib.lsfitreport rep; double diffstep = 0.01; alglib.lsfitcreatef(x, y, c, diffstep, out state); alglib.lsfitsetbc(state, bndl, bndu); alglib.lsfitsetcond(state, epsx, maxits); alglib.lsfitsetscale(state, s); alglib.lsfitfit(state, function_cx_2_func, null, null); alglib.lsfitresults(state, out info, out c, out rep); int iterationscount = rep.iterationscount; System.Console.WriteLine("{0}", info); System.Console.WriteLine("iterationscount = " + iterationscount.ToString()); System.Console.WriteLine("{0}", alglib.ap.format(c, 7)); System.Console.ReadKey(); } public static void function_cx_2_func(double[] c, double[] x, ref double func, object obj) { // vectors a and b [b]double[] a = new double[] { 1, 1, 0, 0}; double[] b = new double[] { 0, 0, 1, 1};[/b] func = func + c[0] * a[(int)x[0]] + c[1] * b[(int)x[0]]; } } Output: 2 iterationscount = 0 {2.1995969,0.9996091} While correct result {2.0, 3.0}. Most likely I was wrong somewhere in the code or in logic of lsfit subpackage. I solved this task through minlm subpackage: Code: class Program { static void Main(string[] args) { // // This example demonstrates minimization of F(x0,x1) = f0^2+f1^2 + .... fn^2 // // using "V" mode of the Levenberg-Marquardt optimizer. // // Optimization algorithm uses: // * function vector f[] = {f1,f2,...,fn^2} // // No other information (Jacobian, gradient, etc.) is needed. // double[] x = new double[] { 0, 0 }; double epsx = 0.0000000001; int maxits = 100; alglib.minlmstate state; alglib.minlmreport rep; double[] bndl = new double[] { 0, 0 }; double[] bndu = new double[] { +4, +4 }; alglib.minlmcreatev(4, x, 0.0001, out state); alglib.minlmsetbc(state, bndl, bndu); alglib.minlmsetcond(state, epsx, maxits); alglib.minlmoptimize(state, function2_fvec, null, null); alglib.minlmresults(state, out x, out rep); System.Console.WriteLine("{0}", alglib.ap.format(x, 7)); System.Console.WriteLine("{0}", alglib.ap.format(rep.iterationscount, 7)); System.Console.ReadLine(); } public static void function2_fvec(double[] x, double[] fi, object obj) { double[] array1 = new double[] { 1, 1, 0, 0 }; double[] array2 = new double[] { 0, 0, 1, 1}; double[] array3 = new double[] { 2, 2, 3, 3}; for (int i = 0; i < array1.Length; i++) { fi[i] = System.Math.Pow(array3[i] - x[0] * array1[i] - x[1] * array2[i], 2); } } } Output {2.0000000,3.0000000} 44.0000000+0.0000000i OK Sergey, could you spare a little time for my problem, please? I hoped use lsfit subpackage due to more compact form for function2_fvec as well as for uniformity of code in other similar tasks. And second question: what is the differece between lsfit subpackage and minlm subpackage? Is it possible to say that some package is better for NLS-fiting? With the best regards Dmitri |
Author: | Sergey.Bochkanov [ Wed Oct 31, 2018 1:22 pm ] |
Post subject: | Re: lsfitcreatef function with vector function |
Hi! lsfit subpackage is intended for "simple" situations like when you have scalar target function which is same for all dataset points, minlm is intended for general situation - i.e. for anything else. Given that, it does not makes much sense in extending lsfit with more complex cases (like yours) - you already have minlm for such tasks :) |
Page 1 of 1 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |