#include <values.h>
#include <conio.h>
#include "matrix.h"
/*Для удобства определим пару типов для работы с вещественными матрицами и векторами */
typedef vector<double> dvector;
typedef matrix<double> dmatrix;
/*Этот класс предназначен для тестирования методов решения граничных задач */
class GrZadDemo
{
double min, max, grusl[6];/*минимум, максимум и массив граничных условий */
public:
GrZadDemo()/*Инициализация массива граничных условий */
{
min=1,max=1.6,
grusl[0]=3,grusl[1]=0.5,grusl[2]=2.075678,
grusl[3]=2,grusl[4]=0.7,grusl[5]=0.5118773;
}
double getmin() {return min;}/*Получение минимума */
double getmax() {return max;}/*Получение максимума */
double getgrusl(int posit)/*получение граничных условий по номеpу */
{
if(posit>6||posit<1)
throw xmsg("Неверные параметры");
return grusl[posit-1];
}
double getrange() {return 2;}/*Порядок уравнения */
/*Вектор значений коэффициентов в данной точке */
dvector getvalue(double x)
{
if(x<min||x>max)
//возвpащает значение функции Бесселя
throw xmsg("Выход за предела диапазона");
dvector pqr=3;
pqr[0]=1.0/x, pqr[1]=1, pqr[2]=0;
return pqr;
}
//вычисляем пpоизводную
dvector getderive(double x, dvector y)
{
dvector f=2, pqr=getvalue(x);
f[0]=y[1];
f[1]=pqr[2]-pqr[0]*y[1]-pqr[1]*y[0];
return f;
}
};
/*Тестирование метода конечных разностей */
void test1()
{
GrZadDemo test;
int r=test.getrange();/*порядок системы дифференциальных уравнений */
int n=100; //число разбиений
int m=n+r; /*число уравнений в оpтогонализиpуемой системе*/
dvector g(r*(r+1));//массив для граничных условий
double min=test.getmin(), max=test.getmax();
double h=(max-min)/n; //шаг
// ЗАПОЛНИМ МАССИВ ГРАНИЧНЫХ УСЛОВИЙ
for(int i=0;i<r*(r+1);i++)
g[i]=test.getgrusl(i+1);
dmatrix mtr(m,m),right(m,1);
// сформируем матрицу СЛАУ
/* Заполним первую и последнюю строки основной матрицы СЛАУ*/
mtr[0][0]=-g[1]/(2*h);
mtr[0][2]=-mtr[0][0];
mtr[0][1]=g[0];
right[0][0]=g[2];
// всего строк: m :от 0 до m-1, m-1 - последняя
mtr[m-1][m-2]=g[4]/(2*h);
mtr[m-1][m-4]=-g[4]/(2*h);
mtr[m-1][m-3]=g[3];
right[m-1][0]=g[5];
/*Далее матрицу заполняем со строки 1 по m-2 включительно*/
for(long i=1;i<=m-2;i++)
{
dvector pqr=test.getvalue(min+(i-1)*h);
mtr[i][i-1]=1/(h*h)-pqr[0]/(2*h);
mtr[i][i]=pqr[1]-2/(h*h);
mtr[i][i+1]=1/(h*h)+pqr[0]/(2*h);
right[i][0]=pqr[2];
}
/*Для тестирования выведем полученную трёхдиагональную матрицу */
cout<<"3-diagonal matrix\n"<<mtr<<endl;
dmatrix result=SLAE_Orto(mtr,right);/*решим СЛАУ*/
cout<<"Solution\n";
/*Решением являются значения функции Бесселя нулевого порядка */
for(long i=0;i<m-1;i++)
cout<<"X="<<min+i*h<<" Y="<<result[i][0]<<endl;
}
double psi(int l,double a,double h,dvector g,double min,GrZadDemo test,int n)
{
/*интегратор по числу разбиений с выводом результата */
dvector y=2;
y[0]=a;
y[1]=(g[2]-g[0]*a)/g[1];
double x=min;
if(l==1)
cout<<x<<" "<<a<<" "<<y[1]<<endl;
for(int m=0;m<n;m++)
{
dvector f=test.getderive(x,y);
y+=h*f;
x+=h;
if(l==1)
cout<<x<<" "<<y[0]<<" "<<y[1]<<endl;
}
if(l==0)
return g[3]*y[0]+g[4]*y[1]-g[5];
}
/*Тестирование метода стрельбы */
void test2()
{
GrZadDemo test;
int r=test.getrange();/*порядок системы дифференциальных уравнений */
int n=100; //число разбиений
dvector g(r*(r+1));//массив для граничных условий
double min=test.getmin(), max=test.getmax();
double h=(max-min)/n; //шаг
for(int i=0;i<r*(r+1);i++)
g[i]=test.getgrusl(i+1);
double t=psi(0,max,h,g,min,test,n);/*три раза решаем задачу Коши */
double k=psi(0,min,h,g,min,test,n);
psi(1,max-(max-min)/(t-k)*t,h,g,min,test,n);
}
void main()
{
test1();//Метод конечных разностей
getch();
test2();//Метод стрельбы
getch();
}