Решение интегрального уравнения. QUANC8 и ZEROIN - Turbo Pascal
Формулировка задачи:
Решение задачи: «Решение интегрального уравнения. QUANC8 и ZEROIN»
UNIT FMM; {$N+} INTERFACE Const ndim = 21;{FOR LAB1=21; LAB2= ; LAB3= } ndimS = 10; ndimC = 10; maxnfe = 3000; {„®ЇгбвЁ¬®Ґ зЁб«® ўлзЁб«Ґ*Ё© Yp=F(t,Y) ¤«п RKF45} {$IFOPT N+} type float = double; { 8 byte real, requires 8087 math chip} {$ELSE} type float = real; { 6 byte real, no math chip required } {$ENDIF} type floatvector = array [1..ndim] of float; floatmatrix = array [1..ndim,1..ndim] of float; rvecn = array [1..6*ndim+3] of float; ivec5 = array [1..5] of integer; ivector = array [1..ndim] of integer; floatvectorS = array [1..ndimS] of float; floatvectorC = array [1..ndimC] of float; floatmatrixCS = array [1..ndimS,1..ndimC] of float; Procedure quanc8( fun : pointer; a,b,abserr,relerr : float; var result, errest : float; var nofun : longint; var flag : float); function zeroin( ax,bx,tol : float; F : pointer) : float; function sign( a,b : float) : float; IMPLEMENTATION Type Floatworkrecord = record yp : floatvector; h : float; f1 : floatvector; f2 : floatvector; f3 : floatvector; f4 : floatvector; f5 : floatvector; savre : float; savae : float; end; Integerworkrecord = record nfe, kop, init, jflag, kflag : integer; end; {$F+} {$L Initval.OBJ} function UserFunction1( X : float; ProcAddr : Pointer) : float; external; Function UserFunction3( X : float; ProcAddr : Pointer) : float; external; {$F-} function sign(a,b:float):float; begin if b=0 then sign:=0 else sign:=b/abs(b)*abs(a) end; Procedure quanc8(fun:pointer;a,b,abserr,relerr:float;var result, errest:float;var nofun:longint;var flag:float); label 72,90,30,50,62,60,70,75,80,82; var w0,w1,w2,w3,w4,area,x0,f0,stone,step,cor11,temp : float; qprev,qnow,qdiff,qleft,esterr,tolerr : float; f,x : array [1..16] of float; fsave,xsave : array [1..8,1..30] of float; qright : array [1..31] of float; levmin,levmax,levout,nomax,nofin,lev,nim,i,j, kk,stepp : longint; begin {writeln('Q8 start a,b,abserr,relerr,result,errest, nofun', #13,#10,a,b,abserr,relerr,result,errest, nofun);} levmin:=1; levmax:=30; levout:=6; nomax:=5000; stepp:=1; for kk:=1 to levout+1 do stepp:=stepp*2; nofin:=nomax-8*(levmax-levout+stepp); w0:=3956.0/14175.0; w1:=23552.0/14175.0; w2:=-3712.0/14175.0; w3:=41984.0/14175.0; w4:=-18160.0/14175.0; flag:=0.0; result:=0.0; cor11:=0.0; errest:=0.0; area:=0.0; nofun:=0; if a=b then goto 90;{end procedure} lev:=0; nim:=1; x0:=a; x[16]:=b; qprev:=0.0; f0:=userfunction1(x0,fun); stone:=(b-a)/16.0; x[8]:=(x0+x[16])/2.0; x[4]:=(x0+x[8])/2.0; x[12]:=(x[8]+x[16])/2.0; x[2]:=(x0+x[4])/2.0; x[6]:=(x[4]+x[8])/2.0; x[10]:=(x[8]+x[12])/2.0; x[14]:=(x[12]+x[16])/2.0; j:=2; while j<=16 do begin f[j]:=userfunction1(x[j],fun); j:=j+2; end; nofun:=9; 30: x[1]:=(x0+x[2])/2.0; f[1]:=userfunction1(x[1],fun); j:=3; while j<=15 do begin x[j]:=(x[j-1]+x[j+1])/2.0; f[j]:=userfunction1(x[j],fun); j:=j+2; end; nofun:=nofun+8; step:=(x[16]-x0)/16.0; qleft:=(w0*(f0+f[8])+w1*(f[1]+f[7])+w2*(f[2]+f[6])+w3*(f[3]+f[5])+w4*f[4])*step; qright[lev+1]:=(w0*(f[8]+f[16])+w1*(f[9]+f[15])+w2*(f[10]+f[14])+w3*(f[11]+f[13])+w4*f[12])*step; qnow:=qleft+qright[lev+1]; qdiff:=qnow-qprev; area:=area+qdiff; esterr:=abs(qdiff)/1023.0; if abserr>=(relerr*abs(area)) then tolerr:=abserr*(step/stone) else tolerr:=relerr*abs(area)*(step/stone); if lev<levmin then goto 50; if lev>=levmax then goto 62; if nofun>nofin then goto 60; if esterr<=tolerr then goto 70; 50: nim:=2*nim; lev:=lev+1; for i:=1 to 8 do begin fsave[i,lev]:=f[i+8]; xsave[i,lev]:=x[i+8]; end; qprev:=qleft; for i:=-1 downto -8 do begin f[2*i+18]:=f[i+9]; x[2*i+18]:=x[i+9]; end; goto 30; 60: nofin:=2*nofin; levmax:=levout; flag:=flag+(b-x0)/(b-a); goto 70; 62: flag:=flag+1.0; 70: result:=result+qnow; errest:=errest+esterr; cor11:=cor11+qdiff/1023.0; 72: if nim=2*(nim div 2) then goto 75; nim:=nim div 2; lev:=lev-1; goto 72; 75: nim:=nim+1; if lev<=0 then goto 80; qprev:=qright[lev]; x0:=x[16]; f0:=f[16]; for i:=1 to 8 do begin f[2*i]:=fsave[i,lev]; x[2*i]:=xsave[i,lev]; end; goto 30; 80: result:=result+cor11; if errest=0.0 then goto 90;{end procedure} 82: temp:=abs(result)+errest; if temp<>abs(result) then goto 90; errest:=2.0*errest; goto 82; 90: exit; end; function zeroin(ax,bx,tol : float; F : pointer) : float; Label 10, 20, 30, 40, 50, 60, 70, 80, 90; Const fierstcall : boolean = true; eps : float = 1.0; var a,b,c,d,e,fa,fb,fc,tol1,xm,p,q,r,s : float; Begin if fierstcall then begin 10: eps:=eps/2.0; tol1:=1.0+eps; if(tol1 > 1.0) then goto 10; end; a:=ax; b:=bx; fa:=userfunction3(a,F); fb:=userfunction3(b,F); 20: c:=a; fc:=fa; d:=b-a; e:=d; 30: if(abs(fc) >= abs(fb)) then goto 40; a:=b; b:=c; c:=a; fa:=fb; fb:=fc; fc:=fa; 40: tol1:=2.0*eps*abs(b)+0.5*tol; xm:=0.5*(c-b); if(abs(xm) <= tol1) then goto 90; if(fb = 0.0) then goto 90; if(abs(e) < tol1) then goto 70; if(abs(fa) <= abs(fb)) then goto 70; if(a <> c) then goto 50; s:=fb/fa; p:=2.0*xm*s; q:=1.0-s; goto 60; 50: q:=fa/fc; r:=fb/fc; s:=fb/fa; p:=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0)); q:=(q-1.0)*(r-1.0)*(s-1.0); 60: if(p > 0.0) then q:=-q; p:=abs(p); if((2.0*p) >= (3.0*xm*q-abs(tol1*q))) then goto 70; if(p >= abs(0.5*e*q)) then goto 70; e:=d; d:=p/q; goto 80; 70: d:=xm; e:=d; 80: a:=b; fa:=fb; if(abs(d) > tol1) then b:=b+d; if(abs(d) <= tol1) then b:=b+sign(tol1,xm); fb:=userfunction3(b,F); if((fb*(fc/abs(fc))) > 0.0) then goto 20; goto 30; 90: zeroin:=b; end; END.
Объяснение кода листинга программы
The code you provided is a Pascal program that implements a method for solving integral equations. It uses a user-defined function to evaluate the equation at different points. The program then adjusts the step size and repeats the process until the desired accuracy is achieved.
The user-defined function UserFunction1
is used to evaluate the equation at a given point x
. The user-defined function UserFunction3
is used to evaluate the equation at a different point x+d
, where d
is the step size.
The program starts by initializing some variables and constants, including the step size step
, the tolerance tolerr
, and the number of function calls nofun
.
It then proceeds to the main loop, which iterates over different steps in the integration process. In each iteration, it calculates the current position x
, evaluates the equation at x
using UserFunction1
, and updates the step size step
.
If the current step size step
is smaller than the tolerance tolerr
, the program increases the step size step
by a factor of 2. Otherwise, it keeps the current step size.
After each iteration, the program updates the variable result
, which represents the sum of the current step size step
and the tolerance tolerr
. It also updates the variable errest
, which represents the residual error between the calculated and exact values.
The program continues iterating until the desired accuracy is achieved, which is determined by the tolerance tolerr
.
At the end of the program, the variable zeroin
is set to the value of the final step size step
.
Please note that the code provided is quite complex and may require further explanation or adjustments to work correctly depending on the specific problem being solved.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д