COMMENT THESE ROUTINES WERE SCANNED IN 1998 FROM LASER 9700 OUTPUT;
COMMENT
			  COPYRIGHT (C) 1981
	     COLUMBIA UNIVERSITY BIOENGINEERING INSTITUTE
				  &
		VASOS-PETER JOHN PANAGIOTOPOULOS II
     TECHNICAL STANFORD-SAIL-ALGOL SUBROUTINE PACKAGE ONE SBRPC1
This project was funded in part (since April, 1979) by
	NSF Rat Skull Grant-Professor Melvin L. Moss-Fall 1979 only
	NIH HD14371 & HL16851 Professor Richard Skalak
	CU-CCA NCA-ID fund and other funds for educational computing
	Samani International Enterprises Siengg Computational Research Fund
	Vasos-Feter John Panagiotopoulos II
I wish to acknowledge the unlimited and most kind assistance of
        Professor Gautam Dasgupta.
References utilised:
	Numerical Analysis, Scheid, Schaum/McGrawHill
	Applied Numerical Methods, Carnahan, Luther&Wilkes,Wiley
	Introductory Computer Methods and Numerical Analysis,Pennington
	Advanced Calculus for Applications,Hildebrand
	Handbook of Mathematical Functions,Abramowitz&Stegun
The following Columbia courses:
		ChE3100X79,ChE4510Y81,ChE4520YS1
ENTRY	Factorial,Lagrange!lnterpolation,Average,Norm,Quadratic,matsum,
	Summation!Of!Function,secant!root,Newton!Raphson,Regula!Falsi,
	Power!Method,RUNGEK,realrd,read!arai,File!Read!Arai,Matrix!Print,
	FIBONACCI,gauss!jordan,Simpson,Recirculation,Max!Array,Min!Array,
	InstaPlot,cc!trapper,sink,Structural!Section,Monte!Carlo,
	Binary!Monte!Carlo,Gradient!Search,Gamma,Legendre!P,
        Weighted!Gauss!Legendre!Integration,
  	C!Conjugate,C!Add,C!Subtract,C!Abs,C!Multiply,C!Divide,C!ExP,CvCmplx
;
BEGIN "SBRPCl"
Require	"sai:abbrev.sai"  source!file;comment sail abbreviations package.;
Require	"omni:disprm.sai" source!file;comment sail omnigraph	 package.;
Require	"sai:routin.hdr"  source!file;comment sail routine	 package.;
Require	"sai:ttyio.hdr"   source!file;comment sail i/o   	 package.;
Define	 Tan(x)=            {sin(x)/cos(x)},
	 Degrees (radians)={radians*180/4/atan(1)},
	 Round!Off(x)=     {2*(x%2)},
	 Even!Odd(x)=      {2*abs(x/2-x%2)},
	 Kroenecker(i,j)=  {if i=j then 1 else 0},
	 Heaviside(x)=     {if x>O then 1 else 0},
	 Dirac(x)=         {if x=O then 1 else 0},
	 Permutation(i.J,k)={if i=j or j=k or i=k then 0 else
	        if  (i=1 and j=2 and k=3) or(i=2 and j=3 and k=1)
	                 or (i=3 and j=l and k=2)
	         then 1 else -1},
	 ARCOS(x)={4*ATAN(1)+ATAN((1+x^2)^.5/X)},
	 ARSIN(x)={-ARCOS((1-x^2)^.5)},
	 INFINITY={.1701412@39},
	 COMPLEX=                    {RECORD!POINTER(CMPLX)},
	 NEW!COMPLEX=                {NEW!RECORD(CMLX)};
  RECORD!CLASS CMPLX (REAL Re.lm);
Internal Real Procedure Factorial (Integer x);
	BEGIN  "Factorial Recursive (self-calling) procedure"
	  return(if x=O then I else x*factorial (x-1));
	END "Factorial Recursive (self-calling) procedure";
Internal Real procedure Lagrange!Interpolation (Real Array x,y;
                                                Integer n;
                                                Real xx);
  begin"Lagrange!Interpolation"
    real array 1 [1:n]
    integer i,j;
    real yy;
     for i:=1 step 1 until n do
        begin "Lagrange looping i=/=j"
          for j:=1 step 1 until n do if (j neq i) then
                l[i] =l[i]*(xx-x(j])/(x[i]-x[j])
		yy:=y[i]*l[i]+yy;
        end "Lagrange looping i=/=j";
    return (yy);
  end"Lagrange!Interpolation";

