Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ_ВМ_2010.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
2.55 Mб
Скачать

Лабораторная работа 6

АППРОКСИМАЦИЯ ФУНКЦИИ ПО МЕТОДУ НАИМЕНЬШИХ КВАДРАТОВ

Задание. Выполнить аппроксимацию таблично заданной функции полиномом m-й степени по методу наименьших квадратов. Вывести параметры аппроксимирующего полинома, график полинома и нанести на график исходные данные.

  1. Создайте новый проект командой Файл/Новый/Приложение.

  2. Сохраните файлы модуля и проекта командой Файл/Сохранить все под именами LR6 и PR_LR6. Для этого удобно использовать соответствующую быструю кнопку (Сохранить все). В последующих сеансах работы сохраненный проект можно открыть командой Файл/Открыть проект (или Повторно открыть). Теперь перейдем к проектированию приложения - переносам на форму необходимых компонентов и заданию их свойствам значений, а в обработчиках событий – размещению кодов соответствующих алгоритмов. (Рекомендуется нажимать кнопку Сохранить все по окончании работы с каждым компонентом.) В результате проектирования получим форму, представленную на рис.6.1.

  3. Выделите форму, щелкнув на ней левой кнопкой мыши, и в свойство Caption (надпись) впишите АППРОКСИМАЦИЯ ФУНКЦИИ ПО МЕТОДУ НАИМЕНЬШИХ КВАДРАТОВ.

  4. На форме разместите 4 кнопки (страница Стандарт) с надписями соответственно: Button1 - ИСХОДНЫЕ ДАННЫЕ, Button2 - РАСЧЕТ КОЭФФИЦИЕНТОВ, Button3 - ГРАФИКИ, Button4 – КОНЕЦ.

  5. Для размещения исходных данных используйте в качестве таблицы компонент StringGrid1 (страница Дополнительно). Установите следующие значения свойств компонента StringGrid1: ColCount – 21, DefaultColWidth -32, FixedCols – 1, FixedRows – 0, Font – черный, обычный, размер 8, RowCount – 3. Раскрыв свойство Options, установите значение подсвойства goEditingtrue, что даст возможность редактировать содержимое таблицы в StringGrid1.

рис.6.1

рис.6.2

рис.6.3

  1. Для задания степени аппроксимирующего многочлена используйте метку LabeledEdit1 (страница Дополнительно). Свойству LabelPosition присвойте значение lpLeft (из выпадающего списка), а свойству Font – жирный, размер 8, свойству Text – 2. Раскрыв свойство EditLabel, установите подсвойство Font – жирный, размер 8, а в подсвойстве Caption впишите соответственно m=.

  2. Для размещения результатов расчетов коэффициентов аппроксимирующего многочлена используйте компонент ValueListEditor1 (страница Дополнительно). Компонент содержит строки вида «имя = значение». Окно компонента имеет две колонки с заголовками «Key» для имен и «Value» для значений. Измените эти значения, используя свойство TitleCaptions типа TStrings. Нажатием на кнопку (три точки) свойства вызовите окно Редактор строки списка, в первой строке которого напишите коэффициент, во второй – значение. Значения других свойств установите такими: Font – черный, обычный, размер 8, DefaultRowHeight – 18, DefaultColWidth – 75.

  3. Для графического представления исходных данных и аппроксимирующего многочлена используйте компонент Chart1 (страница Additional). Зададим свойства компонента. Щелкните правой кнопкой мыши на компоненте Chart1 и в появившемся меню выберите Edit Chart…. На экране появится окно Редактора Диаграмм (Editing Chart1) с открытой страницей Chart, которая имеет несколько закладок. На закладке Panel, нажав кнопку Panel Color, выберите белый цвет. На закладке Series щелкните на кнопке Add - добавить серию. В появившемся окне выберите тип графика – Point и выключите индикатор 3D. После щелчка на OK снова появится окно Editing Chart1. Перейдите на закладку Titles. В окне редактирования, которое в данный момент соответствует Title – заголовку графика, сотрите TChart и напишите (шрифт Font - черный, жирный, размер 10) ТАБЛИЧНАЯ И РАСЧЕТНАЯ ЗАВИСИМОСТИ. Цвет фона Back Color.. установите белый. В выпадающем списке от окна редактирования Title перейдите в окно редактирования Foot и напишите тем же шрифтом аргумент X. В группе кнопок Alignment нажмите кнопку Right. Цвет фона Back Color.. также установите белый. Перейдите на закладку Axis для задания координатных характеристик осей. Оставьте в группе Axis нажатой кнопку Left и включенным индикатор Automatic. Затем нажмите в группе Axis кнопку Bottom и выключите индикатор Automatic. Нажмите среднюю кнопку Changeи в окне Value редактора Minimum Bottom Axis впишите число 0. Аналогичные действия выполните с верхней кнопкой Change, но впишите число 2. И, нажав нижнюю кнопку Change, в окно Increment: занесите 0,2. Перейдите на закладку Series, кнопкой Addдобавьте график Line при выключенном индикаторе 3D . Выделив Series 1, кнопкой Title… вызовите Change Series Title, где дайте заголовок первому графику – исходные данные. Действуя подобным образом, т.е. выделив Series 2, дайте заголовок второму графику – аппроксимирующий полином. На вкладке Legend нажмите кнопку Top. Перейдите со страницы Chart на страницу Series. Здесь на закладке Format задают параметры линий графиков. Требуемый график (исходные данные, аппроксимирующий полином) выбирается из выпадающего списка. Для графика исходные данные установите размеры прямоугольника: Width=2, Height=2, а нажав кнопку Border, задайте толщину линии графика Width=1, и цвет линии графика Color - черный. Для графика аппроксимирующий полином в группе Line через кнопку Borderустанавливается толщина (Width=2) линии графика, и через кнопку Color - цвет линии графика – черный. Выключите индикатор Color Each.

  4. Файл LR6.cpp с обработчиками щелчков на кнопках имеет вид:

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "LR6.h"

