русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Программная реализация численных методов решения задачи Коши


Дата добавления: 2015-01-16; просмотров: 1437; Нарушение авторских прав


 

//файл включения для векторного и матричного типов

#include "matrix.h"

/*для удобства переопределим шаблонные типы векторов и матриц для работы с числовыми объектами - вещественными числами двойной точности */

typedef vector<double> dvector;

typedef matrix<double> dmatrix;

 

/*Класс дифференциальных уравнений */

 

class DEqu

{

double t0, //начальное время

t1, //конечное время

step; //шаг по времени

dvector x0; //вектор начальных условий

/*Будем рассматривать класс уравнений, которые удается разрешить относительно старшей производной. В этом случае при представлении уравнения n-го порядка в виде системы уравнений первого порядка и решении этой системы нам нужна только одна функция - для правой части последнего уравнения в системе, вычисляющая его правую часть по уже вычисленным до этого значениям младших производных и самой функции. Для первого уравнения правая часть - в нулевой момент времени -это начальное значение первой производной, для второго уравнения - второй и т.д., а правая часть для последнего уравнения может включать зависимость от времени, значение функции и всех младших производных. Для унификации ввода этой функции в интерактивном режиме надо программировать интерпретатор. Так как нам этого делать не хотелось, то использовать настоящий класс сможет только программирующий пользователь - ему придется запрограммировать функцию правой части и указать ее имя при вызове соответствующего метода решения системы уравнений. Прототип этой функции объявлен через указатель на функцию, чтобы можно было использовать в качестве аргумента другой функции */

 

dvector (*dxbydt)(double t, dvector x);

 

public:

/*конструктор принимает в качестве параметров все вышеперечисленное */

DEqu(double T0, double Tmax, double Step,



dvector X0, dvector (*Dxbydt)(double T, dvector X)): t0(T0), t1(Tmax), step(Step), x0(X0), dxbydt(Dxbydt) { }

 

//конструктор копирования

DEqu(DEqu &x): t0(x.t0), t1(x.t1), step(x.step),

x0(x.x0), dxbydt(x.dxbydt)

{

}

/*Прототипы функций, реализующих методы Эйлера, Рунге-Кутты второго и четвертого порядка точности и Адамса. Функции возвращают матрицы с количеством столбцов, равным порядку системы, то есть в нулевом столбце - значения функции, а в последующих – значения производных соответствующего номеру столбца порядка */

 

dmatrix EilerSol();

dmatrix RK2Sol();

dmatrix RK4Sol();

dmatrix Adams4Sol();

 

/*набор функций для доступа и модификации параметров системы*/

double &TStart() { return t0; }//начальное время

double &TEnd() { return t1; }//конечное время

dvector &XStart() { return x0; }/*вектор начальных условий*/

double &StepByT() {return step;}//шаг по времени

};

 

 

//Метод Эйлера

dmatrix DEqu::EilerSol()

{

/*определяем количество точек, которые нам необходимо вычислить*/

long StepCount=(TEnd()-TStart())/StepByT();

 

/*создаём матрицу, количество строк в которой равно количеству точек решения с учётом начальной (нулевой) точки */

dmatrix x(StepCount+1,1);

 

x[0]=XStart();/*записываем в нулевую точку начальные условия*/

 

/*итеративно вычисляем все последующие точки решения*/

for(long i=0;i<StepCount;i++)

x[i+1]=x[i]+StepByT()*dxbydt(TStart()+ i*StepByT(), x[i]);

return x;//возвращаем результирующую матрицу

}

 

/*Решение по методу Рунге-Кутта второго порядка (метод трапеций, или метод Хойна)*/

dmatrix DEqu::RK2Sol()

{

//определяем количество вычисляемых точек

long StepCount=(TEnd()-TStart())/StepByT();

 

//создаём матрицу для хранения решений

dmatrix x(StepCount+1, 1);

 

//заносим начальные условия в 0-й вектор матрицы

x[0]=XStart();

 

for(long i=0;i<StepCount;i++)

{

/*вычисляем вектор-коэффициенты следующей точки решения*/

dvector k1=dxbydt(TStart()+i*StepByT(),x[i]);

dvector k2=dxbydt(TStart()+(i+1)*StepByT(),

x[i]+StepByT()*k1);

 

//вычисляем вектор решения на следующем шаге

x[i+1]=x[i]+(StepByT()/2)*(k1+k2);

}

return x;//возвращаем матрицу-результат

}

 

 

