Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №4 / term3.vmath.work4f / frmmain
.cpp#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "frmmain.h"
#pragma package(smart_init)
#pragma link "RzEdit"
#pragma link "RzSpnEdt"
#pragma link "RzCmboBx"
#pragma link "RzPanel"
#pragma link "RzButton"
#pragma resource "*.dfm"
bool waserrors = false;
int _matherr(struct _exception *e) {
waserrors = true;
return 1;
}
__fastcall IntegrableFunction::IntegrableFunction(FunctionValue value, ItitializeParams init)
: m_Function(value), m_Initialize(init) {}
__fastcall IntegrationMethod::IntegrationMethod(IntegralValue integral, int k, int mdiv)
: m_Integral(integral), m_K(k), m_Mdiv(mdiv) {}
TMainForm *MainForm;
__fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) {
}
void __fastcall TMainForm::FormCreate(TObject *Sender) {
FunctionList->Items->AddObject("f(x)=A*x^B", (TObject*)(new IntegrableFunction(&PowerFunction, &PowerInitialize)));
FunctionList->Items->AddObject("f(x)=A*sin(B*x)+C*cos(D*x)", (TObject*)(new IntegrableFunction(&SinAddCosFunction, &SinAddCosInitialize)));
FunctionList->Items->AddObject("f(x)=A*sin(B*x)*cos(C*x)", (TObject*)(new IntegrableFunction(&SinMulCosFunction, &SinMulCosInitialize)));
FunctionList->Items->AddObject("f(x)=A*x^B*kor(C^2+x^2)", (TObject*)(new IntegrableFunction(&PowKorFunction, &PowKorInitialize)));
FunctionList->ItemIndex = 0;
if (FunctionList->OnChange) FunctionList->OnChange(this);
MethodList->Items->AddObject("Метод левых прямоугольников", (TObject*)(new IntegrationMethod(&IntegralLeftRect, 1, 2)));
MethodList->Items->AddObject("Метод правых прямоугольников", (TObject*)(new IntegrationMethod(&IntegralRightRect, 1, 2)));
MethodList->Items->AddObject("Метод симметричных прямоугольников", (TObject*)(new IntegrationMethod(&IntegralCenterRect, 2, 24)));
MethodList->Items->AddObject("Метод трапеций", (TObject*)(new IntegrationMethod(&IntegralTrapezium, 2, 12)));
MethodList->Items->AddObject("Метод парабол", (TObject*)(new IntegrationMethod(&IntegralParabola, 4, 2880)));
MethodList->ItemIndex = 0;
if (MethodList->OnChange) MethodList->OnChange(this);
}
float __fastcall TMainForm::PowerFunction(float &x) { return m_A*pow(x, m_B); }
void __fastcall TMainForm::PowerInitialize() {
AParamEdit->Min = -1.0e299; AParamEdit->Max = 1.0e299;
AParamEdit->Value = 6.0;
BParamEdit->Min = -1.0e299; BParamEdit->Max = 1.0e299;
BParamEdit->Value = 5.0;
XMinEdit->Min = -1.0e4; XMinEdit->Max = 1.0;
XMaxEdit->Min = 0.0; XMaxEdit->Max = 1.0e299;
XMinEdit->Value = 0.0; XMaxEdit->Value = 1.0;
}
float __fastcall TMainForm::SinAddCosFunction(float &x) { return m_A*sin(m_B*x)+m_C*cos(m_D*x); }
void __fastcall TMainForm::SinAddCosInitialize() {
AParamEdit->Min = -1.0e299; AParamEdit->Max = 1.0e299;
AParamEdit->Value = 1.0;
BParamEdit->Min = -1.0e299; BParamEdit->Max = 1.0e299;
BParamEdit->Value = 1.0;
CParamEdit->Min = -1.0e299; CParamEdit->Max = 1.0e299;
CParamEdit->Value = 1.0;
DParamEdit->Min = -1.0e299; DParamEdit->Max = 1.0e299;
DParamEdit->Value = 1.0;
XMinEdit->Min = -1.0e299; XMinEdit->Max = M_PI;
XMaxEdit->Min = -M_PI; XMaxEdit->Max = 1.0e299;
XMinEdit->Value = -M_PI; XMaxEdit->Value = M_PI;
}
float __fastcall TMainForm::SinMulCosFunction(float &x) { return m_A*sin(m_B*x)*cos(m_C*x); }
void __fastcall TMainForm::SinMulCosInitialize() {
AParamEdit->Min = -1.0e299; AParamEdit->Max = 1.0e299;
AParamEdit->Value = 1.0;
BParamEdit->Min = -1.0e299; BParamEdit->Max = 1.0e299;
BParamEdit->Value = 1.0;
CParamEdit->Min = -1.0e299; CParamEdit->Max = 1.0e299;
CParamEdit->Value = 1.0;
XMinEdit->Min = -1.0e299; XMinEdit->Max = M_PI;
XMaxEdit->Min = -M_PI; XMaxEdit->Max = 1.0e299;
XMinEdit->Value = -M_PI; XMaxEdit->Value = M_PI;
}
float __fastcall TMainForm::PowKorFunction(float &x) { return m_A*pow(x, m_B)*sqrt(m_C*m_C+x*x); }
void __fastcall TMainForm::PowKorInitialize() {
AParamEdit->Min = -1.0e299; AParamEdit->Max = 1.0e299;
AParamEdit->Value = 1.0;
BParamEdit->Min = -1.0e29; BParamEdit->Max = 1.0e299;
BParamEdit->Value = 0.1;
CParamEdit->Min = -1.0e299; CParamEdit->Max = 1.0e299;
CParamEdit->Value = 1.0;
XMinEdit->Min = 1.0e-4; XMinEdit->Max = 1.5;
XMaxEdit->Min = 0.0; XMaxEdit->Max = 1.0e299;
XMinEdit->Value = 0.001; XMaxEdit->Value = 1.5;
}
float __fastcall TMainForm::IntegralLeftRect(float h) {
float j = 0.0, yi;
for (float xi=m_XMin; xi<=m_XMax-h; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
float __fastcall TMainForm::IntegralRightRect(float h) {
float j = 0.0, yi;
for (float xi=m_XMin+h; xi<=m_XMax; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
float __fastcall TMainForm::IntegralCenterRect(float h) {
float j = 0.0, yi;
for (float xi=m_XMin+h/2.0; xi<=m_XMax-h/2.0; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
float __fastcall TMainForm::IntegralTrapezium(float h) {
float j = (m_Function(m_XMin)+m_Function(m_XMax))/2.0, yi;
for (float xi=m_XMin+h; xi<=m_XMax-h; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
float __fastcall TMainForm::IntegralParabola(float h) {
float j = m_Function(m_XMin)+m_Function(m_XMax), yi;
for (float xi=m_XMin+h; xi<=m_XMax-h; xi+=h) {
yi = 2.0*m_Function(xi);
j += yi;
}
for (float xi=m_XMin+h/2.0; xi<=m_XMax-h/2.0; xi+=h) {
yi = 4.0*m_Function(xi);
j += yi;
}
return j*h/6.0;
}
void __fastcall TMainForm::FunctionListChange(TObject *Sender) {
((IntegrableFunction*)(FunctionList->Items->Objects[FunctionList->ItemIndex]))->Initialize();
}
void __fastcall TMainForm::NMaxEditButtonClick(TObject *Sender, TSpinButtonType Button) {
int value = log(NMaxEdit->Value)/log(2.0);
if (fabs(exp(value*log(2.0))-NMaxEdit->Value)>=0.5) value+=1;
if (Button==sbUp) { value+=1; } else { value-=1; }
NMaxEdit->Value = exp(value*log(2.0));
}
void __fastcall TMainForm::NMaxEditExit(TObject *Sender) {
NMaxEdit->Value = exp((int)(log(NMaxEdit->Value)/log(2.0))*log(2.0));
}
void __fastcall TMainForm::PrepareData() {
m_A = AParamEdit->Value;
m_B = BParamEdit->Value;
m_C = CParamEdit->Value;
m_D = DParamEdit->Value;
m_XMin = XMinEdit->Value;
m_XMax = XMaxEdit->Value;
m_JExact = JExactEdit->Value;
m_NMax = NMaxEdit->Value;
m_Eps = pow(10.0, EpsEdit->Value);
m_DerEps = pow(10.0, DerEpsEdit->Value);
m_Function = ((IntegrableFunction*)(FunctionList->Items->Objects[FunctionList->ItemIndex]))->m_Function;
m_Integral = ((IntegrationMethod*)(MethodList->Items->Objects[MethodList->ItemIndex]))->m_Integral;
m_K = ((IntegrationMethod*)(MethodList->Items->Objects[MethodList->ItemIndex]))->m_K;
m_Mdiv = ((IntegrationMethod*)(MethodList->Items->Objects[MethodList->ItemIndex]))->m_Mdiv;
waserrors = false;
ErrorLabel->Visible = false;
}
void __fastcall TMainForm::ValidateData() {
ErrorLabel->Visible = waserrors;
}
void __fastcall TMainForm::XMinEditChange(TObject *Sender) {
XMaxEdit->Min = XMinEdit->Value;
}
void __fastcall TMainForm::XMaxEditChange(TObject *Sender) {
XMinEdit->Max = XMaxEdit->Value;
}
void __fastcall TMainForm::EpsEditChange(TObject *Sender) {
JExactEdit->Decimals = -EpsEdit->Value;
}
void __fastcall TMainForm::EvaluateExactButtonClick(TObject *Sender) {
if ((MethodList->ItemIndex<3)&&(MessageDlg("Расчет точного значения методом прямоугольников может занять значительное время.\nПродолжить?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0)==mrNo)) return;
this->PrepareData();
float j = 1.0e299, jj;
int n = 1;
do {
n*=2;
jj = j;
j = m_Integral((m_XMax-m_XMin)/(1.0*n));
} while (fabs(jj-j)/3.0>m_Eps);
JExactEdit->Value = j;
JExactEdit->Decimals = -EpsEdit->Value;
this->ValidateData();
}
void __fastcall TMainForm::IntegrateFunctionButtonClick(TObject *Sender) {
this->PrepareData();
int imax = log(m_NMax)/log(2.0);
float *j = new float[imax+1];
for (int i=0; i<=imax; i++) {
j[i] = m_Integral((m_XMax-m_XMin)/pow(2.0, i));
}
OutputGrid->ColCount = 5;
OutputGrid->RowCount = imax+2;
OutputGrid->FixedRows = 1;
OutputGrid->ColWidths[0] = 50; OutputGrid->Cells[0][0] = " N";
OutputGrid->ColWidths[1] = 100; OutputGrid->Cells[1][0] = " KD";
OutputGrid->ColWidths[2] = 100; OutputGrid->Cells[2][0] = " Dточн";
OutputGrid->ColWidths[3] = 100; OutputGrid->Cells[3][0] = " Dрунге";
OutputGrid->ColWidths[4] = 100; OutputGrid->Cells[4][0] = " Dтеор";
for (int i=0; i<=imax; i++) {
OutputGrid->Cells[0][i+1] = FormatFloat("0", pow(2.0, i));
if (i>1) {
OutputGrid->Cells[1][i+1] = FormatFloat("0.00000000E+00", (j[i-1]-j[i])/(j[i-2]-j[i-1]));
} else {
OutputGrid->Cells[1][i+1] = " --- ";
}
OutputGrid->Cells[2][i+1] = FormatFloat("0.00000000E+00", m_JExact-j[i]);
if (i>0) {
OutputGrid->Cells[3][i+1] = FormatFloat("0.00000000E+00", (j[i-1]-j[i])/(pow(2.0, m_K)-1.0));
} else {
OutputGrid->Cells[3][i+1] = " --- ";
}
float h = (m_XMax-m_XMin)/pow(2.0, i);
float max = -1.0e299;
for (float xi=m_XMin; xi<=m_XMax; xi+=h) {
float der = fabs(Derivative(m_K, xi));
if (der>max) max = der;
}
float c = (m_XMax-m_XMin)*max/m_Mdiv;
OutputGrid->Cells[4][i+1] = FormatFloat("0.00000000E+00", c*pow(h, m_K));
}
delete[] j;
this->ValidateData();
}
float __fastcall TMainForm::Derivative(int n, float x) {
if (n>0) {
return (Derivative(n-1, x+m_DerEps)-Derivative(n-1, x-m_DerEps))/(2.0*m_DerEps);
/*
float eps = m_DerEps;
float der = (Derivative(n-1, x+eps)-Derivative(n-1, x-eps))/(2.0*eps), der0;
do {
der0 = der;
eps *= 0.1;
der = (Derivative(n-1, x+eps)-Derivative(n-1, x-eps))/(2.0*eps);
} while (fabs(der-der0)>m_DerEps);
return der;
*/
} else {
return m_Function(x);
}
}
void __fastcall TMainForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) {
if (Key==16) AuthorLabel->Visible = true;
}
void __fastcall TMainForm::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) {
AuthorLabel->Visible = false;
}