
Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №4 / term3.vmath.work4d / 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, FunctionDerivative derivative, ItitializeParams init)
: m_Function(value), m_Derivative(derivative), 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, &PowerDerivative, &PowerInitialize)));
FunctionList->Items->AddObject("f(x)=A*sin(B*x)+C*cos(D*x)", (TObject*)(new IntegrableFunction(&SinAddCosFunction, &SinAddCosDerivative, &SinAddCosInitialize)));
FunctionList->Items->AddObject("f(x)=A*sin(B*x)*cos(C*x)", (TObject*)(new IntegrableFunction(&SinMulCosFunction, &SinMulCosDerivative, &SinMulCosInitialize)));
FunctionList->Items->AddObject("f(x)=A*x^B*kor(C^2+x^2)", (TObject*)(new IntegrableFunction(&PowKorFunction, &PowKorDerivative, &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);
}
double __fastcall TMainForm::PowerFunction(double &x) { return m_A*pow(x, m_B); }
double __fastcall TMainForm::PowerDerivative(int n, double &x) {
return m_A*pow(m_B, n)*pow(x, m_B-n);
}
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;
}
double __fastcall TMainForm::SinAddCosFunction(double &x) { return m_A*sin(m_B*x)+m_C*cos(m_D*x); }
double __fastcall TMainForm::SinAddCosDerivative(int n, double &x) {
return 0;
}
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;
}
double __fastcall TMainForm::SinMulCosFunction(double &x) { return m_A*sin(m_B*x)*cos(m_C*x); }
double __fastcall TMainForm::SinMulCosDerivative(int n, double &x) {
return 0;
}
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;
}
double __fastcall TMainForm::PowKorFunction(double &x) { return m_A*pow(x, m_B)*sqrt(m_C*m_C+x*x); }
double __fastcall TMainForm::PowKorDerivative(int n, double &x) {
double sq = sqrt(m_C*m_C+x*x);
if (n==1) return m_A*pow(x, m_B)*(m_B*sq/x+2.0*x/sq);
if (n==2) return m_A*pow(x, m_B)*(m_B*m_B*sq/(x*x)*((2.0*x-1.0)/m_B)+2.0*m_B/sq-m_B*x/(pow(sq, 3.0)));
/*
return (PowKorDerivative(n-1, x+m_DerEps)-PowKorDerivative(n-1, x))/m_DerEps;
*/
return 0;
}
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;
}
double __fastcall TMainForm::IntegralLeftRect(double h) {
double j = 0.0, yi;
for (double xi=m_XMin; xi<=m_XMax-h; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
double __fastcall TMainForm::IntegralRightRect(double h) {
double j = 0.0, yi;
for (double xi=m_XMin+h; xi<=m_XMax; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
double __fastcall TMainForm::IntegralCenterRect(double h) {
double j = 0.0, yi;
for (double xi=m_XMin+h/2.0; xi<=m_XMax-h/2.0; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
double __fastcall TMainForm::IntegralTrapezium(double h) {
double j = (m_Function(m_XMin)+m_Function(m_XMax))/2.0, yi;
for (double xi=m_XMin+h; xi<=m_XMax-h; xi+=h) {
yi = m_Function(xi);
j += yi;
}
return j*h;
}
double __fastcall TMainForm::IntegralParabola(double h) {
double j = m_Function(m_XMin)+m_Function(m_XMax), yi;
for (double xi=m_XMin+h; xi<=m_XMax-h; xi+=h) {
yi = 2.0*m_Function(xi);
j += yi;
}
for (double 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, -6.0);
m_Function = ((IntegrableFunction*)(FunctionList->Items->Objects[FunctionList->ItemIndex]))->m_Function;
m_Derivative = ((IntegrableFunction*)(FunctionList->Items->Objects[FunctionList->ItemIndex]))->m_Derivative;
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();
double 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);
double *j = new double[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++) {
double k = (i>1) ? (j[i-2]-j[i-1])/(j[i-1]-j[i]) : m_K;
OutputGrid->Cells[0][i+1] = FormatFloat("0", pow(2.0, i));
if (i>1) {
OutputGrid->Cells[1][i+1] = FormatFloat("0.00000000E+00", k);
} else {
OutputGrid->Cells[1][i+1] = " --- ";
}
OutputGrid->Cells[2][i+1] = FormatFloat("0.00000000E+00", fabs(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] = " --- ";
}
double h = (m_XMax-m_XMin)/pow(2.0, i);
double max = -1.0e299;
for (double xi=m_XMin; xi<=m_XMax; xi+=h) {
double der = fabs(m_Derivative(m_K, xi));
if (der>max) max = der;
}
double c = (m_XMax-m_XMin)*max/m_Mdiv;
if (fabs(c)<1.0e-200) {
OutputGrid->Cells[4][i+1] = " --- ";
} else {
OutputGrid->Cells[4][i+1] = FormatFloat("0.00000000E+00", c*pow(h, m_K));
}
}
delete[] j;
this->ValidateData();
}
double __fastcall TMainForm::DefDerivative(int n, double x) {
if (n>0) {
return (DefDerivative(n-1, x+m_DerEps)-DefDerivative(n-1, x-m_DerEps))/(2.0*m_DerEps);
} 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;
}