CS 203
Homework #1
Option 2.
Conversion from Algol60 to C:
In order to perform this conversion the following modifications were done:
E.g.
'procedure' RK (x,y,n,FKT,eps,eta,xE,yE,fi); 'value' x,y; 'integer' n;'Boolean' fi; 'real' x,eps,eta,xE; 'array' y,yE; 'procedure' FKT;
appears in the C code as:
void RK (float x, float y[], int *n,void
*FKT)(float,float[],int,float[]), float *eps, float *eta, float
*xE, float yE[], int *fi)
E.g.
array z,y1,y2,y3[1:n];
appears in the C code as:
float z[*n+1],y1[*n+1],y2[*n+1],y3[*n+1];
NOTE: In the C version of the program all operations on arrays were done starting at index 1. Thus the arrays had to be declared to be of size n+1. This was done to make the conversion easier and clearer.
Algol60: 'for' k:=1 'step' 1 'until' n 'do' ye[k]:=w[k]:=y[k];
C: for (k=1;k<=*n;k++)
ye[k]=w[k]=y[k];
Algol60: 'for' k:=1 'step' 1 'until' n 'do' 'if' comp (y1[k],y3[k],eta)>eps 'then' 'goto' CC;
C:
while (k<=*n){
if (comp(y1[k],y3[k],&(*eta))>*eps)
{ ß ---Here it does the CC part
.
.
}
k++
- The function ‘equiv’ from Algol60 was rewritten in C as:
((!(x+2.01*H-*xE>0) || (H>0)) && ((x+2.01*H- *xE>0) || !(H>0)))
This was done considering that (P« Q) can be rewritten as (Ø P Ú Q ) Ù ( P Ú Ø Q ).
Conversion from Algol60 to Pascal:
In order to perform this conversion the following modifications were done:
Algol60 Pascal
‘real’ x1; x1 : real;
‘integer’ n; n : integer;
‘array’ w[1:n] w : farray; (where farray was defined as:
array [1..9999] of real in the
type part of the program )
Algol60 a[1]:=a[2]:=a[5]:=h/2;
Pascal a[5]:=h/2;
a[2]:=a[5];
a[1]:=a[2];
Algol60: 'for' k:=1 'step' 1 'until' n 'do'
Pascal: for k:=1 to n do
Begin
(not(x+2.01*H-xE>0) or (H>0)) and ((x+2.01*H-xE>0) or not(H>0))
/*
The RK program converted from Algol60 to C.
*/
# include <stdio.h>
# include <math.h>
//Dummy FKT function
void FKT (float x, float y[], int n, float z[])
{
int k;
for (k=1;k<=n;k++) z[k]=x/y[k];
}
//Dummy comp function
float comp (float a, float b, float *c)
{
*c=*c * *c;
return (fabs(a-b)* *c);
}
void RK1ST (float *x, float y[], float h, float *xe, float ye[], int *n,void (*FKT)(float, float[], int, float[]), float z[])
{
float w[*n+1];
float a[6];
int k,j;
a[1]=a[2]=a[5]=h/2;
a[3]=a[4]=h;
*xe=*x;
for (k=1;k<=*n;k++)
ye[k]=w[k]=y[k];
for (j=1;j<=4;j++)
{
FKT(*xe,w,*n,z);
*xe=*x+a[j];
for (k=1;k<=*n;k++)
{
w[k]=y[k]+a[j]*z[k];
ye[k]=ye[k]+a[j+1]*z[k]/3;
}
}
}
void RK (float x, float y[], int *n,void (*FKT)(float,float[],int,float[]), float *eps, float *eta, float *xE, float yE[], int *fi)
{
float z[*n+1],y1[*n+1],y2[*n+1],y3[*n+1];
float x1,x2,x3,H;
int out;
int k,j;
static float s,Hs;
if (*fi)
{
H=*xE-x;
s=0;
}
else
H=Hs;
out=0; // False
//AA:
while (!out)
{
if ((!(x+2.01*H-*xE>0) || (H>0)) && ((x+2.01*H- *xE>0) || !(H>0)))
{
Hs=H;
out=1;
H=(*xE-x)/2;
}
RK1ST(&x,y,2*H,&x1,y1,&(*n),FKT,z);
//BB:
RK1ST(&x,y,H,&x2,y2,&(*n),FKT,z);
RK1ST(&x2,y2,H,&x3,y3,&(*n),FKT,z);
k=1;
while (k<=*n)
{
if (comp(y1[k],y3[k],&(*eta))>*eps)
{
H=.5*x;
out=0;
x1=x2;
for (j=1;j<=*n;j++) y1[j]=y2[j];
RK1ST(&x,y,H,&x2,y2,&(*n),FKT,z);
RK1ST(&x2,y2,H,&x3,y3,&(*n),FKT,z);
k=0;
}
k++;
}
x=x3;
if (!out)
{
for (k=1;k<=*n;k++)
y[k]=y3[k];
if (s==5)
{
s=0;
H=2*H;
}
s++;
}
}
for (k=1;k<=*n;k++)
yE[k]=y3[k];
}
// Dummy main
void main()
{
float x = 1.06;
int n = 4;
float eps = 0.0001;
float eta = 0.1;
float xE = 5;
int fi = 1; //true
float y[n+1],yE[n+1];
int k;
for (k=1;k<=n;k++)
y[k] =(x*k)/3;
RK (x,y,&n,FKT,&eps,&eta,&xE,yE,&fi);
for (k=1;k<=n;k++)
printf("%.4f ",yE[k]);
}
{
The RK program converted from Algol60 to Pascal
}
program convert;
type farray = array [1..9999] of real;
var y,yE : farray;
k,n : integer;
x,eps,eta,xE : real;
fi : Boolean;
{------------Dummy FKT procedure-------------------------}
procedure FKT(x: real; y:farray; n:integer; var z:farray);
var k:integer;
begin
for k:=1 to n do z[k]:=x/y[k]
end;
{------------Dummy comp function ------------------------}
function comp(a:real; b:real;var c:real):real;
begin
c:=c*c;
comp:=abs(a-b)*c;
end;
{-----------------------------------------------------------------}
procedure RK1ST(var x: real; var y:farray; var h:real; var xe:real;
var ye: farray; var n:integer;
procedure FKT(x: real; y:farray; n:integer; var z:farray);
var z:farray);
var w :farray;
a : array [1..5] of real;
k,j :integer;
begin
a[5]:=h/2;
a[2]:=a[5];
a[1]:=a[2];
a[4]:=h;
a[3]:=a[4];
xe:=x;
for k:=1 to n do
begin
w[k]:=y[k];
ye[k]:=w[k]
end;
for j:=1 to n do
begin
FKT(xe,w,n,z);
xe:=x+a[j];
for k:=1 to n do
begin
w[k]:=y[k]+a[j]*z[k];
ye[k]:=ye[k]+a[j+1]*z[k]/3
end;
end;
end;
{--------------------------------------------------------------------}
procedure RK(x:real; y:farray; n:integer;
procedure FKT(x:real;y:farray; n:integer; var z:farray);
var eps,eta:real;var xE:real; var yE:farray; var fi:Boolean);
var z,y1,y2,y3 : farray;
x1,x2,x3,H,myH : real;
out : Boolean;
k : integer;
s,Hs : static real;
begin
if fi then
begin
H:=xE-x;
s:=0;
end
else
H:=Hs;
out:=false;
while not(out) do
begin
if (not(x+2.01*H-xE>0) or (H>0)) and ((x+2.01*H-xE>0) or not(H>0)) then
begin
Hs:=H;
out:=true;
H:=(xE-x)/2;
end;
{"myH" had to be introduced since the procedure call to RK1ST does not accept 2*H}
myH:=2*H;
RK1ST(x,y,myH,x1,y1,n,FKT,z);
RK1ST(x,y,H,x2,y2,n,FKT,z);
RK1ST(x2,y2,H,x3,y3,n,FKT,z);
k:=1;
while k<=n do
begin
if comp(y1[k],y3[k],eta)<=eps then
k:=k+1
else
begin
H:=0.5*x;
out:=false;
x1:=x2;
for k:=1 to n do y1[k]:=y2[k];
RK1ST(x,y,H,x2,y2,n,FKT,z);
RK1ST(x2,y2,H,x3,y3,n,FKT,z);
k:=1;
end;
end;
x:=x3;
if not(out) then
for k:=1 to n do y[k]:=y3[k];
if s=5 then
begin
s:=0;
H:=2*H;
end;
s:=s+1;
end;
for k:=1 to n do yE[k]:=y3[k]
end;
{Dummy main}
begin
x:=1.06;
n:=4;
eps:=0.0001;
eta:=0.1;
xE:=5;
fi:=true;
for k:=1 to n do y[k]:=(x*k)/3;
RK(x, y, n, FKT, eps, eta, xE, yE, fi);
for k:=1 to n do write(yE[k]:6:4,' ')
end.