Internal Real Procedure Integral!of!Polynomial!Term(real a,b,n,u1,u2);
  begin "Integral Of Polynomial Term"
    comment Integral of (A+BU)+N from U1 to U2;
    return(if n neq -1 then((a+b*u2)f(n+1))/(n+1)/b-((a+b*u1)+(n+1))/(n+1)/b
		else 1/b*(log(a+b*u2)-log(a+b*u1));
  end "lntegral Of Polynomial Term";

Internal Real Procedure Average(real array a:integer n);
  begin "avg"
    real sum; integer m;m:=n;
     while (n:=n-1) do sum:=sum+a[n];
       return(sum/m);
  end "avg";

Internal Real Procedure Norm (Real Array Vector;Integer Rank);
  BEGIN "Norm of vector "
    REAL Scalar!Norm;
      while (rank:=rank-1) do Scalar!Norm:=Scalar!Norm+Vector[rank]+2;
     return(Scalar!Norm^.5);
  END "Norm of vector ";

Internal Procedure Quadratic(real a,b,c;
                    reference real first!root, second!root;
                    reference string root!type);
  begin "Quadratic"
    real g,d;
      g:=b^2-4*a*c;
      if (a=O) then
        begin "real1"
          first!root:=second!root:=-c/b;
          root!type:="single real root";
        end "real1";
       else
        begin "two-root"
          if (g>0) then
            begin "real2"
              d:=sqrt(g);
              first!root:=(-b-d)/(2.*a);
              second!root:=( b-d)/(2.*a);
 	      root!type:="double real roots";
            end "real2"
           else
            begin "cmp2"
	      first!root:=-b/2./a;
	      second!root:=sqrt(-g)/2/a;
		root!type:="imaginary first +/-second*i";
            end "cmp2";
	end "two-root";
    return;
  end "Quadratic";

Internal Real procedure matsum (real array x; integer dim);
   begin"matsum" real ssum;
      for dim:=dim step -l until 1 do ssum:=ssum+x [dim] ;return(ssum)
   end"matsum";

Internal Real procedure
                Summation!Of!Function(INTEGER Start!Index,End!Index,Interval;
                                      REAL X;
                                      REAL PROCEDURE Funct);
   begin"Summation!Of!Function"
      integer icount;real g;
         for icount:=start!index step Interval until End!lndex do
            g:=g+funct(x,icount);
      return (g)
   end"Summation!Of!Function";

Internal Real Procedure secant!root(REAL X0,X1,Accuracy;REAL PROCEDURE F);
   begin"sec" real x2;
      while (abs(f(xO))geq accuracy ) do
         x0:=(f(x1:=x0)*(x2:=x1)*f(x2)*x1)
                  /(f(x1)-f(x2));
      return (xO)
   end"sec";

Internal  Real procedure Newton!Raphson(REAL X0,X1,Accuracy;REAL PROCEDURE F);
   Begin "Newton Raphson Root Determination Reverse diff'
      Real x2;
         While (abs(f(x2)-f(x1)) geq accuracy) do
            x0:=((x2:=x1)-(x1:=x0))*f(x1)/(f(x1)-f(x2))+x1;
		Return (xO)
   End"Newton Raphson Root Determination Reverse diff";

Internal Real procedure Regula!Falsi(REAL XO,Xl,Accuracy;REAL PROCEDURE F):
   Begin"Regula Falsi According to Firouztale, Spencer & Wright"
      Real x2;
        While (abs(f(x2)-f(x1)) geq accuracy) do
           x0:=((x2:=x1)-(x1:=x0))*f(x1)/(f(x1)-f(x2))+x1;
	Return (x0);
   End"Regula Falsi According to Firouztale, Spencer & Wright";

lnternai Procedure Power!Method( Real array a;
                                 Reference Real Array Eigen!Vector;
                                 Integer Rank;
                                 Reference Real Eigen!Value;
                                 Real Accuracy);
   BEGIN "POWERM: Power Method of Mises for Eigen Systems"
      Comment   Panagiotopoulos Strikes Again
         Real Array Temp!Eigen!Pseudo[1:Rank];
         Integer I,J;
         Real Old!Eigen!Value;
          While ( Eigen!Value-Old!Eigen!Value>Accuracy) do
             BEGIN "Power Method Inner Block"
               Old!Eigen!Value:=Eigen!Value;
                Eigen!Value:=0;
               For I:=1 step 1 until Rank do
                 BEGIN "Mises"
                    For J:=1 step 1 until Rank do
                      Temp!Eigen!Pseudo[i]:=Temp!Eigen!Pseudo[i]
                        +a[j,3]*Eigen!Vector[3];
		      Eigen!value:=Eigen!Value+Temp!Eigen!Pseudo[i]^2;
                 END "Mises";
               Eigen!Value:=Eigen!Value^.5;
	      For I:=1 step 1 until Rank do
                Eigen!Vector[i]:=Temp!Eigen!Pseudo[i]/Eigen!Value:
	     END "Power Method Inner Block";
   If (Eigen!Vector[1) neq 0) then
     While(Rank:=Rank-1) do
		Eigen!Vector[Rank]:=Eigen!Vector[Rank]/Eigen!Vector[1];
   Return;
END "POWERM: Power Method of Mises for Eigen Systems";
Internal Procedure RUNGEK(REFERENCE REAL ARRAY X;
                   INTEGER N!Equations;
                   REAL PROCEDURE DRV;
                   REAL Delta!X, End!x);
BEGIN "RUNGEK: Runge-Kutta-Gill fourth-order Integration Program"
      Integer i,j,k;
      Real XX;
      Comment : 1)Derived from Taylor expansion of ODE
                2)DRV must return derivative of Jth function
                3)X has independant variable&'solutions
                4)IC's must be entered as x[O, _];
          for xx:=x[O,C] step DeltaIX until EndIX do
            BEGIN "Integration Stepping"
              Real Array C[1:4,1:N!Equations];
                i:=i+1;x[i,0]:=xx;
                for j:=1 step 1 until N!Equations do
                 BEGIN "Gill constants"
                   c[1,j]:=DRV(x[i,0],x[i,j],j);  
                   c[2,j]:=DRV(x[i,0]+.5*Delta!X,x[i,j]+.5*Delta!X*C[1,j],j);
                   c[3,j]:=DRV(x[i,0]+.5*Delta!X,x[i,j]+.2071068*Delta!X*C[1,j]
                       +.2928932*Delta!X*C[2,j]    ,j);
                   c[4,j]:=DRV(x[i,0]+Delta!X,x[i,j]-.7071068*Delta!X*C[1,j]
                       +1.7071068*Delta!X*C[3,j]    ,j);
                   c[i+1,j]:=x[i,j]
                           +Delta!X/6*
                                    (           C[1,j]
                                                +.2928932*C[2,j]
		                                +3.4142136*c[3,j]
                                                +C[4,j]
                                    );
                 END "Gill constants":
                for j:=1 step 1 until N!Equations do
                          If(ABS(  (C[3,j]-C[2,j])
                                  /(C[2,j]-C[1,j])
                                  )
                                >.01
                             )
                          Then Delta!X:=Delta!x/10;
              END "Integration Stepping";
