ВычМат / ВычМат(3)
.docxМИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
«КАЗАНСКИЙ (ПРИВОЛЖСКИЙ) ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»
НАБЕРЕЖНОЧЕЛНИНСКИЙ ИНСТИТУТ (ФИЛИАЛ)
КАФЕДРА ИНФОРМАЦИОННЫХ СИСТЕМ
ЛАБОРАТОРНАЯ РАБОТА №3
«Метод наименьших квадратов»
По дисциплине
«Вычислительная математика»
Выполнил:
Студент группы 2161121
Золотых С.В.
Проверил:
Мингалеева Л.Б.
Набережные Челны
2018
Цель
Табулировать функцию , получить 10 значений. Перебрать 7 основных функций, подсчитать сигма и выбрать наименьшее. (Должна получиться та функция, которую табулировали.)
Реализация
-
Табуляция функции:
-
Все последующие вычисления сводятся к вычислению формулы:
В формулах меняются только показатели . Параметры находятся из уравнения выше с помощью метода Крамера и обратной матрицы. Для примера приведено решение параметрической функции, которая и является искомой:
Таким образом:
Получаем:
Подставляем полученные параметры в параметрическую формулу и находим y*:
Находим отклонение от исходных данных с помощью формулы:
Отклонение равно нулю, значит эта формула подходит лучше всего.
Реализация в Excel
Реализация на языке C#
using System;
namespace Метод_наименьших_квадратов
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
double[] x = { 1, 1.5, 2 , 2.5, 3 , 3.5 ,4 , 4.5, 5, 5.5};
double[] y = { 0.18221188, 0.245960311, 0.332011692, 0.448168907, 0.604964746, 0.816616991, 1.102317638, 1.487973172, 2.008553692, 2.711263892 };
label2.Text = "Линейная функция: " + Convert.ToString(Lin(x,y));
label3.Text = "Показательная функция: " + Convert.ToString(Poc(x, y));
label4.Text = "Логарифмическая функция: " + Convert.ToString(Log(x, y));
label5.Text = "Степенная функция: " + Convert.ToString(Step(x, y));
label6.Text = "Обратная функция: " + Convert.ToString(Obr(x, y));
label7.Text = "Гиперболическая функция: " + Convert.ToString(Giper(x, y));
label8.Text = "Дробно-линейная функция: " + Convert.ToString(Drob(x, y));
}
public double Lin(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2=new double[10];
for (int i = 0; i < 10; i++)
{
Sum_X += x[i];
Sum_Y += y[i];
X_2 += Math.Pow(x[i],2);
X_Y += x[i] * y[i];
}
double det_A = X_2*10-Sum_X*Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y*10-Sum_Y*Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2*Sum_Y-X_Y*Sum_X;
//Находим значения переменных
double A = det_B / det_A;
double B = det_C / det_A;
for (int i = 0; i < 10; i++)
{
y_2[i] = A * x[i] + B;
sigma += Math.Pow((y[i] - y_2[i]),2);
}
return Math.Round(sigma,4);
}
public double Poc(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] y_3 = new double[10];
for (int i = 0; i < 10; i++)
{
y_3[i] = Math.Log(y[i]);
Sum_X += x[i];
Sum_Y += y_3[i];
X_2 += Math.Pow(x[i], 2);
X_Y += x[i] * y_3[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A = Math.Exp(det_B / det_A);
double B = Math.Exp(det_C / det_A);
for (int i = 0; i < 10; i++)
{
y_2[i] = B * (Math.Pow(A,x[i]));
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
public double Log (double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] x_2 = new double[10];
for (int i = 0; i < 10; i++)
{
x_2[i] = Math.Log(x[i]);
Sum_X += x_2[i];
Sum_Y += y[i];
X_2 += Math.Pow(x_2[i], 2);
X_Y += x_2[i] * y[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A =det_B / det_A;
double B = det_C / det_A;
for (int i = 0; i < 10; i++)
{
y_2[i] = A * x_2[i] + B;
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
public double Step(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] x_2 = new double[10];
double[] y_3 = new double[10];
for (int i = 0; i < 10; i++)
{
x_2[i] = Math.Log(x[i]);
y_3[i] = Math.Log(y[i]);
Sum_X += x_2[i];
Sum_Y += y_3[i];
X_2 += Math.Pow(x_2[i], 2);
X_Y += x_2[i] * y_3[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A = det_B / det_A;
double B = Math.Exp(det_C / det_A);
for (int i = 0; i < 10; i++)
{
y_2[i] = B*Math.Pow(x[i],A);
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
public double Obr(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] y_3 = new double[10];
for (int i = 0; i < 10; i++)
{
y_3[i] = 1/y[i];
Sum_X += x[i];
Sum_Y += y_3[i];
X_2 += Math.Pow(x[i], 2);
X_Y += x[i] * y_3[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A = det_B / det_A;
double B = det_C / det_A;
for (int i = 0; i < 10; i++)
{
double n = A * x[i] + B;
y_2[i] = 1/n;
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
public double Giper(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] x_2 = new double[10];
for (int i = 0; i < 10; i++)
{
x_2[i] = 1 / x[i];
Sum_X += x_2[i];
Sum_Y += y[i];
X_2 += Math.Pow(x_2[i], 2);
X_Y += x_2[i] * y[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A = det_B / det_A;
double B = det_C / det_A;
for (int i = 0; i < 10; i++)
{
y_2[i] = B + A*x_2[i];
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
public double Drob(double[] x, double[] y)
{
double X_2 = 0;
double sigma = 0;
double X_Y = 0, Sum_X = 0, Sum_Y = 0;
double[] y_2 = new double[10];
double[] x_2 = new double[10];
double[] y_3 = new double[10];
for (int i = 0; i < 10; i++)
{
x_2[i] = 1 / x[i];
y_3[i] = 1 / y[i];
Sum_X += x_2[i];
Sum_Y += y_3[i];
X_2 += Math.Pow(x_2[i], 2);
X_Y += x_2[i] * y_3[i];
}
double det_A = X_2 * 10 - Sum_X * Sum_X;
//Определитель первой вспомогательной матрицы
double det_B = X_Y * 10 - Sum_Y * Sum_X;
//Определитель второй вспомогательной матрицы
double det_C = X_2 * Sum_Y - X_Y * Sum_X;
//Находим значения переменных
double A = det_B / det_A;
double B = det_C / det_A;
for (int i = 0; i < 10; i++)
{
double n = B *x[i] + A;
y_2[i] = x[i]/n;
sigma += Math.Pow((y[i] - y_2[i]), 2);
}
return Math.Round(sigma, 4);
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Вывод
Реализовала метод наименьших квадратов, предназначенный для нахождения минимума суммы квадратов отклонений некоторых функций от искомых переменных. Была реализована табуляция заданной параметрической функции, затем преобразование полученных данных в других функциях с целью нахождения наименьшего отклонения. Так же были применены методы решения СЛАУ, изученные в первой лабораторной, для нахождения параметров.