2015-05-26 106 views
0

我寫了一個程序來計算不同準確度的方程根。 4種不同的方法。 我正在使用PascalABC。帕斯卡文件控制檯輸出

所以,問題是:當我想看到輸出時,程序只顯示4個方法的結果。順序不會影響輸出結果,也不會影響file \ console輸出。 我完全不知道該怎麼做,這是我第一次遇到這個問題。至少在帕斯卡爾。 這裏是代碼:

uses crt; 

type 
pint = ^integer; 
aptr = ^real; 
bptr = ^real; 
xpreal = array[1..6] of real; 
npint = array[1..6] of integer; 

function fun(x:real): real; 
begin fun := x * x * x + x * x - 3; end; 

function dfdx(x:real): real; 
begin dfdx := 3 * x * x + 2 * x end; 

function fi(x:real): real; 
begin fi := sqrt(3/(x + 1)) end; 

function half(a, b, eps:real; n:pint):real; 
var 
    x:real; 
begin 
    n^ := 0; 
    repeat 
    x := (a + b)/2; 
    n^ := n^ + 1; 
    if (fun(a) * fun(x) >= 0) then 
     a := x 
    else 
     b := x; 
    until abs(fun(x)) < eps; 
    half := x; 
end; 

function def(b, eps:real; n:pint):real; 
var 
    x: real; 
begin 
    x := b; 
    n^ := 0; 
    repeat 
    x := x - fun(x)/dfdx(x); 
    n^ := n^ + 1; 
    until abs(fun(x)) < eps; 
    def := x; 
end; 

function itr(a: aptr; b: bptr): real; 
var 
x: real; 
begin 
x := fun(a^) * (a^-b^)/(fun(b^) - fun(a^)) + a^; 
    if fun(x) * fun(a^) >= 0 then a^ := x else a^ := a^; 
    if fun(x) * fun(b^) >= 0 then b^ := x else b^ := b^; 
itr := x; 
end; 

function hord(a, b, eps:real; n:pint):real; 
begin 
    n^ := 0; 
while(abs(fun(itr(@a, @b))) > eps) do 
    begin 
    n^ := n^ + 1; 
    end; 
hord := itr(@a, @b); 
end; 

function iter(b, eps:real; n:pint):real; 
var 
    x: real; 
begin 
    n^ := 0; 
    x := b; 
    repeat 
    x := fi(x); 
    n^ := n^ + 1; 
    until abs(fun(x)) < eps; 
    iter := x; 
end; 

procedure graph(var inf: text; x:xpreal; n: npint; c: integer); 
var 
i,j:integer; 
eps: real; 
begin 
    eps := 0.01; 
    writeln(inf); 

    write(inf, 'eps= '); 
    for i := 1 to c do 
    begin 
     write(inf, eps:6:7, ' '); 
     eps := eps * 0.1; 
    end; 

    writeln(inf); write(inf, 'x = '); 
    for i := 1 to c do 
    begin 
     write(inf, x[i]:8:7,' '); 
    end; 
    writeln(inf); writeln(inf); 
    writeln(inf, '^N'); writeln(inf); 

    for i := n[c-1] downto 0 do 
    begin 
    writeln(inf, '|'); 
    for j := 1 to c do 
     if (n[j] = i) then 
      write(inf, '<*>') 
     else write(inf, ' '); 
    writeln(inf); 
    end; 

writeln(inf, '+------------------------------------> eps'); 
writeln(inf); 

    eps := 0.01; 
    for i := 1 to 6 do 
    begin 
     write(inf, 'EPS = : ', eps:6:7); 
    for j := 0 to n[i] do 
    write(inf,'* '); 
    write(inf,n[i]); 
    writeln(inf); 
    eps := eps * 0.1; 
    end; 
writeln(inf, '__________________________'); 
end; 

var 
    a, b, eps : real; 
    i   : integer; 
    x   : xpreal; 
    n   : npint; 
    inf  : text; 

begin 
    a := 0.6; 
    b := 1.4; 
    eps := 0.01; 

    assign(inf,'C:\My Documents\Pas\output.txt'); 
    rewrite(inf); 

    for i := 1 to 6 do //1-st output 
     begin 
     x[i] := half(a, b, eps, @n[i]); 
     eps := eps * 0.1; 
     end; 
    writeln(inf, 'half-seg-method'); 
    graph(inf, x, n, 6); 

    for i := 1 to 6 do //2-nd output 
     begin 
     x[i] := def(b, eps, @n[i]); 
     eps := eps * 0.1; 
     end; 
    writeln(inf, 'Newton-method'); 
    graph(inf, x, n, 6); 

    for i := 1 to 6 do //3-rd output 
     begin 
     x[i] := iter(b, eps, @n[i]); 
     eps := eps * 0.1; 
     end; 
    writeln(inf, 'iter-method'); 
    graph(inf, x, n, 6); 

    for i := 1 to 6 do //4-th output 
     begin 
     x[i] := hord(a, b, eps, @n[i]); 
     eps := eps * 0.1; 
     end; 
    writeln(inf, 'hord-method'); 
    graph(inf, x, n, 6); 

     close(inf); 
end. 
+0

PascalABC是否有運行時檢查?第一步是啓用它們。 –

回答

0

有很多與你的代碼的問題:

首先:主要錯誤是,你想不可能精確由於編碼 錯誤。你忘了每個循環之前重置eps至0.01,因此,你與eps=1e-8啓動六個牛頓部分,並會結束它與 eps=1e-14

eps := 0.01; 
    for i := 1 to 6 do {3-rd output} 
     begin 
     x[i] := iter(b, eps, @n[i]); 
     eps := eps * 0.1; 
     end; 
    writeln(inf, 'iter-method'); 
    graph(inf, x, n, 6); 

    eps := 0.01; 
    for i := 1 to 6 do {4-th output} 
    .... 

的第二個問題是,您的收斂測試可能會失敗絕對誤差準則。通常我們使用相對誤差測試,例如爲你的牛頓:

function def(b, eps:real; n:pint):real; 
var 
    x: real; 
    d: real; 
begin 
    x := b; 
    n^ := 0; 
    repeat 
    d := fun(x)/dfdx(x); 
    x := x - d; 
    n^ := n^ + 1; 
    until abs(d) < eps*abs(x); 
    def := x; 
end; 

這還額外顯示了你編碼風格的另一個問題。使用相同的參數反覆評估函數,而不是將函數值存儲在局部變量中:對於簡單的函數,這可能幾乎沒有問題,但對於更復雜的函數而言,這些函數非常昂貴且無效。 它在你的function itr(a: aptr; b: bptr): real;中更加引人注目,而不是三個函數調用你做的七個

...