Вычисление пределов с помощью ряда Тейлора

К примеру, sin = x -(x3/3!)+(x5/5!)- …

Здесь описано как вычислять Sin, Cos, ArcTg, Exp. Другие функции пишутся аналогично.

Точность вычисления

Для того, чтобы вычислить приближённое значение по формуле, мы должны взять бесконечно большое число, чтобы приблизиться к истинному значению функции. Т.е. при n→infinity (бесконечность), получаем истинное значение функции в данной точке.
На практике мы этого не станем делать, так как в Паскале имеются типы с ограниченным размером, такие как: Real, Single, Double, Extended. Что же теперь делать?

Введём понятие точность вычисления и назовём эту переменную eps (epsilon). Точность вычисления может быть разная: 0.05, 0.001 и намного большая, 10-8. В большинстве случаев хватает точности 3 знака после нуля, поэтому возьмём eps=0.001, или в краткой форме записи для Паскаля, 1e-3, что означает 1*10-3. Типа Single для этой точности вполне хватит, на нём и остановимся. Если истинное значение функции в заданной точке равно, допустим, 1.2328, а вычисленное значение равно 1.2323, то при нашей точности вычисления разница по модулю между ними составляет 0.0005<eps, то есть ответ нас устраивает.

Вычисление циклом

Для вычисления бесконечного ряда нужно применить цикл, в котором мы каждый раз будем проверять, насколько точно вычислено требуемое значение X, то есть проверим:|Xnew - Xold| < eps ?
где Xnew - это новое вычисленное значение,
Xold - предыдущее вычисленное значение.
Как только в ходе вычисления внутри цикла мы выясним, что достигнута требуемая точность (eps), выходим из него. Дальше вычислять уже нет необходимости.

Далее. Как вычислять эти значения? Смотрим на общую формулу: sin (x) = Sum [(-1)n * x2n+1 / (2n+1)!] , где n→infinity. Из чего состоит данная формула? Из вычисления степени числа (функция Power), факториала числа (функция Factorial) и вычисления знака (функция Sign). Для повторения вычисления этих функций смотрите прикреплённые вверху ссылки.

Теперь надо собрать все эти функции в одном выражении, которое будет вычисляться в отдельной функции.

 { вычисление значения элемента с индексом //i// ряда Тейлора для синуса}
function Sine (x: single; i: integer): single;
var k: integer;
begin
  K := 2 * i + 1;
  Sine := ( Sign (i) * Power (x, k) / factorial (k) );
end;

Что осталось? Объединить всё написанное в одной функции вычисления приближённого значения FunctionValue.

function FunctionValue (x: single): single;

На входе задаётся точка (число), в которой нужно вычислить значение функции.

Примеры программ

Общий случай

Значение функции вычисляется в процедуре FunctionValue. Только подставьте нужное название функции.

А теперь программа:

const eps: single = 1e-3; { Epsilon - необходимая точность, 1*10^(-3) }
 
function Factorial (N: word): single; { N! }
var
  f: single;
begin
  Factorial := 1.0;
  if n = 0 then exit;
 
  f := 1.0;
  for n := 1 to n do
    f := f * n;
 
  Factorial := f;
end;
 
function Sign (p: integer): single; { (-1)^p }
begin
     if Not Odd(P) then
       Sign := 1
     else
       Sign := -1;
end;
 
function Power (base: single; N: integer): single; { степень N по основанию base }
var k: integer;
    P: single;
begin
     P := 1.0;
     for k := 1 to N do
       P := P * base;
 
     Power := P;
end;
 
{--------------------------------------------------------------------}
 
function Sine (x: single; i: integer): single;
var k: integer;
begin
  K := 2 * i + 1;
  Sine := ( Sign (i) * Power (x, k) / factorial (k) );
end;
 
function CoSine (x: single; i: integer): single;
var k: integer;
begin
  K := 2 * i;
  CoSine := ( Sign (i) * Power (x, k) / factorial (k) );
end;
 
function ArcTg (x: single; i: integer): single;
var k: integer;
begin
  K := 2 * i + 1;
  ArcTg := ( Sign (i) * Power (x, k) / k );
end;
 
function Exp (x: single; i: integer): single;
begin
  Exp := Power (x, i) / factorial (i);
end;
 
{--------------------------------------------------------------------}
 
function FunctionValue (x: single): single;
var sum,old: single;
    index: integer;
begin
     if x <= 0.0 then
     begin
          FunctionValue := 0.0;
          exit;
     end;
     index := 0;
     sum := 0.0;
     repeat { повторять }
           old := sum; { old - прежнее вычисленное значение функции }
           sum := sum + ArcTg (x, index);   { Sin, Cos, Exp }
           index := index + 1;
     until abs (sum - old) < eps; { пока не достигнута необходимая точность }
     FunctionValue := sum
end;
 
begin
     writeln ( 'ArcTg (x) =', FunctionValue ( 1.0 / sqrt (3.0) ) : 8 : 3 );  { ArcTg }
{     writeln ( 'Cosinus (x) =', FunctionValue ( pi / 6.0 ) : 8 : 3 );  { CoSine }
     readln;
end.

Вычисление косинуса

cos X = 1 - (X ^ 2 / 2!) + (X ^ 4 / 4!) + (X ^ 6 / 6!) + ...
{ Implementing Taylor expansion for cosine }
program Cosine_Taylor;
 
function Factorial (N: integer): double; { N! }
var
  f: double;
begin
  Factorial := 1.0;
  if n = 0 then exit;
 
  f := 1.0;
  for n := 1 to n do
    f := f * n;
 
  Factorial := f
end;
 
{ cos X = 1 - (X ^ 2 / 2!) + (X ^ 4 / 4!) + (X ^ 6 / 6!) + ... }
function CalcCos (x: double): double;
var
	term, sum, oldsum: double;
	i, n: integer;
begin
	i := 0;
    n := 0;
	sum := 1.0; { initializing first term value }
	repeat
		oldsum := sum;
        x := sqr(x); { implementing X^2, X^4, ... each itteration}
        n := n + 2;
		term := x / Factorial(n); { taking into account term, evaluated in previous itteration }
		i := i + 1;
		if Odd(i) then
			term := -term; { negate term each itteration }
		sum := sum + term;
	until abs (sum - oldsum) < 1e-3 {desired precision};
	CalcCos := sum
end;
 
var x: double;
begin
	readln(x); {x - input value, in radians}
	writeln ('Comparing computed results:');
	writeln ('Infinite serie sum = ', CalcCos(x):4:3);
	writeln ('cos(x)=', cos(x):4:3);
	readln;
end.
 
pascal/limit_calculation.txt · Последние изменения: 2009/12/24 21:40 От romtek
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki