//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <math.h>
#include "UnitRGR.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner){
}
//---------------------------------------------------------------------------
// Кнопка "Закрыть"
void __fastcall TForm1::Button3Click(TObject *Sender){
   Close();
}
//---------------------------------------------------------------------------
// Кнопка "Очистить"
void __fastcall TForm1::Button1Click(TObject *Sender){
   Edit1->Clear();Edit2->Clear();Edit3->Clear();Edit4->Clear();Edit5->Clear();Edit6->Clear();Edit7->Clear();Edit8->Clear();Edit9->Clear();Edit10->Clear();Edit11->Clear();Edit12->Clear();
   for (int i=0; i<=StringGrid1->ColCount; i++)
      for (int j=0; j<=StringGrid1->RowCount; j++)
         StringGrid1->Cells[i][j]="";
   for(int i=0;i<=Form1->Chart1->SeriesList->CountActive()-1;i++) Form1->Chart1->Series[i]->Clear();
}
//---------------------------------------------------------------------------
// Прототип нелинейное уравнение
double f(double);
// Прототип нахождение корня нелин. ур-я
bool Equat(double,double,double,int,double&,double&);
// Прототип табулирование функции
void Tab(double,double,double,double,double,double,int,double**,double**,double*,double*);
// Прототип вывод результатов
void RezOut(double,double,double*,double*,double**,double**,int,int);
//---------------------------------------------------------------------------
//Кнопка "Выполнить"
void __fastcall TForm1::Button2Click(TObject *Sender){
   // Ввод исходных данных
   double
      xn=StrToFloat(Edit1->Text),
      dx=StrToFloat(Edit2->Text),
      an=StrToFloat(Edit4->Text),
      ak=StrToFloat(Edit5->Text),
      da=StrToFloat(Edit6->Text),
      c=StrToFloat(Edit7->Text),
      d=StrToFloat(Edit8->Text),
      eps=StrToFloat(Edit9->Text),
      b,zt;
   int
      n=StrToInt(Edit3->Text),
      km=StrToInt(Edit10->Text),
      m=(int)((ak-an)/da+1); // Кол-во зн-й параметра А
   // Объявление динамических массивов
   double*Mx=new double[n];
   double*Ma=new double[m];
   double **My= new double* [m];
   for(int i=0;i<m;i++) My[i]=new double[n];
   double **Er= new double* [m];
   for(int i=0;i<m;i++) Er[i]=new double[n];
   // Проверка на наличие ошибок и вызов подпрограмм
   if (eps >= 1 || eps <= 0) ShowMessage("Погрешность должна быть < 1 и > 0!");
   else{
      if (Equat(c,d,eps,km,b,zt)){
         Tab(an,ak,da,xn,dx,b,n,My,Er,Mx,Ma);
         RezOut(b,zt,Mx,Ma,My,Er,m,n);
      } else ShowMessage("Решение не найдено за "+IntToStr(km)+" итераций");
   }
   // Освобождение памяти
   delete [] Mx;
   delete [] Ma;
   for(int i=0;i<m;i++) delete[]My[i];
   delete [] My;
   for(int i=0;i<m;i++) delete[]Er[i];
   delete [] Er;
}
//---------------------------------------------------------------------------
// Нелинейное уравнение
double f(double x){
  return (exp(-x)+x*x-2);
}
//---------------------------------------------------------------------------
// Нахождение корня нелинейного уравнения методом деления отрезка пополам
bool Equat(double c,double d,double eps,int km,double&b,double&zt){
   int i=1;
   double z;
   while(i<=km){
      z=(c+d)/2;
      if(fabs(f(z)) > eps)
         if(f(c)*f(z) > 0) c=z; else d=z;
      else{
         i=km;
         b=z;
         zt=f(z); // Погрешность вычисления корня по невязке
         return true;
      }
      i++;
   }
   return false;
}
//---------------------------------------------------------------------------
// Табулирование функции
void Tab(double an,double ak,double da,double xn,double dx,double b,int n,double**My,double**Er,double*Mx,double*Ma){
   double a=an,x;
   int i=0;
   while (a<=ak){
      x=xn;
      for (int j=0;j<n;j++){
         Mx[j]=x;
         if (x<1){
            My[i][j]=4*b-exp(a*x);
            Er[i][j]=0;
         }   
         else
            if (a*x+b*b>0){
               My[i][j]=(x*x*x)/(sqrt(a*x+b*b));
               Er[i][j]=0;
            }
            else Er[i][j]=1;
         x+=dx;
      }
      Ma[i]= a;
      i++;
      a+=da;
   }
}
//---------------------------------------------------------------------------
// Вывод результатов
void RezOut(double b,double zt,double*Mx,double*Ma,double**My,double**Er,int m,int n){
   Form1->Edit11->Text=FloatToStrF(b,ffGeneral,10,6);
   Form1->Edit12->Text=FloatToStrF(zt,ffGeneral,10,6);
   Form1->StringGrid1->RowCount=n+1;
   Form1->StringGrid1->ColCount=m+1;
   Form1->StringGrid1->Cells[0][0]="X/A";
   for(int i=0;i<m;i++){
      Form1->StringGrid1->Cells[i+1][0]="A["+IntToStr(i)+"]="+FloatToStr(Ma[i]);
      Form1->Chart1->Series[i]->Title="A["+IntToStr(i)+"]";
      Form1->Chart1->Series[i]->Clear();
      for (int j=0;j<n;j++){
         Form1->StringGrid1->Cells[0][j+1]="X["+IntToStr(j)+"]="+FloatToStr(Mx[j]);
         if(Er[i][j]==1)
            Form1->StringGrid1->Cells[i+1][j+1]="Err";
         else
            Form1->StringGrid1->Cells[i+1][j+1]=FloatToStrF(My[i][j],ffGeneral,6,5);
         Form1->Chart1->Series[i]->AddXY(Mx[j],My[i][j]);
      }
   }
}
//---------------------------------------------------------------------------
