home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / simplex / simplex2.pas
Encoding:
Pascal/Delphi Source File  |  1986-04-15  |  23.2 KB  |  924 lines

  1. Overlay Procedure Simplex;
  2.                   { Curve fitting with the Simplex Algorithm}
  3.                   { m is the number of parameters to fit, n       }
  4.                   { is m + 1, nvpp = number of vars per data point}
  5. Const
  6.   n_max              = 11;   { m + 1                             }
  7.   nvpp_max           = 10;   { maximum no. of variables per data point}
  8.   maxiter            = 100;  { maximum no. of iterations         }
  9.   alfa               = 1.0;  { Reflection coefficient, > 0       }
  10.   beta               = 0.5;  { Contraction coefficient, in(0..1) }
  11.   gamma              = 2.0;  { expansion coefficient, > 1        }
  12.   LW                 = 5;
  13.   MaxNumLength       = 10;
  14.   MaxExpression      = 100;
  15.   MaxToken           = 100;
  16.   MaxPriority        = 6;
  17.   MaxParam           = 50;
  18.   NameLength         = 7;
  19.   FirstUnary         = 4;
  20.   LastUnary          = 15;
  21.   FirstBinary        = 16;
  22.   LastBinary         = 22;
  23.   LastOperand        = 24;
  24.   MaxString          = 200;
  25.  
  26. Type
  27.   vector             = array[1..n_max] of real;
  28.   index              = 0..255;
  29.   PriorRange         = 1..MaxPriority;
  30.   Name               = String[NameLength];
  31.   Token              = 0..MaxToken;
  32.   TokenKind          = (Operand,UnaryOp,BinaryOp,EndExpression,LeftParen,
  33.                         Variable,RightParen);
  34.   DeftToken          = Record
  35.                          NM      : Name;
  36.                        Case K: TokenKind of
  37.                          Variable,
  38.                          Operand    :  (Val : Real);
  39.                          UnaryOp,
  40.                          BinaryOp   :  (Pri : PriorRange);
  41.                          EndExpression,
  42.                          LeftParen,
  43.                          RightParen : ()
  44.                        End;
  45.   Expression         = array[1..MaxExpression] of Token;
  46.   ExprIndex          = 0..MaxExpression;
  47.   Param              = 0..MaxParam;
  48.   Message            = String[255];
  49.  
  50.  
  51. Var
  52.   vars          : array[1..nvpp_max] of index;
  53.   done          : boolean;
  54.   Nvars         : index;
  55.   H,L           : array[1..n_max] of index;
  56.   niter,m,n,
  57.   I,J           : integer;
  58.   next, center,
  59.   mean, error,maxerr,
  60.   p,q,step      : vector;
  61.   simp          : array[1..n_max] of vector;
  62.   Root2,Z       : real;
  63.   PostFix       : Expression;
  64.   Lexicon       : Array[Token] of DeftToken;
  65.   Nparameter    : Param;
  66.   Parameter     : Array[Param] of Token;
  67.  
  68.   InString      : String[MaxString];
  69.  
  70. {$V-}
  71. Procedure Errors(Line: Message);
  72. Begin
  73.   TextBackground(4) ; textcolor(0);
  74.   Writeln(' ERROR!! ');
  75.   TextBackground(0); TextColor(15);
  76.   Writeln(Line);
  77.   Halt;
  78. End;
  79. {$V+}
  80.  
  81. Procedure DefineTokens;
  82. Begin
  83.   Lexicon[1].NM  :=  '';
  84.   Lexicon[1].K   := EndExpression;
  85.   Lexicon[2].NM  := '(';
  86.   Lexicon[2].K   := LeftParen;
  87.   Lexicon[3].NM  := ')';
  88.   Lexicon[3].K   := RightParen;
  89.   Lexicon[4].NM  := '\';
  90.   Lexicon[4].K   := UnaryOp;
  91.   Lexicon[4].Pri := 6;
  92.   Lexicon[5].NM  := 'ABS';
  93.   Lexicon[5].K   := UnaryOp;
  94.   Lexicon[5].Pri := 6;
  95.   Lexicon[6].NM  := 'SQR';
  96.   Lexicon[6].K   := UnaryOp;
  97.   Lexicon[6].Pri := 6;
  98.   Lexicon[7].NM  := 'SQRT';
  99.   Lexicon[7].K   := UnaryOp;
  100.   Lexicon[7].Pri := 6;
  101.   Lexicon[8].NM  := 'EXP';
  102.   Lexicon[8].K   := UnaryOp;
  103.   Lexicon[8].Pri := 6;
  104.   Lexicon[9].NM  := 'LN';
  105.   Lexicon[9].K   := UnaryOp;
  106.   Lexicon[9].Pri := 6;
  107.   Lexicon[10].NM  := 'LOG';
  108.   Lexicon[10].K   := UnaryOp;
  109.   Lexicon[10].Pri := 6;
  110.   Lexicon[11].NM  := 'SIN';
  111.   Lexicon[11].K   := UnaryOp;
  112.   Lexicon[11].Pri := 6;
  113.   Lexicon[12].NM  := 'COS';
  114.   Lexicon[12].K   := UnaryOp;
  115.   Lexicon[12].Pri := 6;
  116.   Lexicon[13].NM  := 'ARCTAN';
  117.   Lexicon[13].K   := UnaryOp;
  118.   Lexicon[13].Pri := 6;
  119.   Lexicon[14].NM  := 'ROUND';
  120.   Lexicon[14].K   := UnaryOp;
  121.   Lexicon[14].Pri := 6;
  122.   Lexicon[15].NM  := 'TRUNC';
  123.   Lexicon[15].K   := UnaryOp;
  124.   Lexicon[15].Pri := 6;
  125.   Lexicon[16].NM  := '+';
  126.   Lexicon[16].K   := BinaryOp;
  127.   Lexicon[16].Pri := 4;
  128.   Lexicon[17].NM  := '-';
  129.   Lexicon[17].K   := BinaryOp;
  130.   Lexicon[17].Pri := 4;
  131.   Lexicon[18].NM  := '*';
  132.   Lexicon[18].K   := BinaryOp;
  133.   Lexicon[18].Pri := 5;
  134.   Lexicon[19].NM  := '/';
  135.   Lexicon[19].K   := BinaryOp;
  136.   Lexicon[19].Pri := 5;
  137.   Lexicon[20].NM  := 'DIV';
  138.   Lexicon[20].K   := BinaryOp;
  139.   Lexicon[20].Pri := 5;
  140.   Lexicon[21].NM  := 'MOD';
  141.   Lexicon[21].K   := BinaryOp;
  142.   Lexicon[21].Pri := 5;
  143.   Lexicon[22].NM  := '^';
  144.   Lexicon[22].K   := BinaryOp;
  145.   Lexicon[22].Pri := 6;
  146.   Lexicon[23].NM  := 'PI';
  147.   Lexicon[23].K   := Operand;
  148.   Lexicon[23].Val := 3.14159;
  149.   Lexicon[24].NM  := 'E';
  150.   Lexicon[24].K   := Operand;
  151.   Lexicon[24].Val := 2.71828;
  152. End;
  153.  
  154. Function Kind(T: Token) : TokenKind;
  155. Begin
  156.   Kind := Lexicon[T].K
  157. End;
  158.  
  159.  
  160. Procedure StartExpression;
  161. Const
  162.   HashSize        = 101;
  163.  
  164. Type
  165.   Address         = 0..HashSize;
  166.   IndexName       = 0..NameLength;
  167.   IndexString     = 0..MaxString;
  168.  
  169. Var
  170.   InFix           : Expression;
  171.   H               : Array[Address] of Token;
  172.   TokenCount      : Token;
  173.  
  174. Function Hash(X: Name) : Address;
  175. Var
  176.   A     : Integer;
  177.   Ch    : Char;
  178.   Found : Boolean;
  179. Begin
  180.   If Length(X) <= 0 then
  181.     Errors('Hash attempted with empty name')
  182.   Else Begin
  183.     Ch := X[1];
  184.     A  := Abs( Ord(Ch)) mod HashSize;
  185.     Repeat
  186.       If H[A] = 0 then
  187.         Found := True
  188.       Else if Lexicon[H[A]].NM = X then
  189.         Found := True
  190.       Else Begin
  191.         If Length(X) > 1 then
  192.           Begin
  193.             Ch := X[2];
  194.             A  := A + Abs(Ord(Ch));
  195.           End
  196.         Else
  197.           A := A + 29;
  198.         If A > HashSize then A := A mod HashSize;
  199.         Found := False
  200.       End
  201.     Until Found;
  202.     Hash := A
  203.   End
  204. End;
  205.  
  206. Procedure MakeHashTable;
  207. Var
  208.   A     : Address;
  209.   T     : Token;
  210.  
  211. Begin
  212.   For A := 0 to HashSize do
  213.     H[A] := 0;
  214.   For T := 2 to LastOperand do
  215.      H[Hash(Lexicon[T].NM) ] := T;
  216. End;
  217.  
  218.  
  219.  
  220. Procedure ReadExpression;
  221. Var
  222.   ExprLength     : ExprIndex;
  223.   Position       : IndexString;
  224.   ParenCount     : Integer;
  225.   Digit,Alphabet,
  226.   Lower          : Set of Char;
  227.  
  228. Procedure PutToken(X: Token);
  229. Begin
  230.   ExprLength := Succ(ExprLength);
  231.   InFix[ExprLength] := X;
  232. End;
  233.  
  234.  
  235. Function Leading: Boolean;
  236. Var K : TokenKind;
  237. Begin
  238.   If ExprLength = 0 then
  239.     Leading := True
  240.   Else begin
  241.     K := Kind(InFix[ExprLength]);
  242.     Leading := (K = LeftParen) or (K = UnaryOp) or (K = BinaryOp)
  243.   End;
  244. End;
  245.  
  246. Procedure FindWord;
  247. Var
  248.   Word           : Name;
  249.   T              : Token;
  250.   I              : IndexName;
  251.   NewPosition    : IndexString;
  252.  
  253. Begin
  254.   NewPosition := Position + 1;
  255.   While InString[NewPosition] in (Alphabet + Digit) do
  256.     NewPosition := Newposition + 1;
  257.   If NewPosition - Position <= NameLength then
  258.     Word := Copy(InString,Position,NewPosition - Position)
  259.   Else Begin
  260.     Word := Copy(Instring,Position,NameLength);
  261.     Writeln('Warning: the name ',Word,' has been truncated');
  262.   End;
  263.   For I := 1 to Length(Word) do
  264.     If Word[I] in Lower then Word[I] := UpCase(Word[I]);
  265.   T := H[Hash(word)];
  266.   If T <> 0 then
  267.     If Leading then
  268.       If Kind(T) = BinaryOp then
  269.         Errors('Binary Operator in illegal Postion')
  270.       Else
  271.         PutToken(T)
  272.     Else
  273.       If Kind(T) <> BinaryOp then
  274.         Errors('Binary Operator Expected')
  275.       Else
  276.         PutToken(T)
  277.   Else
  278.     If TokenCount >= MaxToken then
  279.       Errors('Too many distinct variables and constants')
  280.     Else if not Leading then
  281.       Errors('Operand immediately follows ) or another Operand')
  282.     Else begin
  283.       TokenCount := TokenCount + 1;
  284.       H[Hash(Word)] := TokenCount;
  285.       Lexicon[TokenCount].NM := Word;
  286.       Lexicon[TokenCount].K  := Operand;
  287.       If Nparameter >= MaxParam then
  288.         Errors('Too many parameters')
  289.       Else begin
  290.         Nparameter := Nparameter + 1;
  291.         Parameter[Nparameter] := TokenCount;
  292.         PutToken(TokenCount);
  293.       End;
  294.     End;
  295.   Position := NewPosition;
  296. End;
  297.  
  298. Procedure FindNumber;
  299. Var
  300.   NumberName,X          : String[MaxNumLength];
  301.   DecPoint,NewPosition  : IndexString;
  302.   R                     : Real;
  303.   Code                  : Integer;
  304.  
  305. Begin
  306.   If Not Leading then
  307.     Errors('Constant in Illegal Position')
  308.   Else if TokenCount >= MaxToken then
  309.     Errors('Too many Constants and Variables')
  310.   Else Begin
  311.     NewPosition := Position;
  312.     While Instring[NewPosition] in (digit + ['.','e','E']) do
  313.       NewPosition := NewPosition + 1;
  314.     X := Copy(Instring,Position,NewPosition - Position);
  315.     If Length(X) <= Namelength then
  316.       NumberName := X
  317.     Else
  318.       NumberName := Copy(X,1,NameLength);
  319.     Val(X,R,Code);
  320.     TokenCount   := TokenCount + 1;
  321.     Lexicon[TokenCount].NM  := NumberName;
  322.     Lexicon[TokenCount].K   := Operand;
  323.     Lexicon[TokenCount].Val := R;
  324.     PutToken(TokenCount);
  325.     Position := NewPosition;
  326.   End;
  327. End;
  328.  
  329. Procedure FindSymbol;
  330. Var
  331.   X  : Name;
  332.   T  : Token;
  333.  
  334. Begin
  335.   X := Copy(InString,Position,1);
  336.   T := H[Hash(X)];
  337.   If T = 0 then
  338.     Begin
  339.       Writeln(X,' ',T);
  340.       Errors('Unrecognized symbol in Expression')
  341.     End
  342.   Else if Leading then
  343.     If Kind(T) = RightParen then
  344.       Errors('Illegal place for closing parenthesis')
  345.     Else if Kind(T) = BinaryOp then
  346.       If X = '+' then begin end
  347.       Else if X = '-' then
  348.       Begin
  349.         X := '\';
  350.         T := H[Hash(X)];
  351.         PutToken(T);
  352.       End
  353.       Else
  354.         Errors('Binary Operator in Illegal Position')
  355.     Else
  356.       PutToken(T)
  357.   Else
  358.     If (Kind(T) = RightParen) or (Kind(T) = BinaryOp) then
  359.       PutToken(T)
  360.     Else
  361.       Errors('Binary operator or ) expected');
  362.   If Kind(T) = LeftParen then
  363.     ParenCount := ParenCount + 1
  364.   Else if Kind(T) = RightParen then
  365.     Begin
  366.       ParenCount := ParenCount - 1;
  367.       If Parencount < 0 then Errors('More right than left parentheses')
  368.     End;
  369.     Position := Position + 1
  370. End;
  371.  
  372. Begin
  373.   TokenCount := LastOperand;
  374.   Writeln(' Type in the Expression to evaluate on the following line: ');
  375.   Write(' Y = ');Readln(Instring);
  376.   Instring   := Instring + ' ';
  377.   ExprLength := 0;  NParameter := 0; ParenCount := 0;
  378.   Position   := 1;
  379.   Lower      := ['a'..'z'];
  380.   Alphabet   := Lower + ['A'..'Z'];
  381.   Digit      := ['0'..'9'];
  382.   While Position <= Length(Instring) do
  383.     If Instring[Position] = ' ' then
  384.       Position := Position + 1
  385.     Else if instring[Position] in alphabet then
  386.       FindWord
  387.     Else if instring[Position] in Digit + ['.'] then
  388.       FindNumber
  389.     Else
  390.       FindSymbol;
  391.   If ParenCount <> 0 then
  392.     Errors('Numbers of Left and Right Parentheses are not Equal');
  393.   If Leading then
  394.     Errors('Input Expression is Incomplete.');
  395.   PutToken(1)
  396. End;
  397.  
  398. Procedure Translate;
  399. Const
  400.   MaxStack  = 100;
  401.  
  402. Var
  403.   Stack     : Array[1..MaxStack] of Token;
  404.   Nstack    : 0..MaxStack;
  405.   T,X       : Token;
  406.   EndRight  : Boolean;
  407.   InFixCount,PostFixCount    : 0..100;
  408.  
  409. Procedure Push(X : Token);
  410. Begin
  411.   Nstack := Nstack + 1;
  412.   Stack[Nstack] := X;
  413. End;
  414.  
  415. Procedure Pop(Var X : Token);
  416. Begin
  417.   X := Stack[Nstack];
  418.   Nstack := Nstack - 1;
  419. End;
  420.  
  421. Procedure GetToken(Var X: Token);
  422. Begin
  423.   X := InFix[InFixCount];
  424.   InFixCount := Succ(InFixCount);
  425. End;
  426.  
  427. Procedure PutToken(X: Token);
  428. Begin
  429.   PostFix[PostFixCount] := X;
  430.   PostFixCount := Succ(PostFixCount);
  431. End;
  432.  
  433. Function Priority(T : Token): PriorRange;
  434. Begin
  435.   Priority := Lexicon[T].Pri;
  436. End;
  437.  
  438. Begin
  439.   Nstack := 0;
  440.   InFixCount := 1;  PostFixCount := 1;
  441.   Repeat
  442.     GetToken(T);
  443.     Case Kind(T) of
  444.       Operand    : PutToken(T);
  445.       LeftParen  : Push(T);
  446.       RightParen : Begin
  447.                      Pop(T);
  448.                      While Kind(T) <> LeftParen do
  449.                      Begin
  450.                        PutToken(T);
  451.                        Pop(T)
  452.                      End
  453.                    End;
  454.       UnaryOp,
  455.       BinaryOp   : Begin
  456.                      Repeat
  457.                        If Nstack = 0 then
  458.                          EndRight := True
  459.                        Else If Kind(Stack[Nstack]) = LeftParen then
  460.                          EndRight := True
  461.                        Else If Priority(Stack[Nstack]) < Priority(T) then
  462.                          EndRight := True
  463.                        Else Begin
  464.                          EndRight := False;
  465.                          Pop(X);
  466.                          PutToken(X);
  467.                        End
  468.                      Until EndRight;
  469.                      Push(T);
  470.                    End;
  471.       EndExpression :
  472.                   While Nstack > 0 do
  473.                     Begin
  474.                       Pop(X);
  475.                       PutToken(X);
  476.                     End;
  477.     End;
  478.   Until Kind(T) = EndExpression;
  479.   PutToken(T);
  480. End;
  481.  
  482. Begin
  483.   MakeHashTable;
  484.   ReadExpression;
  485.   Translate
  486. End;
  487.  
  488. Procedure ReadParameters;
  489. Var
  490.   I,J   : Param;
  491.  
  492. Begin
  493.   If Nparameter > 0 then
  494.     Begin
  495.       ClrScr;
  496.       Writeln('The following parameters are present in your equation.');
  497.       For I := 1 to Nparameter do
  498.         With Lexicon[Parameter[I]] do
  499.         Begin
  500.           Writeln(I,':  ',NM:Namelength);
  501.         End;
  502.       Write(^J' How many of these parameters are variables? ');
  503.       Readln(Nvars);
  504.       m := nparameter - nvars;
  505.       n := m + 1;
  506.       Writeln(^J' Enter the parameter number for each variable : '^J);
  507.       For I := 1 to Nvars do
  508.         Begin
  509.           Write(' Variable ',I,': ');
  510.           Readln(J);
  511.           Lexicon[Parameter[J]].K := Variable;
  512.         End;
  513.       ClrScr;
  514.       J := 0;
  515.       For I := 1 to Nparameter do
  516.         With Lexicon[Parameter[I]] do
  517.           Begin
  518.             If  K = Variable then
  519.               Begin
  520.                 J := J + 1;
  521.                 Writeln(NM,'  corresponds to which column of');
  522.                 Write(' data in your data set? ');
  523.                 Readln(Vars[J]);
  524.               End;
  525.           End;
  526.       ClrScr;
  527.       Writeln('Enter initial guesses for the following coefficients ');
  528.       J := 0;
  529.       For I := 1 to Nparameter do
  530.         With Lexicon[Parameter[I]] do
  531.         Begin
  532.           If K = Operand then
  533.             Begin
  534.               J := J + 1;
  535.               Write(NM:Namelength,'?  ');
  536.               Readln(Simp[1,J]);
  537.               Step[J] := Simp[1,J]/5.0;
  538.             End;
  539.         End;
  540.       Write('Which column of your data is the dependant (Y) variable? ');
  541.       Readln(IY);
  542.     End;
  543. End;
  544.  
  545. Procedure EvaluatePostFix(Var Result: Real);
  546. Const
  547.   MaxStack   = 100;
  548. Var
  549.   Stack      : Array[1..MaxStack] of Real;
  550.   Nstack     : 0..MaxStack;
  551.   T          : Token;
  552.   A,B        : Real;
  553.   PostFixCount : 1..MaxExpression;
  554.  
  555. Function GetValue(T: Token): Real;
  556. Begin
  557.   If (Kind(T) <> Operand) and (Kind(T) <> Variable) then
  558.     Errors('Attempt to get Value for non-Operand')
  559.   Else
  560.     GetValue := Lexicon[T].Val
  561. End;
  562.  
  563. Procedure Push(V: Real);
  564. Begin
  565.   If Nstack >= MaxStack then Errors('Stack OverFlow')
  566.   Else Begin
  567.     Nstack := Nstack + 1;
  568.     Stack[Nstack] := V
  569.   End
  570. End;
  571.  
  572. Procedure Pop(Var V: Real);
  573. Begin
  574.   If Nstack <= 0 then Errors('Stack UnderFlow')
  575.   Else Begin
  576.     V := Stack[Nstack];
  577.     Nstack := Nstack - 1
  578.   End
  579. End;
  580.  
  581.  
  582. Function Exponent(X,Y: Real): Real;
  583. Const
  584.   Epsilon    = 0.000001;
  585.  
  586. Var
  587.   I: Integer;
  588.   P: Real;
  589.  
  590. Begin
  591.   If Abs(Y - Round(Y)) < Epsilon then
  592.   Begin
  593.     P := 1.0;
  594.     If Y >= 0.0 then
  595.       For I := 1 to Round(Y) do P := P*X
  596.     Else if X = 0.0 then Errors('Negative Power of 0.0')
  597.     Else
  598.       For I := -1 downto Round(Y) do
  599.         P := P/X;
  600.     Exponent := P;
  601.   End
  602.   Else if X > 0.0 then
  603.     Exponent := Exp(Y*Ln(X))
  604.   Else if Abs(X) < Epsilon then
  605.     Exponent := 0.0
  606.   Else
  607.     Errors('Attempt to take negative number to non-integer power')
  608. End;
  609.  
  610. Function DoBinary(T: Token; X,Y: Real): Real;
  611. Begin
  612.   If (T < FirstBinary) or (T > LastBinary) then
  613.     Errors('Binary operator code out of range')
  614.   Else Case T of
  615.     16: DoBinary := X + Y;
  616.     17: DoBinary := X - Y;
  617.     18: DoBinary := X * Y;
  618.     19: If Y = 0 then Errors('Division by 0') else DoBinary := X/Y;
  619.     20: If Round(Y) = 0 then Errors('Integer Division by 0') else
  620.         DoBinary := Round(X) div Round(Y);
  621.     21: If Round(Y) = 0 then Errors('Attempt to use 0 Modulus') else
  622.           DoBinary := Round(X) mod Round(Y);
  623.     22: DoBinary := Exponent(X,Y);
  624.   End;
  625. End;
  626.  
  627. Function DoUnary(T: Token; X: Real): Real;
  628. Begin
  629.   If (T < FirstUnary) or (T > LastUnary) then
  630.     Errors('Unary Operator code out of Range')
  631.   Else Case T of
  632.     4:  DoUnary := -1.0*X;
  633.     5:  DoUnary := Abs(X);
  634.     6:  DoUnary := Sqr(X);
  635.     7:  DoUnary := Sqrt(X);
  636.     8:  DoUnary := Exp(X);
  637.     9:  DoUnary := Ln(X);
  638.     10: DoUnary := Ln(X)/2.302585093;
  639.     11: DoUnary := Sin(X);
  640.     12: DoUnary := Cos(X);
  641.     13: DoUnary := ArcTan(X);
  642.     14: DoUnary := Round(X);
  643.     15: DoUnary := Trunc(X);
  644.   End;
  645. End;
  646.  
  647. Procedure GetToken(Var T: Token);
  648. Begin
  649.   T := PostFix[PostFixCount];
  650.   PostFixCount := Succ(PostFixCount);
  651. End;
  652.  
  653.  
  654. Begin
  655.   PostFixCount := 1;
  656.   Nstack := 0;
  657.   Repeat
  658.     GetToken(T);
  659.     Case Kind(T) of
  660.       Operand,Variable:
  661.                 Begin
  662.                   Push(GetValue(T));
  663.                 End;
  664.       UnaryOp :
  665.                 Begin
  666.                   Pop(A);
  667.                   Push(DoUnary(T,A))
  668.                 End;
  669.      BinaryOp :
  670.                 Begin
  671.                   Pop(B);
  672.                   Pop(A);
  673.                   Push(DoBinary(T,A,B))
  674.                 End;
  675.      EndExpression :
  676.                 If Nstack = 1 then
  677.                    Pop(Result)
  678.                  Else
  679.                    Errors('Stack Problem');
  680.     End;
  681.   Until Kind(T) = EndExpression;
  682. End;
  683.  
  684. Function f (II: Integer ; X: vector) : real;
  685. Var
  686.   I,J,L      : Index;
  687. begin
  688.   J := 0;
  689.   L := 0;
  690.     For I := 1 to Nparameter do
  691.       With Lexicon[Parameter[I]] do
  692.         Begin
  693.           If K = Variable then
  694.             Begin
  695.               J := J + 1;
  696.               Val := GetX(II,Vars[J]);
  697.             End
  698.           Else
  699.             Begin
  700.               L := L + 1;
  701.               Val := X[L];
  702.             End;
  703.         End;
  704.     EvaluatePostfix(Z);
  705.     F := Z;
  706.   end;
  707.  
  708.  
  709. Procedure Sum_of_residuals(var X : vector);
  710. Var
  711.   I   : Integer;
  712. Begin
  713.   x[n] := 0.0;
  714.   For I := 1 to Nobs do
  715.     Begin
  716.       x[n] := x[n] + sqr(f(I,X) - GetX(I,IY));
  717.     End;
  718. End;
  719.  
  720. Procedure enter;
  721.   Begin
  722.     Write(IO,' SIMPLEX optimization curve fitting ');
  723.     Writeln(IO,^J^J'Evaluating the Expression: ');
  724.     Writeln(IO,^J' ',InString);
  725.     Writeln(IO,^J' max number of iterations = ',maxiter:5);
  726.     Write(IO,' start coord.: ');
  727.     For I := 1 to M do
  728.       Begin
  729.         If (I mod LW) = 0 then writeln(IO);
  730.         Write(IO,Simp[1,I]);
  731.       End;
  732.     Writeln(IO);
  733.     Write(IO,' Start Steps: ');
  734.     For I := 1 to M do
  735.       Begin
  736.         If (I mod LW) = 0 then writeln(IO);
  737.         Write(IO,Step[I]);
  738.       End;
  739.     Writeln(IO);
  740.     Write(IO,' Maximum Errors: ');
  741.     For I := 1 to N do
  742.       Begin
  743.         maxerr[I] := 1.0E-04;
  744.         If (I mod LW) = 0 then writeln(IO);
  745.         Write(IO,maxerr[I])
  746.       End;
  747.     Writeln(IO);
  748.     Nobs := Nobs;
  749.   End;
  750. Procedure Report;
  751. Var
  752.   Y, DY, Sigma     : real;
  753. Begin
  754.   GotoXY(1,24);Writeln;
  755.   Writeln(IO,' Program exited after ',niter:5,' iteration ');
  756.   Writeln(IO,' The final SIMPLEX is');
  757.   For J := 1 to N do
  758.     Begin
  759.       For I := 1 to N do
  760.         Begin
  761.           If (I mod LW) = 0 then Writeln(IO);
  762.           Write(IO,Simp[j,i]:10,'  ')
  763.         End;
  764.       Writeln(IO);
  765.     End;
  766.   Writeln(IO,' The mean is');
  767.   For I := 1 to N do
  768.     Begin
  769.       If (I mod LW) = 0 then Writeln;
  770.       Write(IO,Mean[I]);
  771.     End;
  772.   Writeln(IO);
  773.   Writeln(IO,' The estimated fractional error is');
  774.   For I := 1 to N do
  775.     Begin
  776.       If (I mod LW) = 0 then Writeln;
  777.       Write(IO,error[I]);
  778.     End;
  779.   Writeln(IO);
  780.   Sigma := 0.0;
  781.   For I := 1 to Nobs do
  782.     Begin
  783.       Y := f(I,mean);
  784.       dY := GetX(I,IY) - Y;
  785.       PutX(Y,I,FC);
  786.       PutX(dY,I,RC);
  787.       Sigma := Sigma + Sqr(dY);
  788.     End;
  789.   Sigma := Sqrt(Sigma / Nobs);
  790.   Writeln(IO,' The standard deviation is ',Sigma);
  791.   Sigma := Sigma / Sqrt(Nobs - M);
  792.   Writeln(IO,' The estimated error of the function is', Sigma);
  793. End;
  794.  
  795. Procedure First;
  796.   Begin
  797.     Writeln(' Starting Simplex');
  798.     For J := 1 to N do
  799.       Begin
  800.         Write(' Simp[',J:1,']');
  801.         For I := 1 to N do
  802.           Begin
  803.             If (I mod LW) = 0 then Writeln;
  804.             Write(Simp[J,I]);
  805.           End;
  806.         Writeln;
  807.       End;
  808.       Writeln;
  809.   GotoXY(50,1);
  810.   TextBackground(15); TextColor(0);
  811.   Write('   Iteration No.              ');
  812.   TextBackground(0); TextColor(0);
  813. End;
  814. Procedure New_vertex;
  815.   Begin
  816.     GotoXY(65,1);Write(niter:4);
  817.     For I := 1 to N do
  818.       Begin
  819.         Simp[H[N],I] := Next[I];
  820.       End;
  821.     Writeln;
  822.   End;
  823. Procedure Order;
  824. Var
  825.   I, J            : Index;
  826.  
  827.   Begin
  828.     For J := 1 to N do
  829.       Begin
  830.         For I := 1 to N do
  831.           Begin
  832.             If Simp[I,J] < Simp[L[J],J] then L[J] := I;
  833.             If Simp[I,J] > Simp[H[J],J] then H[J] := I;
  834.           End;
  835.       End;
  836.   End;
  837. {****************************************************************************}
  838. {Start of Main                                                               }
  839. Begin
  840.   Root2 := Sqrt(2.00);
  841.   ClrScr;
  842.   DefineTokens;
  843.   StartExpression;
  844.   ReadParameters;
  845.   Enter;
  846.   Sum_of_residuals(Simp[1]);
  847.   For I := 1 to M do
  848.     Begin
  849.       P[I] := Step[I]*(Sqrt(N) + M - 1)/(M * Root2);
  850.       Q[I] := Step[I]*(Sqrt(N) -1)/(M * Root2);
  851.     End;
  852.   For I := 2 to N do
  853.     Begin
  854.       For J := 1 to M do Simp[I,J] := Simp[1,J] + Q[J];
  855.       Simp[I,I-1] := Simp[1,I-1] + P[I-1];
  856.       Sum_of_residuals(Simp[I]);
  857.     End;
  858.   For I := 1 to N do
  859.     Begin;
  860.       L[I] := 1; H[I] := 1;
  861.     End;
  862.   Order;
  863.   First;
  864.   Niter := 0;
  865.   Repeat;
  866.   Done := True;
  867.   Niter := Succ(Niter);
  868.   For I := 1 to N do Center[I] := 0.0;
  869.   For I := 1 to N do
  870.      If I <> H[N] then For J := 1 to M do Center[J] := Center[J] + Simp[I,J];
  871.   For I := 1 to N do
  872.     Begin
  873.       Center[I] := Center[I]/ M;
  874.       Next[I] := (1.0 + Alfa)* Center[I] - Alfa*Simp[H[N],I]
  875.     End;
  876.   Sum_of_residuals(next);
  877.   If Next[N] <= Simp[L[N],N] then
  878.     Begin
  879.       New_vertex;
  880.       For I := 1 to M do
  881.          Next[I] := Gamma*Simp[H[N],I] + (1.0 - Gamma)*Center[I];
  882.       Sum_of_Residuals(next);
  883.       If Next[N] <= Simp[L[N],N] then New_Vertex;
  884.     End
  885.   Else
  886.     Begin
  887.       If Next[N] <= Simp[H[N],N] then
  888.         New_vertex
  889.      Else
  890.        Begin
  891.          For I := 1 to M do
  892.            Next[I] := Beta*Simp[H[N],I] + (1.0 - Beta)*Center[I];
  893.          Sum_of_residuals(next);
  894.          If Next[N] <= Simp[H[N],N] then
  895.            New_vertex
  896.          Else
  897.            Begin
  898.              For I := 1 to N do
  899.                Begin
  900.                  For J := 1 to M do
  901.                    Simp[I,J] := (Simp[I,J] + Simp[L[N],J])*Beta;
  902.                  Sum_of_residuals(Simp[I]);
  903.                End
  904.            End
  905.        End
  906.     End;
  907.     Order;
  908.     For J := 1 to N do
  909.       Begin
  910.         Error[J] := (Simp[H[J],J] - Simp[L[J],J])/Simp[H[J],J];
  911.         If done then
  912.           If error[J] > Maxerr[J] then  Done := false;
  913.       End;
  914.     Until (done or (Niter = Maxiter));
  915.     For I := 1 to N do
  916.       Begin
  917.         Mean[I] := 0.0;
  918.         For J := 1 to N do Mean[I] := Mean[I] + Simp[J,I];
  919.         Mean[I] := Mean[I]/N;
  920.       End;
  921.     Report;
  922.   Pause;
  923. End;
  924.