END "RUNGEK: Runge-Kutta-Gill fourth-order Integration Program";

Internal Real procedure realrd(string s);
      begin "realrd"
	  ! input real constants and assign to real variables;
          real f; string a;
          print(13&10&"Please input ",s,">  ");
          a:=inchwl;f:=realscan(a,32);
          return (f)
      end "realrd";

Internal Procedure read!arai (reference real array a; integer n;string name);
  begin"araird" string ary; integer i;
      !similarly input arrays;
      print (13&10&"Type in array,"&name&", elements sep by space,",
               "<cr> when finished;",n,"elements "&13&10&" > ");
      ary:=inchwl;
      for i:=1 step 1 until n do a[i]:=realscan(ary,32);
  end"araird"; 

Internal Procedure File!Read!Arai (REFERENCE REAL Array A;
                          INTEGER N,Channel,BreakTable);
  begin"array-file" STRING Ary; INTEGER I;Ary:=NULL;
    for i:=0 step 1 until n do
      begin "ary-in"
       if ary=null then ary:=input(Channel,Breaktable);
		a[i]:=realscan(ary,32)
      end "ary-in";
  end"array-file";
Internal Simple Procedure Matrix!Print(REAL ARRAY A;
                              INTEGER Down,Accross;
                              STRING Name);
  BEGIN "Print a two-dimensional array" Integer I,J;
    Print (10&13&9&"Matrix:"&Name&13&10);
     For I:=1 step 1 until Down do
       BEGIN "Matrix looping"
          for j:=1 step 1 until accross do
		Print (a[i,j] ,32&null)
          Print (13&10&Null);
        END "Matrix looping";
  END "Print a two-dimensional array";