/*Решение по методу Рунге-Кутта 4-го порядка точности*/

dmatrix DEqu::RK4Sol()

{

//количество точек решения

long StepCount=(TEnd()-TStart())/StepByT();

 

dmatrix x(StepCount+1, 1);//матрица решения

 

x[0]=XStart();//начальные условия

 

for(long i=0;i<StepCount;i++)

{

//вычисляем вектор-коэффициенты решения

dvector k1=dxbydt(TStart()+i*StepByT(),x[i]);

dvector k2=dxbydt(TStart()+(i+0.5)*StepByT(),

x[i]+(StepByT()/2)*k1);

dvector k3=dxbydt(TStart()+(i+0.5)*StepByT(),

x[i]+(StepByT()/4)*(k1+k2));

dvector k4=dxbydt(TStart()+(i+1)*StepByT(),

x[i]+StepByT()*(-k2+2*k3));

 

x[i+1]=x[i]+(StepByT()/6)*(k1+4*k3+k4); //следующая точка

}

return x;//возвращаем матрицу решений

}

 

//Метод Адамса

dmatrix DEqu::Adams4Sol()

{

//определяем количество точек решения

long StepCount=(TEnd()-TStart())/StepByT();

 

dmatrix x(StepCount+1,1);/*матрица решения - массив векторов*/

 

/*преобразуем указатель на данный объект в указатель на объект для решения системы дифференциальных уравнений методом Рунге-Кутта четвёртого порядка и получаем объект соответствующего типа вызовом конструктора копирования */

DEqu obj=*this;

 

/*если количество точек решения таково, что данную систему нельзя решить методом Адамса-Башфорта, возвращаем решение по методу Рунге-Кутта*/

if(StepCount<=3) return obj.RK2Sol();

 

/*В противном случае модифицируем параметры системы (конечное время) так, чтобы по методу Рунге-Кутта четвёртого порядка находились только первые четыре решения */

obj.TEnd()=TStart()+3*StepByT();

 

dmatrix tempx=obj.RK4Sol();/*получаем первые четыре точки*/

 

for(long i=0;i<4;i++)/*и переписываем их в векторы результирующей матрицы*/

x[i]=tempx[i];

 

/*начиная с пятой точки, работает собственно метод Адамса*/

for(long i=3;i<StepCount;i++)

x[i+1]=x[i]+(StepByT()/24)*

(

55*dxbydt(TStart()+i*StepByT(),x[i])-

59*dxbydt(TStart()+(i-1)*StepByT(),x[i-1])+

37*dxbydt(TStart()+(i-2)*StepByT(),x[i-2])-

9*dxbydt(TStart()+(i-3)*StepByT(),x[i-3])

);

return x;//возвращаем результирующую матрицу

}

 

 

//Тестовые функции

dvector testfunc(double x, dvector y)

{

//Решение уравнения Бесселя

dvector dy=2;

dy[0]=y[1];/*начальное условие для первой производной*/

dy[1]=-y[0]-y[1]/x;

 

 

/*решение уравнений движения

dvector dy=4;

dy[0]=y[2];

dy[1]=y[3];

dy[2]=-y[0]/hypot(y[0],y[1]);

dy[3]=-y[1]/hypot(y[0],y[1]);*/

return dy;

}

 

 

void main()

{

dvector StartCond=2;

StartCond[0]=0.9384698;

StartCond[1]=-0.2422685;

/* dvector StartCond=4;

StartCond[0]=0.5;

StartCond[1]=0;

StartCond[2]=0;

StartCond[3]=1.63;*/

 

DEqu testobj(0.5, 1.1, 0.1,/*0, 20.3, 0.1,*/

StartCond, testfunc);

dmatrix resEiler=testobj.EilerSol();

dmatrix resRK2=testobj.RK2Sol();

dmatrix resRK4=testobj.RK4Sol();

dmatrix resAdams4=testobj.Adams4Sol();

cout<<resEiler<<endl<<resRK2<<endl;

}



<== предыдущая лекция | следующая лекция ==>
Проблема устойчивости | Метод конечных разностей для линейных краевых (граничных) задач


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.504 сек.