Интерполяция почему-то рисует прямую линию - C#

Узнай цену своей работы

Формулировка задачи:

Может быть я до конца не понимаю смысл полиномов. Однако вроде я использую верные формулы для интерполяции. Собственно есть 4 метода интерполяции: Полином Лагранжа, Полином Ньютона, Кубический сплайн(alglib), линейная интерполяция. Проблему можно рассматривать на любом методе. В общем в создал я метод интерполяции
Листинг программы
  1. public interface IRaschet
  2. {
  3. double Compute(double[] volt, double[] sum);
  4. }
  5. public class Lagrange : IRaschet
  6. {
  7. double[] x;
  8. double[] y;
  9. public double Compute(double[] volt, double[] sum)
  10. {
  11. double x0 = sum[1];
  12. x = sum;
  13. y = volt;
  14. double lagrangePol = 0;
  15. int size = 100;
  16. for (int i = 0; i < size; i++)
  17. {
  18. double basicsPol = 1;
  19. for (int j = 0; j < size; j++)
  20. {
  21. if (j != i)
  22. {
  23. basicsPol *= (x0 - x[j]) / (x[i] - x[j]);
  24. }
  25. }
  26. lagrangePol += basicsPol * y[i];
  27. }
  28. return lagrangePol;
  29. }
  30. }
  31. public class Spline : IRaschet
  32. {
  33. public double Compute(double[] volt, double[] sum)
  34. {
  35. // * x - abscissas
  36. // * y - vector of experimental data, straight line with small noise
  37. double[] x;
  38. double[] y;
  39. x = volt;
  40. y = sum;
  41. int info;
  42. double v;
  43. alglib.spline1dinterpolant s;
  44. alglib.spline1dfitreport rep;
  45. double rho;
  46. rho = -5.0;
  47. alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep);
  48. //System.Console.WriteLine("{0}", info); // EXPECTED: 1
  49. v = alglib.spline1dcalc(s, 0.0);
  50. //System.Console.WriteLine("{0:F1", v); // EXPECTED: 0.10
  51. rho = +10.0;
  52. alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep);
  53. //System.Console.WriteLine("{0}", info); // EXPECTED: 1
  54. v = alglib.spline1dcalc(s, 1.0);
  55. //System.Console.WriteLine("{0:F2", v); // EXPECTED: 0.969
  56. rho = +3.0;
  57. alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep);
  58. //System.Console.WriteLine("{0}", info); // EXPECTED: 1
  59. //System.Console.ReadLine();
  60. return v;
  61. }
  62. }
  63. public class Newton : IRaschet
  64. {
  65. public double Compute(double[] volt, double[] sum)
  66. {
  67. double t=1;
  68. int n=100;
  69. double[] x = volt;
  70. double[] y = sum;
  71. double res = y[0], F, den;
  72. int i, j, k;
  73. for (i = 1; i <= n; i++)
  74. {
  75. F = 0;
  76. for (j = 0; j <= i; j++)
  77. {
  78. den = 1;
  79. for (k = 0; k <= i; k++)
  80. {
  81. if (k != j) den *= (x[j] - x[k]);
  82. }
  83. F += y[j] / den;
  84. }
  85. for (k = 0; k < i; k++) F *= (t - x[k]);
  86. res += F;
  87. }
  88. return res;
  89. }
  90. }
  91. public class Linear : IRaschet
  92. {
  93. public double Compute(double[] volt, double[] sum)
  94. {
  95. Form1 objForm1 =new Form1();
  96. double a;
  97. double b;
  98. double ux;
  99. double uxx=1;
  100. double mx;
  101. mx = 50;
  102. double[] mass; mass = new double[] { 1000, 2000, 3000, 4000, 5000 };
  103. int n = 5;
  104. double[] uz; uz = volt;
  105. double[] yz; yz = sum;
  106. int beg = 0;
  107. int end = 0;
  108. double Ybeg = 0;
  109. double Yend = 0;
  110. for (int i = 0; i < n - 1; i++)
  111. {
  112. if (mass[i] <= mx && mass[i] <= mx)
  113. {
  114. beg = i;
  115. end = i + 1;
  116. }
  117. Ybeg = uz[beg];
  118. Yend = uz[end];
  119. a = (Yend - Ybeg) / (mass[end] - mass[beg]);
  120. b = Ybeg - a * mass[beg];
  121. ux = a * mx + b;
  122. objForm1.textBox2.Text = (ux).ToString();
  123. Ybeg = yz[beg];
  124. Yend = yz[end];
  125. a = (Yend - Ybeg) / (mass[end] - mass[beg]);
  126. b = Ybeg - a * mass[beg];
  127. uxx = a * mx + b;
  128. objForm1.textBox10.Text = (uxx).ToString();
  129. }
  130. return uxx;
  131. }
  132. }