Internal Real Procedure FIBONACCI(REAL Aa,Bb,Accuracy;
                          REAL PROCEDURE  F);
  begin"fibonacci"
  ! MAXIMISATION -give neg fct for min;
  real new!fibonacci,fibonacci!old,temporary,tau,l,r,a,b;
       fibonacci!old:=0;new!fibonacci:=1;l:=a:=aa;r:=b:=bb;
       while abs((l-r)/r)>accuracy do
          begin"fibonacci section"
            new!fibonacci:=fibonacci!old+new!fibonacci
                 +O*(fibonacci!old:=new!fibonacci);
            tau:=fibonacci!old/new!fibonacci;
            l:=b-tau*abs(b-a);r:=a+tau*abs (b-a);
            if f(l)>f(r) then b:=r else a:=l;
            if a<aa or b>bb then done;
 	  end"fibonacci section";
      return((a+b)/2);
  end"fibonacci";

Internal Procedure gauss!jordan (reference real array a,bb;integer n);
  begin "gauss" real array c[1:n,1:n+1],b,d,e [1:n+1]
    integer i,ipl,j,m,k,l,ko,km;real r,rl,s;label unitise,skip;
    comment The Panagiotopoulos-Snyder matrix zonker;
    for i:=1 step 1 until n do for j:=i step 1 until n do c[i,j]:=a[i,j];
    for i:=1 step 1 until n do c[i,n+1]:=bb[i];
    for i:=1 step 1 until n do
     begin "gj1"
      r:=c[i,i];     if (i geq n) then go unitise;     m:=i;ip1:=i+1;
      for j:=ip1 step 1 until n do
       begin "gj2"
          r1:=abs(c[m,i]); s:=abs(c[j,i]);if (r1<s) then m:=j;
       end "gj2";
     if(m=i) then go unitise; r:=c[m,i];
     for j:=i step 1 until n+1 do
	begin "gj3" b[j]:=c[i,j];c[i,j]:=c[m,j];c[m,j]:=b[j];end "gj3";
     unitise:    for k:=1 step 1 until n+1 do b[k]:=c[i,k]/r;
     for k:=1 step 1 until n do
       begin "gj4" s:=c[k,i]; if (s=0) then go skip;
         for l:=1 step 1 until n+1 do d[l]:=-s*b[l];
         for ko:=1 step 1 until n+1 do e[ko]:=c[k,ko]+d[ko];
         for km:=1 step 1 until n+1 do c[k,km]:=e[km];	skip:
       end "gj4";
      for k:=1 step 1 until n+1 do c[i,k]:=b[k];
    end "gj1";
  for i:=1 step 1 until n do bb[i]:=c[i,n+1];
end "gauss";

Internal Real Procedure Simpson (real delta!x;real array y; integer n!rows);
       begin "simpsn"
               define oddevn(i)={i-2*(i%2)};
               real s;integer i;
               for i:=0 step 1 until n!rows do
                       if i=0 or i=n!rows then s:=s+y[i] else
                              if oddevn(i) then s:=s+4*y[i] else
                                        s:=s+2*y[i];
               s:=s*delta!x/3;return(s);
       end"simpsn";

Internal Real Procedure Max!Array(Real Array Our!Vector;
                         Integer Dimension)

  BEGIN "Maximum of Vector"	Real Maximum; Maximum:=-INFINITY;
    Dimension:=Dimension+1;
	While (Dimension:=Dimension-1) do
	if Our!Vector[Dimension]>Maximum then Maximum:=Our!Vector[Dimension];
    Return (Maximum)
END "Maximum of Vector";

Internal Real Procedure Min!Array(Real Array Our!Vector;
                         Integer Dimension);
  BEGIN "Minimum of Vector"	Real Minimum: Minimum:=INFlNITY;
    Dimension:=Dimension+1;
	While (Dimension:=Dimension-1) do
	if Our!Vector[Dimension]<Minimum then Minimum:=Our!Vector[Dimension];
    Return (Minimum);
  END "Minimum of Vector";

Internal Procedure Recirculation(Real Array X,R,T;
                        Reference Real Array Recirculation;
                        Integer Vector!Length);
  begin "Cardiac Recirculation"
    Integer I;
	begin "loop"
	Real Total!Mass,Mass!Integral,Max!Mass,Delta!T;
        Integer I!T,Chan;
        Real Array!Temp[0:Vector!Length];
             delta!t:=t[2]-t[1];
             total!mass:=(mass!integral:=simpson(delta!x,vector!length))
		/delta!t/vector!length;
             max!Mass:=Max!Array(x,vector!length);
             for i:=0 step 1 until vector!length do
              begin "recirc fro temp"
               for i!t:=1 step 1 until vector!length-! do
                 if (i-i!t)geq 0 then
                    temp[i!t]:=x[i!t]*r[i-i!t]/max!mass;
                recirculation[i]:=simpson(delta!t,temp,i);
               end  "recirc fro temp";
        end"loop";
  end"Cardiac Recirculation";

