Использование нелинейного квадрата в C#

Я пытаюсь найти подходящую функцию, которая имеет форму:

f(x) = P / (1 + e^((x + m) / s)

куда P известная константа. Я подгоняю эту функцию к списку измеренных двойных чисел (между 20-100 элементами), и все эти значения имеют соответствующее значение x. Я относительно новичок в C# и не очень разбираюсь в математике, поэтому мне сложно читать доступную документацию.

Я пытался использовать AlgLib, но не знаю, с чего начать и какую функцию использовать.

Редактировать: чтобы уточнить, что я ищу: я хотел бы найти метод C#, где я могу передать форму функций, а также некоторые координаты (значения x и y) и получить метод, возвращающий две неизвестные переменные (с и м выше).

1 ответ

Решение

Я использую AlgLib ежедневно именно для этой цели. Если вы перейдете по ссылке http://www.alglib.net/docs.php и прокрутите весь путь вниз, вы найдете документацию с примерами кода на нескольких языках (включая C#), которые, я думаю, помогут вам очень: http://www.alglib.net/translator/man/manual.csharp.html

Для вашей задачи вы должны рассмотреть все необходимые ограничения, но простой пример получения нелинейного наименьших квадратов с учетом вашей входной функции и данных будет выглядеть примерно так:

public SomeReturnObject Optimize(SortedDictionary<double, double> dataToFitTo, double p, double initialGuessM, double initialGuessS)
{
   var x = new double[dataToFitTo.Count,1];

   for(int i=0; i < dataToFitTo.Count; i++)
   {
       x[i, 0] = dataToFitTo.Keys.ElementAt(i);
   }

   var y = dataToFitTo.Values.ToArray();
   var c = new[] {initialGuessM, initialGuessS};

   int info;
   alglib.lsfitstate state;
   alglib.lsfitreport rep;

   alglib.lsfitcreatef(x, y, c, 0.0001, out state);
   alglib.lsfitsetcond(state, epsf, 0, 0);
   alglib.lsfitfit(state, MyFunc, null, p);
   alglib.lsfitresults(state, out info, out c, out rep);

   /*  When you get here, the c[] array should have the optimized values 
       for m and s, so you'll want to handle accordingly depending on your
       needs.  I'm not sure if you want out parameters for m and s or an 
       object that has m and s as properties. */

}

private void MyFunc(double[] c, double[] x, ref double func, object obj)
{
    var xPt = x[0];
    var m = c[0];
    var s = c[1];
    var P = (double)obj;
    func = P / (1 + Math.Exp((xPt + m) / s));
}

Имейте в виду, это всего лишь быстрый и грязный пример. В Alglib имеется множество встроенных функций, поэтому вам нужно будет скорректировать код проблемы в соответствии с вашими потребностями с помощью граничных ограничений, взвешивания, размера шага, масштабирования переменных... и т. Д. Должно быть понятно, как это сделать, из примеров и документации во второй ссылке.

Также обратите внимание, что Alglib очень внимательно относится к сигнатуре метода MyFunc, поэтому я бы избегал перемещаться по этим входам или добавлять их больше.

Кроме того, вы можете написать свой собственный алгоритм Левенберга-Марквардта, если Alglib не удовлетворяет всем вашим потребностям.

Другие вопросы по тегам