Интерполяция почему-то рисует прямую линию - C#
Формулировка задачи:
Может быть я до конца не понимаю смысл полиномов. Однако вроде я использую верные формулы для интерполяции. Собственно есть 4 метода интерполяции: Полином Лагранжа, Полином Ньютона, Кубический сплайн(alglib), линейная интерполяция. Проблему можно рассматривать на любом методе. В общем в создал я метод интерполяции
В весь код можно не вникать. В код для расчёта полинома передаю массивы sum и volt в качестве аргументов x и y.
Далее строю график с помощью zedgraph
Что то обсчитывается , массивы заполняются, лист точек заполняется. Вроде что-то работает. НО график строится прямая горизонтальная линия. Такого быть не может, должна какая то кривая получиться. И еще почему, если задать n=больше 8 (количество промежуточных точек нужно 100), то программа крашится и говорит что индекс лежит не в пределах массива. Так как я задаю 8 точек, то логично, что между ними мне нужно вычислить 100 промежуточных и построить график.
public interface IRaschet { double Compute(double[] volt, double[] sum); } public class Lagrange : IRaschet { double[] x; double[] y; public double Compute(double[] volt, double[] sum) { double x0 = sum[1]; x = sum; y = volt; double lagrangePol = 0; int size = 100; for (int i = 0; i < size; i++) { double basicsPol = 1; for (int j = 0; j < size; j++) { if (j != i) { basicsPol *= (x0 - x[j]) / (x[i] - x[j]); } } lagrangePol += basicsPol * y[i]; } return lagrangePol; } } public class Spline : IRaschet { public double Compute(double[] volt, double[] sum) { // * x - abscissas // * y - vector of experimental data, straight line with small noise double[] x; double[] y; x = volt; y = sum; int info; double v; alglib.spline1dinterpolant s; alglib.spline1dfitreport rep; double rho; rho = -5.0; alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep); //System.Console.WriteLine("{0}", info); // EXPECTED: 1 v = alglib.spline1dcalc(s, 0.0); //System.Console.WriteLine("{0:F1", v); // EXPECTED: 0.10 rho = +10.0; alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep); //System.Console.WriteLine("{0}", info); // EXPECTED: 1 v = alglib.spline1dcalc(s, 1.0); //System.Console.WriteLine("{0:F2", v); // EXPECTED: 0.969 rho = +3.0; alglib.spline1dfitpenalized(x, y, 50, rho, out info, out s, out rep); //System.Console.WriteLine("{0}", info); // EXPECTED: 1 //System.Console.ReadLine(); return v; } } public class Newton : IRaschet { public double Compute(double[] volt, double[] sum) { double t=1; int n=100; double[] x = volt; double[] y = sum; double res = y[0], F, den; int i, j, k; for (i = 1; i <= n; i++) { F = 0; for (j = 0; j <= i; j++) { den = 1; for (k = 0; k <= i; k++) { if (k != j) den *= (x[j] - x[k]); } F += y[j] / den; } for (k = 0; k < i; k++) F *= (t - x[k]); res += F; } return res; } } public class Linear : IRaschet { public double Compute(double[] volt, double[] sum) { Form1 objForm1 =new Form1(); double a; double b; double ux; double uxx=1; double mx; mx = 50; double[] mass; mass = new double[] { 1000, 2000, 3000, 4000, 5000 }; int n = 5; double[] uz; uz = volt; double[] yz; yz = sum; int beg = 0; int end = 0; double Ybeg = 0; double Yend = 0; for (int i = 0; i < n - 1; i++) { if (mass[i] <= mx && mass[i] <= mx) { beg = i; end = i + 1; } Ybeg = uz[beg]; Yend = uz[end]; a = (Yend - Ybeg) / (mass[end] - mass[beg]); b = Ybeg - a * mass[beg]; ux = a * mx + b; objForm1.textBox2.Text = (ux).ToString(); Ybeg = yz[beg]; Yend = yz[end]; a = (Yend - Ybeg) / (mass[end] - mass[beg]); b = Ybeg - a * mass[beg]; uxx = a * mx + b; objForm1.textBox10.Text = (uxx).ToString(); } return uxx; } }
private IRaschet Extra; public double[,] Pts = new double[8, 2]; public double[] sum = new double[8]; public double[] volt = new double[8]; private void formSumArray() { sum[0] = Convert.ToDouble(textBox2.Text); sum[1] = Convert.ToDouble(textBox3.Text); sum[2] = Convert.ToDouble(textBox4.Text); sum[3] = Convert.ToDouble(textBox5.Text); sum[4] = Convert.ToDouble(textBox6.Text); sum[5] = Convert.ToDouble(textBox7.Text); sum[6] = Convert.ToDouble(textBox8.Text); sum[7] = Convert.ToDouble(textBox9.Text); { volt[0] = 0f; volt[1] = 1f; volt[2] = 2f; volt[3] = 3f; volt[4] = 4f; volt[5] = 5f; volt[6] = 6f; volt[7] = 6.2f; } for (int a = 0; a < volt.Length; a++) { Pts[a, 0] = volt[a]; Pts[a, 1] = sum[a]; } } private void button3_Click(object sender, EventArgs e) { // ВЫЗЫВАЕТЕ МЕТОД COMPUTE formSumArray(); GraphPane pane = zedGraphControl1.GraphPane; GraphControl("Величина", "Напряжение", "График"); // для первого вызова // Создадим список точек PointPairList list = new PointPairList(); double xmin = 0; double xmax = 10; // Заполняем список точек for (double x = xmin; x <= xmax; x += 0.01) { // добавим в список точку list.Add(x, Extra.Compute(volt, sum)); } // Создадим кривую с названием "Sinc", // которая будет рисоваться голубым цветом (Color.Blue), // Опорные точки выделяться не будут (SymbolType.None) LineItem myCurve = pane.AddCurve("Sinc", list, Color.Blue, SymbolType.None); // Вызываем метод AxisChange (), чтобы обновить данные об осях. // В противном случае на рисунке будет показана только часть графика, // которая умещается в интервалы по осям, установленные по умолчанию zedGraphControl1.AxisChange(); // Обновляем график zedGraphControl1.Invalidate(); }
Наверное я как-то неправильно работаю с zedgraph, кто из знающих может увидеть ошибку?
Решение задачи: «Интерполяция почему-то рисует прямую линию»
textual
Листинг программы
public class Lagrange : IRaschet { double[] x; double[] y; public double Compute(double x, double[] volt, double[] sum) //нужно будет изменить интерфейс { double x0 = x; //точка, в которой нужно найти значение функции x = sum; //массив известных X, не уверен, что тут правильно написано, что sum, а что volt y = volt; //массив известных Y double lagrangePol = 0; int size = volt.Length; // размер массивов for (int i = 0; i < size; i++) { double basicsPol = 1; for (int j = 0; j < size; j++) { if (j != i) { basicsPol *= (x0 - x[j]) / (x[i] - x[j]); } } lagrangePol += basicsPol * y[i]; } return lagrangePol;//значение функции в данной точке X. } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д