Internal Procedure Instaplot(REAL ARRAY X,Y,Window!Points,Text!XY!Location;
                        INTEGER Dimension,Picture!Number,Plotter!Type;
                        STRING PLX!File!Name,Text;
                        BOOLEAN Insta!Window,Want!Axes,Want!PLX!File,Want!Text,
                                   Want!Ticks!Labeled,New!Picture);
  BEGIN "InstaFlot"	
    integer i;
     if not New!Picture
       then dappend(Picture!Number)
       else
         begin "Open New Picture"
                   dini (Plotter!Type,0,0,0);dget;
                   If Insta!Window then
                      BEGIN "Instant Windowing"
                        Window!Points[1]:=Min!Array(x,dimension);
		        Window!Points[2]:=Max!Array(x,dimension);
                        Window!Points[3]:=Min!Array(y,dimension);
                        Window!Points[4]:=Max!Array(y,dimension);
                      END "Instant Windowing";
                   dwind(Window!Points[1],Window!Points[2],
                         Window!Points[3],Window!Points[4]);
                   dopen(Picture!Number);
                   if Want!Axes then
                      BEGIN "Plot Axes"
                        dvect(Window!Points[1],Window!Points[3],
                              Window!Points[2],Window!Points[3]);
                        dvect(Window!Points[1],Window!Points[3],
                              Window!Points[1],Window!Points[4]);
                        dvect(Window!Points[1],Window!Points[4],
                              Window!Points[2],Window!Points[4]);
                        dvect(Window!Points[2],Window!Points[3],
                              Window!Points[2],Window!Points[4]);
                      END "Plot Axes";
                   if Want!Ticks!Labeled then
                      BEGIN "Make Tick Marks"
                         Real X!Removed,Y!Removed;
                           X!Removed:=(Window!Points[2]
                                      -Window!Points[1])
                                   *(-.075);
                           Y!Removed:=(Window!Points[4]
                                      -Window!Points [3])
                                   *(-.075);
                           Setformat(3,2);
                           DMove(
                                 Window!Points[1],
                                 Window!Points[3]
                                  -Y!Removed);
                           DText(CVG(
				(Window!Points[1])));
                           DMove(
                                (Window!Points[2]
                                 +Window!Points[1])/2,
                                 Window!Points[3]
                                  -Y!Removed);
                           DText(CVG((Window!Points[2]
                                 +Window!Points[1])/2
                                ));
                           DMove(
                                Window!Points[2],
                                Window!Points[3]
                                 -Y!Removed);
                           DText(CVG((Window!Points[2])
                                )); 
                           DMove(
                                Window!Points[1]
                                 -X!Removed,
                                Window!Points[3]);
                           DText(CVG((Window!Points[3])
                                ));
                           DMove(
                                Window!Points[1]
                                 -X!Removed,
                               (Window!Points[4]
                               +Window!Points[3])/2);
                           DText(CVG(
                               (Window!Points[4]
                               +Window!Points[3])/2
                               ));
                           DMove(
                                Window!Points[1]
                                    -X!Removed,
                                Window!Points[4]);
                           DText(CVG((Window!Points[4])
                                )); 
                           SetFormat(13,6);
                      END "Make Tick Marks";
         end "Open New Picture";
      for i:=1 step 1 until Dimension do ddraw (x[i] ,y[i]);
   BEGIN "Close Plot"
      INTEGER Terminal!Channel,File!Hexnumber;
      REAL ARRAY Buffer!Pointer[1:128];
    if Want!PLX!file then
	BEGIN "PLX quiet term step one"
                terminal!channel:=openfile("TTY:","RW");
                Fiie!Hexnumber:=cvsix(PLX!File!Name)
		!Terminal , Shut Up!!;
                sfmod(Terminal!Channel,
                        '400000000000 LOR rfmod(Terminal!Channel));
        END "PLX quiet term step one";
        If Want!Text then
               BEGIN "Make Text"
                       dmove(Text!XY!Location[1],Text!XY!Location[2]);
                       dtext(Text);
               END "Make Text";
      dget;dpost(Picture!Number);            ddone;
     If Want!PLX!File then dplot(Buffer!Pointer[1],File!Hexnumber);
     dunpost(Picture!Number);
     If Want!PLX!File then
        BEGIN "PLX quiet term step two't
             sfmod (Terminal!Channel,
		'377777777777 LAND rfmod(Terminal!Channel))
             cfile(Terminal!Channel);
	END "PLX quiet term step two";
   END "Close Plot";
  END "Instaplot";

Internal   SIMPLE PROCEDURE cc!trapper(procedure trap!proc);
begin "assembler routine"
	start!code			comment start assembler code;
          movei 1,'400000;		comment move octal immed to 1;
	  hrlzi 3,'400000;		comment half word instuction;
	  epcap;			comment enable capabilities;
	end;				comment end assembler code;
	Psimap(34,trap!proc,0,1);	comment chan 34 calls trap!proc;
	Enable(34);			comment enable channel 34;
	Ati(34,3);			comment use warning if ASCII #3;
		end"assembler routine";
Internal simple procedure sink;
  BEGIN "SINK:CUBI logout procedure"
    start!code		comment start assembler code;
			dtach;		comment detach current job;
			movni 1,1;	comment move neg immmed of 1 to 1
						to specify current job;
			lgout;		comment now logout detached job
						which spec'd by -1/curr;
	end;	comment end assembler code;
  END "SINK:CUBI logout procedure";
Internal Procedure Structural Section;
  BEGIN "Structural Section Properties, Interactive"
    INTEGER No!Coordinates;
    Real Array x,y,inertia[O:4]
    REAL height,area,area!x,top!section!mod,bottom!section!mod;
        no!coordinates:=realrd("Number of Coordinates");
        height:=realrd("Section Height");
        x[0]:=realrd("Starting X Coordinates");
        y[0]:=realrd("Starting Y Coordinates");
          While(no!coordinates:=no!coordinates-1) do
                BEGIN "Centroid Averaging"
                  x[1]:=realrd("Next X");
                  y[1]:=realrd("Next Y");
                  x[2] =x[1]+x[0];
		  x[3]:=x[1]-x[0];
                  y[2]:=y[1]-y[0];
                  y[3]:=y[1]+y[0];
                  area:=area-y[2]*x[2]/2;
                  x[4]:=x[4]+y[2]/ 8*(x[2]^2+x[3]^2);
                  inertia[1]:=inertia[1]
		       +x[3]*y[3]/24*(y[2]^2+y[3]^2);
                  inertia[2]:=inertia[2]
		       -x[2]*y[2]/24*(x[2]^2+x[3]^2);
		    x[0]:=x[1];y[0]:=y[1];area!x:=-area;
                END "Centroid Averaging";
        x[4]:=x[4]/area!x;y[4]:=y[4]/area;
       inertia[3]:=inertia[1]-area*y[4]^2;
       inertia[4]:=inertia[2]-area*x[4]^2;
       y[0]:=height-y[4];
       top!section!mod:=inertia[3]/y[4];
       bottom!section!mod:=inertia[3]/y[0];
      PRINT(13&10&"STRUCTURAL SECTION PROPERTIES:
		**ASSUMING HOMOGENEOUS DIMENSIONS** -
		AREA:", area,
                13&10&"X-Axis Moment of Inertia:" ,inertia[3],
                13&10&"Centroid to Top:'t,y[0],
                13&10&"Centroid to Bottom:",y[4],
                13&10&"Bottom Section Modulus:",bottom!section!mod,
		13&10&"Top Section Modulus:",top!Section!mod,12&0);
   END "Structural Section Properties, Interactive";
Internal Procedure Monte!CarIo(REFERENCE REAL ARRAY X;
                               INTEGER Order, N!Step);
   BEGIN "Monte Carlo Random Path"
      INTEGER N,Power10;
         x[1]:=1;
         Power10:=10+Order;
         For n:=1 step 1 until (n!step-1) do
           x[n+1]:=(x[n]*4782969) mod power1O;
         return;
   END "Monte Carlo Random Path";
Internal Procedure Binary!Monte!Carlo(REFERENCE REAL ARRAY X;
                             INTEGER Order, N!Step,Large!Number)
  BEGIN "Monte Carlo Random Path ,Binary"
    INTEGER N,Power2;
      x[1] =1;
      Power2:=2+Order;
      Large!Number:=Large!Number*8-3;
      For n:=1 step 1 until (n!step-1) do
        BEGIN "Binary Assembler Operations"
	   real xx,xxx;
             xx:=x[n]
	        Start!Code		comment begin assembler;
                         move 1,xx;	comment put x[n] in 1;
			 imul 1,large!number; comment xx*larg..;
			 idiv 1,power2; comment div by power2;
			 movem 2,xxx;	comment remainder in 2;
		end;			comment end assembler code;
	    x[n+1]:=xxx;
	END "Binary Assembler Operations";
    return;
  END "Monte Carlo Random Path ,Binary";
Internal Procedure Gradient!Search(REAL PROCEDURE F;
			  REFERENCE REAL ARRAY X;
			  REAL Delta,Accuracy,Initial!Slope;
			  REAL ARRAY X!Upper,X!Lower;
			  INTEGER Vector!Length;
			  REFERENCE BOOLEAN Out!Of!Bounds);
  BEGIN "Gradient Search acc. to Prof. Amir N. Nahavandi"
    COMMENT : 0) Panagiotopoulos baffles them again!
	      1) F should return dependant variable for vector set of
                     all independant variables passed.
	      2) Delta passed is used as norm of Delta!X.
	      3) lf search goes out of bounds then nothing is returned and
		         Out!Of!Bounds is set true.
	      4) X is the vector of independant variables.
	      5) Vector Slope is the gradient for the current iteration.
                        It is initially set so that each element is equal to
                        a guessed slope, lnitial!Slope.
              6) Algorithm due to class notes of ChE451OY81 as taught by
		        Professor Amir N. Nahavandi of CU ChE,AP/ENE&ME.
    ;
       Real array X!Old,Slope,Delta!X[1:Vector!Length];
       Boolean Converged,First!Iteration;
          Out!Of!Bounds:=false;
          Converged:=false;
	  First!Iteration:=true;
          While not converged do
             BEGIN "Search by max'd slope"
                Real Slope!Norm,Delta!X!Norm,Avg!Delta!X;
                Integer I,J;
                  If first!iteration
                      then
                        for i:=1 step 1 until Vector!Length do
                           Slope [i]:=Initial!Slope
                      else
                        for i:=1 step 1 until Vector!Length do
                           Slope[i]:=(f(x)-f(x!old))/Delta!X[i];
		  First!Iteration:=false;
                  Slope!Norm:=Delta!X!Norm:=Avg!Delta!X:=0;
                  Slope!Norm:=NORM(Slope,Vector!Length);
                  Delta!X[1] :=slope[1]/slope!norm*delta;
		  for i:=2 step 1 until vector!length do
		          delta!X[i]:=delta!x[1]*slope[i]/slope[1]
                    comment by condition of maximised slope, i.e.,
                            by setting derivatives of hyperplane
                            slopes to zero;
                  Delta!X!Norm:=NORM(Delta!X,Vector!Length);
		  Avg!Delta!X:=AVERAGE(Delta!X,Vector!Length);
                  If (avg!delta!x*vector!length/delta!x!norm<accuracy)
                           then converged:=true;
		  For i:=1 step 1 until vector!length do
                         if x[i]>x!upper[i] or x[i]<x!lower[i]then
                             out!of!bounds:=true;
		  for i:=1 step 1 until vector!length do
                          x[i]:=(x!old[i]:=x[i])+delta!x[i];
             END "Search by max'd slope";
         if not out!of!bounds then return;
	END "Gradient Search acc. to Prof. Amir N. Nahavandi";
