Разработка полноценных Windows-приложений
3. Построение системы линейных уравнений и ее решение
Для построения системы линейных уравнений будем использовать шаблонный класс матриц matrix<type>. Этот класс выделен в отдельный заголовочный файл matrix.h. Его необходимо скопировать в каталог с проектом и добавить в проект с помощью утилиты Solution Explorer (вызвать контекстное меню проекта в окне утилиты Solution Explorer
Add
Existing item… и далее указать имя файла). Полный код класса приведен в приложении. Напишем функции для поиска обратной матрицы. Введем их в файле RegrDlg.cpp после строк.
#include "stdafx.h" #include "Regr.h" #include "RegrDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif
Функции для поиска обратной матрицы:
//Функции для решения СЛАУ методом окаймления
matrix<double> bordering (matrix<double> u, matrix<double> v,
matrix<double> A, matrix<double> a)
{
matrix<double> b = a - u*A*v;
b.setcell(1/b.getcell(0,0),0,0);
matrix<double> s = -u*A*b.getcell(0,0);
matrix<double> w = -A*v*b.getcell(0,0);
matrix<double> B = A - A*v*s;
B.addcolend(w);
s.addcolend(b);
B.addrowend(s);
return B;
}
matrix>double> getreverse (matrix<double> M)
{
matrix<double> Res;
if(M.getcolsize() == M.getrowsize())
{
Res = M.getminor(0,0,0,0);
Res.setcell(1/Res.getcell(0,0),0,0);
for(uni i = 1; i < M.getcolsize(); i++)
{
matrix<double> v = M.getminor(i,0,i,i-1);
matrix<double> u = M.getminor(0,i,i-1,i);
matrix<double> a = M.getminor(i,i,i,i);
Res = bordering(u,v,Res,a);
}
}
return Res;
}Для формирования и решения системы мы создали кнопку Start approximation. Обработаем нажатие на нее. Обработчик нажатия на кнопку Start approximation:
void CRegrDlg::OnBnClickedButtonStart()
{
UpdateData(true);
CRichEditCtrl *pRich = (CRichEditCtrl *) GetDlgItem(IDC_RICHEDIT_RES); //Переменная для управления RichEditom
if(mNum >= mInitArr.GetSize()) //Если данные не соответствуют
{
pRich->SetWindowTextA(CString("Number of points mismatches approximation degree")); //Выводим предупреждение
return; //Выходим
}
mNodeMatrix.setsize(mNum + 1,mNum + 1); //Задаем размерность матрицы для поиска коэффициентов
int n = (int) mInitArr.GetSize();
for(int i = 0; i < mNum + 1; i++) //Идем по строкам матрицы
for(int j = 0; j < mNum + 1; j++) //Идем по столбцам матрицы
{
double elem = 0; //вспомогательная переменная
for(int k = 0; k < n; k++) //Идем по точкам таблицы
elem += pow(mInitArr[k].x,(double)i+j); //Формируем элемент матрицы
mNodeMatrix.setcell(elem/n,j,i); //Инициализируем элемент матрицы
}
mRightPart.setsize(1,mNum + 1); //Задаем размерностьправой части системы
for(int i = 0; i < mNum + 1; i++) //Идем по строкам правой части
{
double elem = 0; //Вспомогательный элемент
for(int k = 0; k < n; k++) //Идем по точкам таблицы
elem += mInitArr[k].y*pow(mInitArr[k].x,(double)i); //Формируем элемент правой части
mRightPart.setcell(elem/n,0,i); //Инициализируем элемент правой части
}
matrix<double> Solution(::getreverse(mNodeMatrix)*mRightPart); //Решаем уравнение
CString str; //Строка для вывода результатов
str.Format("f(x) = %f",Solution.getcell(0,0));
//Формируем строку полинома
for(uni i = 1; i < Solution.getrowsize(); i++)
{
CString temp;
temp.Format(" + %f*x^%d",Solution.getcell(0,i),i);
str += temp;
}
pRich->SetWindowTextA(str); //Выводим ее
}4. Вывод информации
Вывод осуществляется в двух направлениях: вывод таблицы узлов и вывод аналитической формулы полинома. За вывод узлов отвечает элемент управления списковое представление, код вывода точек в таблице представлен в обработчиках кнопок Add и Delete. За вывод формулы полинома отвечает элемент управления текстовое поле с форматированием, код вывода формулы приведен в обработчике кнопик Start approximation. Для завершения программы добавим строку:
#include "matrix.h"
в файл RegrDlg.h перед описанием класса SDPoint. Скомпилируем и запустим приложение. В результате в соответствии с введенными данными должно получиться следующее: рис. 5.10
