Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
19
Добавлен:
02.05.2014
Размер:
10.72 Кб
Скачать
#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;
}

Соседние файлы в папке term3.vmath.work4f