Internal REAL PROCEDURE GAMMA(REAL X);
	BEGIN "gamma function"
          return (
            if x=1 then 1
                else if x=.5 then 2*atan(1)^.5
		else if x<0 then gamma(x+1)/x
		else if x=0 then 1
		else if (x mod 1)=0 then (x-1)*gamma(x-1)
                else 1/(x+.57721*x^2-.65588*x^3-.042*x^4+.16654*x^5-.0422*x^6
                        -.00962*x^7+.0072189*x^8)
            );
        END "gamma function";
Internal Real Procedure Legendre!F(real x; integer n)
   BEGIN" Legendre P polynomial trig expsn 3 terms acc. to Abramowitz&Stegun"
      real p,theta;
      theta:=arcos(x);
         return (2^(2*n+1)*factorial(n)^2/factorial(2*n+1)
                  *(sin((n+1)*theta)+(n+1)/ (2*n+3)*sin((N+3)*theta)
                          +1.5*(n+1)*(n+1)/ (2*n+3)/ (2*n+5)*sin((n+5)*theta)
   END "Legendre P polynomial trig expsn 3 terms acc. to Abramowitz&Stegun";
Internal REAL PROCEDURE Weighted!Gauss!Legendre!Integration(REAL ARRAY X!Vector;
                                    INTEGER Vector!Length;
                                    REAL PROCEDURE F;
                                    REAL X!Initial,X!Final);

   BEGIN "Gauss-Legendre Integration acc. to Abramowitz & Stegun"
      REAL Sum;INTEGER I;REAL x;
        for I:=1 step 1 until Vector!Length do
           BEGIN "Gauss Legendre Weighting Factor Summing"
              x:=(-x!Initial-X!Final +2*X!Vector[i])/(X!Final-X!Initial);
              sum:=sum+f(x)*2/(1-x^2)/Legendre!p(X!Vector!Length)^2;
	   END "Gauss Legendre Weighting Factor  Summing";
        Return (sum/2*(X!Final-X!Initial));
   END "Gauss-Legendre Integration acc. to Abramowitz & Stegun";
INTERNAL COMPLEX PROCEDURE C!Conjugate(COMPLEX z);
	BEGIN "Complex Conjugate"
		CMPLX:Im[Z]:=-CMPLX:Im[Z]
	END "Complex Conjugate";
INTERNAL COMPLEX PROCEDURE C!Add(COMPLEX z1,z2);
   BEGIN "Complex Addition"
      COMPLEX Z; Z:=NEW!COMPLEX;
        CMPLX:Re[Z]:=CMPLX:Re[Z1]+CMPLX:Re[Z2];
        CMPLX:Im[Z]:=CMPLX:Im[Z1]+CMPLX:Im[Z2];
      RETURN (Z);
   END "Complex Addition";
INTERNAL COMPLEX PROCEDURE C!Subtract(COMPLEX z1,z2);
  BEGIN "Complex Subtraction"
    COMPLEX Z; Z:=NEW!COMPLEX;
	CMPLX:Re[Z]:=CMPLX:Re[Z1]-CMPLX:Re[Z2];
        CMPLX:Im[Z]:=CMPLX:Im[Z1]-CMPLX:Im[Z2];
    RETURN(Z);
  END "Complex Subtraction";
INTERNAL REAL PROCEDURE C!Abs(COMPLEX Z);
  BEGIN "Absolute Value of Complex Number"
	RETURN((CMPLX:Re[Z]^2 + CMPLX:Im[Z]^2)^.5);
  END "Absolute Value of Complex Number";
INTERNAL COMPLEX PROCEDURE C!Multiply(COMPLEX Z1,Z2);
  BEGIN "Complex Multiplication"
    COMPLEX Z; Z:=NEW!COMPLEX;
      CMPLX:Re[Z]:=CMPLX:Re[Z1]*CMPLX:Re[Z2]-CMPLX:Im[Z1]*CMPLX:Im[Z2];
      CMPLX:Im[Z]:=CMPLX:Re[Z1]*CMPLX:Im[Z2]+CMPLX:Re[Z2]*CMPLX:Im[Z1];
    RETURN(Z);
  END "Complex Multiplication":
INTERNAL COMPLEX PROCEDURE C!Divide(COMPLEX Z1,Z2);
  BEGIN "Complex Division"
    REAL Denominator; COMPLEX Z; Z:=NEW!COMPLEX;
      Denominator:=CMPLX:Re[Z2]^2-CMPLX:Im[Z2]^2
      CMPLX:Re[Z]:=(CMPLX:Re[z1]*(CMPLX:Re[z2]+CMPLX:Im[z1]*CMPLX:Im[Z2]))
	/Denominator;
      CMPLX:Im[Z]:=(CMPLX:Im[z1]*(CMPLX:Re[z2]-CMPLX:Re[z1]*CMPLX:Im[Z2]))
	/Denominator;
      RETURN (z)
  END "Complex Division";
INTERNAL COMPLEX PROCEDURE C!EXP(COMPLEX z):
  BEGIN "Complex Eulerian Antilogarithm"
   REAL R!Exponentiated,Theta;  COMPLEX ZZ; ZZ:=NEW!COMPLEX;
      R!Exponentiated:=EXP(C!Abs(Z))
      Theta:=ATAN(-CMPLX:Im[Z]/CMPLX:Re[Z]);
      CMPLX:Re[ZZ]:=COS(Theta)*R!Exponentiated;
      CMPLX:Im[ZZ]:=SIN(Theta)*R!Exponentiated;
     RETURN (ZZ);
  END "Complex Eulerian Antilogarithm";
INTERNAL STRING PROCEDURE CvCmplx(COMPLEX z);
  BEGIN "Complex to String Conversion for output"
    RETURN (Cvs(CMPLX:Re[Z]) 
             & (If CMPLX:Im[Z] < 0 then " - " else " + ") &
             Cvs(CMPLX:Im[Z])&"i");
  END "Complex to String Conversion for output";
END "SBRPC1";