Подбор параметров или как описать кривую - C#
Формулировка задачи:
Добрый день!
Стоит задача найти уравнение кривой вида y=A+B*exp(-x/C) (3 параметра)
В моем распоряжении внушительный массив данных (в среднем около 150 000 точек) y и x (см. рис. 0)
У меня получилось выполнить эту задачу с помощью VBA и поиска решений excel (Solver) (см. рис. 1, оранжевая кривая построена по найденным параметрам, синяя - исходная), но есть больше НО
Эксель очень плохо работает с такими большими массивами, обработка ячеек ведется по нескольку минут.
Есть может быть готовый метод для c# в который включен алгоритм Solver'a или может есть какой-нибудь еще способ найти коэффициенты уравнения кривой по массиву (y,x)?
Заранее спасибо!
Решение задачи: «Подбор параметров или как описать кривую»
textual
Листинг программы
class Program { public static double[] LeastSquaresBestFitLine1(double[] x, double[] y) { //Calculates equation of best-fit line using short cuts int n = x.Length; double xMean = 0.0; double yMean = 0.0; double numeratorSum = 0.0; double denominatorSum = 0.0; double bestfitYintercept = 0.0; double bestfitSlope = 0.0; double sigma = 0.0; double sumOfResidualsSquared = 0.0; //Calculates the mean values for x and y arrays for (int i = 0; i < n; i++) { xMean += x[i] / n; yMean += y[i] / n; } //Calculates the numerator and denominator for best-fit slope for (int i = 0; i < n; i++) { numeratorSum += y[i] * (x[i] - xMean); denominatorSum += x[i] * (x[i] - xMean); } //Calculate the best-fit slope and y-intercept bestfitSlope = numeratorSum / denominatorSum; bestfitYintercept = yMean - xMean * bestfitSlope; //Calculate the best-fit standard deviation for (int i = 0; i < n; i++) { sumOfResidualsSquared += (y[i] - bestfitYintercept - bestfitSlope * x[i]) * (y[i] - bestfitYintercept - bestfitSlope * x[i]); } sigma = Math.Sqrt(sumOfResidualsSquared / (n - 2)); return new double[] { bestfitYintercept, bestfitSlope, sigma }; } public static double[] LeastSquaresWeightedBestFitLine1(double[] x, double[] y, double[] w) { //Calculates equation of best-fit line using short cuts int n = x.Length; double wxMean = 0.0; double wyMean = 0.0; double wSum = 0.0; double wnumeratorSum = 0.0; double wdenominatorSum = 0.0; double bestfitYintercept = 0.0; double bestfitSlope = 0.0; double sigma = 0.0; double sumOfResidualsSquared = 0.0; //Calculates the sum of the weights w[i] for (int i = 0; i < n; i++) { wSum += w[i]; } //Calculates the mean values for x and y arrays for (int i = 0; i < n; i++) { wxMean += w[i] * x[i] / wSum; wyMean += w[i] * y[i] / wSum; } //Calculates the numerator and denominator for best-fit slope for (int i = 0; i < n; i++) { wnumeratorSum += w[i] * y[i] * (x[i] - wxMean); wdenominatorSum += w[i] * x[i] * (x[i] - wxMean); } //Calculate the best-fit slope and y-intercept bestfitSlope = wnumeratorSum / wdenominatorSum; bestfitYintercept = wyMean - wxMean * bestfitSlope; //Calculate the best-fit standard deviation for (int i = 0; i < n; i++) { sumOfResidualsSquared += w[i] * (y[i] - bestfitYintercept - bestfitSlope * x[i]) * (y[i] - bestfitYintercept - bestfitSlope * x[i]); } sigma = Math.Sqrt(sumOfResidualsSquared / (n - 2)); return new double[] { bestfitYintercept, bestfitSlope, sigma }; } static void Main(string[] args) { Console.WriteLine("Testing Exponential Fit"); Console.WriteLine(" Original equation: y = a e^{cx}"); Console.WriteLine("Linearized equation: ln(y) = cx + ln(a)"); Console.WriteLine("which is in the form: Y = mx + b for a straight line\n"); double[] x = new double[] { 1, 2, 3, 4, 5 }; double[] y = new double[] { 3.5, 6.2, 9.5, 15.3, 20.4 }; double[] logy = new double[] { 1.25276, 1.82455, 2.25129, 2.72785, 3.01553 }; double[] results = LeastSquaresBestFitLine1(x, logy); Console.WriteLine("Results without weights, just (x,ln(y)): "); Console.WriteLine("Best-fit y-intercept b = ln(a) = {0}", results[0]); Console.WriteLine("Best-fit slope = m = c ={0}", results[1]); Console.WriteLine("Best-fit sigma = {0}", results[2]); Console.WriteLine("Equation for weighted best-fit exponential:"); Console.WriteLine("y = a e^(cx) = {0}exp({1}x)\n", Math.Exp(results[0]), results[1]); double[] resultsWt = LeastSquaresWeightedBestFitLine1(x, logy, y); Console.WriteLine("Results with weights w = y. Calc (x,ln(y),w)):"); Console.WriteLine("Best-fit y-intercept b = ln(a)= {0}", resultsWt[0]); Console.WriteLine("Best-fit slope = m = c = {0}", resultsWt[1]); Console.WriteLine("Best-fit sigma = {0}", resultsWt[2]); Console.WriteLine("Equation for weighted best-fit exponential:"); Console.WriteLine("y = a e^(cx) = {0}exp({1}x)\n", Math.Exp(resultsWt[0]), resultsWt[1]); Console.ReadLine(); } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д