#include<math.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

const int n=20;

double x[n+1]={0.0};

double y[n+1]={0.0,-3.97,-4.07,-4.04,-4.30,-4.27,-4.54,-4.79,-5.07,-5.30,

-5.51,-5.83,-6.06,-6.40,-6.83,-7.54,-7.68,-8.36,-8.91,-9.39,-9.98};

void __fastcall TForm1::Button1Click(TObject *Sender)

{

ValueListEditor1->Strings->Clear();

Series1->Clear();

Series2->Clear();

StringGrid1->Cells[0][0]="i";

StringGrid1->Cells[0][1]="x[i]";

StringGrid1->Cells[0][2]="y[i]";

for(int i=1;i<n+1;i++){

StringGrid1->Cells[i][0]=IntToStr(i);

x[i]=i*0.1;

StringGrid1->Cells[i][1]=FloatToStrF(x[i],ffFixed,2,2);

StringGrid1->Cells[i][2]=FloatToStrF(y[i],ffFixed,3,2);}

LabeledEdit1->SetFocus();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{ ValueListEditor1->Strings->Clear();

Series1->Clear();

Series2->Clear();

int m=StrToInt(LabeledEdit1->Text);

float c,b,s,*p,**a;

p=new float[m+1];

a=new float*[m+1];

for(int i=0;i<m+1;i++)

a[i]=new float[m+2];

for(int r=0;r<m+1;r++){

a[r][m+1]=0;

for(int i=1;i<n+1;i++)

a[r][m+1]+=pow(x[i],r)*StrToFloat(StringGrid1->Cells[i][2]);

for(int c=0;c<m+1;c++){

a[r][c]=0;

for(int i=1;i<n+1;i++)

a[r][c]+=pow(x[i],r+c);}}

for(int i=0;i<m;i++){

c=a[i][i];

for(int j=i;j<m+2;j++) a[i][j]/=c;

for(int k=i+1;k<m+1;k++){

b=a[k][i];

for(int l=i;l<m+2;l++)

a[k][l]=a[k][l]-b*a[i][l];}}

p[m]=a[m][m+1]/a[m][m];

for(int k=m-1;k>=0;k--){

s=0;

for(int j=k+1;j<m+1;j++) s+=a[k][j]*p[j];

p[k]=a[k][m+1]-s;}

AnsiString st,st1;;

for(int i=0;i<=m;i++){

st=" p["+IntToStr(i)+"]";

st1=" "+FloatToStrF(p[i],ffGeneral,5,2);

ValueListEditor1->Values[st]=st1;}

delete []p; p=0;

for(int i=0;i<=m;i++)delete []a[i];

delete []a; a=0;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

{float x1,p,pol;

int m=StrToInt(LabeledEdit1->Text);

Series1->Clear();

Series2->Clear();

for(int i=1;i<n+1;i++){

Series1->AddXY(x[i],StrToFloat(StringGrid1->Cells[i][2]),"",clBlack); }

for(x1=0;x1<=2;x1+=0.001){

pol=0;

for(int k=0;k<=m;k++){

p=StrToFloat(ValueListEditor1->Cells[1][k+1]);

if(k)pol+=p*pow(x1,k);

else pol+=p;}

Series2->AddXY(x1,pol,"",clBlack);}

}

//---------------------------------------------------------------------------

  1. Запустим приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск. После щелчков на кнопках ИСХОДНЫЕ ДАННЫЕ, РАСЧЕТ КОЭФФИЦИЕНТОВ, ГРАФИКИ, получим результаты выполнения задания (рис.6.2).

  2. Объясните результаты при m=0 и при m=1.

  3. Воспользуемся тем, что таблица ИСХОДНЫЕ ДАННЫЕ позволяет редактировать значения y[i]. Изменив два значения, а также порядок аппроксимирующего многочлена, после щелчков на кнопках РАСЧЕТ КОЭФФИЦИЕНТОВ, ГРАФИКИ, получим результаты (рис.6.3), которые убедительно показывают, что аппроксимация эффективно ослабляет влияние выбросов в исходных данных, что полезно при обработке результатов экспериментов.

  4. Для возврата к первоначальным исходным данным достаточно щелкнуть на кнопке ИСХОДНЫЕ ДАННЫЕ.

  5. Щелчком на кнопке конец выйдите из режима выполнения и перейдите в режим проектирования приложения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]