![]() |
|
#1
|
|||
|
|||
![]() Здравствуйте, уважаемые форумчане!
В общем, название темы само за себя говорит, а теперь более подробно. Есть программа, решающая задачу Коши методом Эйлера и методом двойного пересчета. Так как метод двойного пересчета, по-сути, усовершенствованный метод Эйлера, то они для удобства объединены в одну процедуру, которая за каждый проход цикла считает и выводит в таблицу: Х, Y, Y2, Е. Е - это погрешность, т.е. разность между Y2 (значение y методом двойного пересчета) и Y (значение у методом Эйлера). Так вот, проблема в том и заключается, что по какой-то неведомой мне причине вычитаение вычисляется неправильно. Надеюсь на то, что вы мне поможете разобраться с этим. Итак, код классов: Код:
type ADouble=array[1..2] of double; //Класс - родитель, для вывода результатов и хранения заданной функции EchoMethods=class(TObject) //Функция Function MyFunction(x,dy:double):ADouble; //Процедура вывода в таблицу Procedure EchoTab(x,y,y2:double); end; //Класс - наследник, для хранения методов счета DifferentialMethod2=class(EchoMethods) //Метод Эйлера/Двойного пересчета Procedure Euler(x0,x1,y0,dy0,h:double); end; ... Коды Метода Эйлера, заданной функции и вывода: Код:
//Заданная функция Function EchoMethods.MyFunction(x,dy:double):ADouble; begin MyFunction[1]:=dy; MyFunction[2]:=-0.01*exp(0.4*x); end; //Метод Эйлера Procedure DifferentialMethod2.Euler(x0,x1,y0,dy0,h:double); var F:ADouble; x,x2:double; y,y2:double; dy,dy2:double; begin x:=x0; x2:=x0; y:=y0; y2:=y0; dy:=dy0; dy2:=dy0; Form1.Series1.AddXY(x0,y0); Form1.Series2.AddXY(x0,y0); repeat EchoTab(x,y,y2); //Стандартный метод Эйлера F:=MyFunction(x,dy); x:=x+h; y:=y+F[1]*h; dy:=F[1]+F[2]*h; Form1.Series1.AddXY(x, y); //Метод двойного пересчета repeat F:=MyFunction(x2,dy2); x2:=x2+h/2; y2:=y2+F[1]*(h/2); dy2:=dy2+F[2]*(h/2); if (Round(x2*100) mod 2 = 0) then Form1.Series2.AddXY(x2,y2); until (Round(x2*100) mod 2 = 0); until (x>=x1); end; //Процедура вывода в таблицу Procedure EchoMethods.EchoTab(x,y,y2:double); var i:integer; begin i:=Round(x*10); Form1.StringGrid1.Cells[0,i+1]:=FloatToStr(x); Form1.StringGrid1.Cells[1,i+1]:=FloatToStr(y); Form1.StringGrid1.Cells[2,i+1]:=FloatToStr(y2); Form1.StringGrid1.Cells[3,i+1]:=FloatToStr(y2-y); end; Собственно, в выделенной строке вся засада и кроется. Вычитание производится совершенно неверно. Хотя, конечно, может и не в выделенной... В общем, такие пироги. Хотелось бы с вашей помощью понять, в чем причина неправильного счета. |