В весь код можно не вникать. В код для расчёта полинома передаю массивы sum и volt в качестве аргументов x и y. Далее строю график с помощью zedgraph
Листинг программы
  1. private IRaschet Extra;
  2. public double[,] Pts = new double[8, 2];
  3. public double[] sum = new double[8];
  4. public double[] volt = new double[8];
  5. private void formSumArray()
  6. {
  7. sum[0] = Convert.ToDouble(textBox2.Text);
  8. sum[1] = Convert.ToDouble(textBox3.Text);
  9. sum[2] = Convert.ToDouble(textBox4.Text);
  10. sum[3] = Convert.ToDouble(textBox5.Text);
  11. sum[4] = Convert.ToDouble(textBox6.Text);
  12. sum[5] = Convert.ToDouble(textBox7.Text);
  13. sum[6] = Convert.ToDouble(textBox8.Text);
  14. sum[7] = Convert.ToDouble(textBox9.Text);
  15. {
  16. volt[0] = 0f;
  17. volt[1] = 1f;
  18. volt[2] = 2f;
  19. volt[3] = 3f;
  20. volt[4] = 4f;
  21. volt[5] = 5f;
  22. volt[6] = 6f;
  23. volt[7] = 6.2f;
  24. }
  25. for (int a = 0; a < volt.Length; a++)
  26. {
  27. Pts[a, 0] = volt[a];
  28. Pts[a, 1] = sum[a];
  29. }
  30. }
  31. private void button3_Click(object sender, EventArgs e)
  32. {
  33. // ВЫЗЫВАЕТЕ МЕТОД COMPUTE
  34. formSumArray();
  35. GraphPane pane = zedGraphControl1.GraphPane;
  36. GraphControl("Величина", "Напряжение", "График"); // для первого вызова
  37. // Создадим список точек
  38. PointPairList list = new PointPairList();
  39. double xmin = 0;
  40. double xmax = 10;
  41. // Заполняем список точек
  42. for (double x = xmin; x <= xmax; x += 0.01)
  43. {
  44. // добавим в список точку
  45. list.Add(x, Extra.Compute(volt, sum));
  46. }
  47. // Создадим кривую с названием "Sinc",
  48. // которая будет рисоваться голубым цветом (Color.Blue),
  49. // Опорные точки выделяться не будут (SymbolType.None)
  50. LineItem myCurve = pane.AddCurve("Sinc", list, Color.Blue, SymbolType.None);
  51. // Вызываем метод AxisChange (), чтобы обновить данные об осях.
  52. // В противном случае на рисунке будет показана только часть графика,
  53. // которая умещается в интервалы по осям, установленные по умолчанию
  54. zedGraphControl1.AxisChange();
  55. // Обновляем график
  56. zedGraphControl1.Invalidate();
  57. }
Что то обсчитывается , массивы заполняются, лист точек заполняется. Вроде что-то работает. НО график строится прямая горизонтальная линия. Такого быть не может, должна какая то кривая получиться. И еще почему, если задать n=больше 8 (количество промежуточных точек нужно 100), то программа крашится и говорит что индекс лежит не в пределах массива. Так как я задаю 8 точек, то логично, что между ними мне нужно вычислить 100 промежуточных и построить график.
Наверное я как-то неправильно работаю с zedgraph, кто из знающих может увидеть ошибку?

Решение задачи: «Интерполяция почему-то рисует прямую линию»

textual
Листинг программы
  1. public class Lagrange : IRaschet
  2.     {
  3.         double[] x;
  4.         double[] y;    
  5.         public double Compute(double x, double[] volt, double[] sum) //нужно будет изменить интерфейс
  6.         {
  7.             double x0 = x; //точка, в которой нужно найти значение функции
  8.             x = sum; //массив известных X, не уверен, что тут правильно написано, что sum, а что volt
  9.             y = volt; //массив известных Y
  10.             double lagrangePol = 0;
  11.             int size = volt.Length; // размер массивов
  12.             for (int i = 0; i < size; i++)
  13.             {
  14.                 double basicsPol = 1;
  15.                 for (int j = 0; j < size; j++)
  16.                 {
  17.                     if (j != i)
  18.                     {
  19.                         basicsPol *= (x0 - x[j]) / (x[i] - x[j]);
  20.                     }
  21.                 }
  22.                 lagrangePol += basicsPol * y[i];
  23.             }
  24.             return lagrangePol;//значение функции в данной точке X.
  25.         }
  26.     }

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


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

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

11   голосов , оценка 4.091 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы