Подбор параметров или как описать кривую - 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();
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.867 из 5
Похожие ответы