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

minlmoptimize doesnt do anything! Help please!
http://forum.alglib.net/viewtopic.php?f=2&t=4349
Page 1 of 1

Author:  RZD [ Thu Jun 11, 2020 4:56 pm ]
Post subject:  minlmoptimize doesnt do anything! Help please!

Hello,

I am trying to fit a curve of the form:
f(x)=c0+c1*tanh(c2*(x-c3))
to 300 points of 2d data e.g. "x" and "y" coordinates, in my case "x" is index and "y" is some given known numerical value.
I need this to be done fast and so after solving this with lsfit I tried to implement using minlm.
Since minlm minimizes a function of sum of squares form i.e.,
F=f1^2+f2^2+...fm^2
I defined my functions to be the errors of the data for a given guess of coefficients i.e.
fi=c0+c1*tanh(c2*(i-c3))-data(i)
and analytically computed the jacobian matrix (300X4).
Unfortunately, minlmresults seems to do nothing and I cant figure out why. Please help me, I have nowhere else to turn.
I post my code below and attach my data in a txt file. "esf" is the 300 points of data I mentions:

using System;
using System.IO;
using System.Text;
using System.Linq;

namespace minlm_d_vj_example
{
class Program
{
public static int Main(string[] args)
{
string esf_string = File.ReadAllText(@"...4_1_1_esf.txt"); //Read data from file
string[] esf_string_split = esf_string.Split('\n');
double[] esf = new double[esf_string_split.Length-1];

double[] ci = new double[4]; //In this block I initialize the coefficients with a clever guess
ci[0] = (esf[0] + esf[^1]) / 2;
ci[1] = (esf[0] - esf[^1]) / 2;
int d = 0;
double dThreshold = ci[0];
for (; (d < esf.Length) && (esf[d] > dThreshold); d++) ;
ci[3] = d;
int di = 2;
double f1 = esf[d - di];
double f2 = esf[d + di];
ci[2] = -(f1 - f2) / (2 * di) / ci[1];

double[] s = new double[] { 1, 1, 1, 1};
double epsx = 0.0000000001;
int maxits = 0;

alglib.minlmstate state;
alglib.minlmcreatevj(esf.Length, ci, out state);
alglib.minlmsetcond(state, epsx, maxits);
alglib.minlmsetscale(state, s);
//alglib.minlmoptguardgradient(state, 0.001);
alglib.minlmoptimize(state, function1_fvec, function1_jac, null, null);
alglib.minlmreport rep;
alglib.minlmresults(state, out ci, out rep);
System.Console.WriteLine("{0}", alglib.ap.format(ci, 2));
alglib.optguardreport ogrep;
alglib.minlmoptguardresults(state, out ogrep);
System.Console.WriteLine("{0}", ogrep.badgradsuspected);
System.Console.ReadLine();
return 0;

void function1_fvec(double[] c, double[] fi, object obj)
{
for (int i = 0; i < esf.Length; i++)
{
fi[i] = c[0] + c[1] * Math.Tanh(c[2] * (i - c[3])) - esf[i];
}
}
void function1_jac(double[] c, double[] fi, double[,] jac, object obj)
{
for (int i = 0; i < esf.Length; i++)
{
fi[i] = c[0] + c[1] * Math.Tanh(c[2] * (i - c[3])) - esf[i];
double k = i - c[3];
jac[i, 0] = 1; //Here I used some algebra to avoid unnecessary computations. OptGuard gives True but I can't find any problems with the jacobian.
jac[i, 1] = Math.Tanh(c[2] * k);
jac[i, 2] = c[1] * (1 - jac[i, 1] * jac[i, 1]) * k;
jac[i, 3] = jac[i, 2] * (-c[2] / k);
}
}
}
}
}

Attachments:
File comment: This files contains the data to be fitted as a function of index.
4_1_1_esf.txt [2.64 KiB]
Downloaded 1680 times

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