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.