home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l042 / 2.ddi / CHAP9.ARC / LEAST2.INC < prev    next >
Encoding:
Text File  |  1987-12-30  |  26.0 KB  |  557 lines

  1. {----------------------------------------------------------------------------}
  2. {-                                                                          -}
  3. {-     Turbo Pascal Numerical Methods Toolbox                               -}
  4. {-     Copyright (c) 1986, 87 by Borland International, Inc.                -}
  5. {-                                                                          -}
  6. {----------------------------------------------------------------------------}
  7.  
  8. procedure LeastSquares{(NumPoints        : integer;
  9.                    var XData             : TNColumnVector;
  10.                    var YData             : TNColumnVector;
  11.                        NumTerms          : integer;
  12.                    var Solution          : TNRowVector;
  13.                    var YFit              : TNColumnVector;
  14.                    var Residuals         : TNColumnVector;
  15.                    var StandardDeviation : Float;
  16.                    var Variance          : Float;
  17.                    var Error             : byte;
  18.                        Fit               : FitType)};
  19.  
  20. var
  21.   WData : TNColumnVector;          { Transformed X-values  }
  22.   ZData : TNColumnVector;          { Transformed Y-values  }
  23.   Basis : TNmatrix;                { Matrix of basis functions  }
  24.  
  25.   Multiplier : Float;              { Multiplier and Constant are used in }
  26.   Constant : Float;                { some modules to pass information    }
  27.                                    { from Transform to InverseTransform  }
  28.                                    { or TransformSolution.  These must   }
  29.                                    { therefore have dummy parameters     }
  30.                                    { when Multiplier and Constant are    }
  31.                                    { not used.                           }
  32.  
  33. procedure InitializeAndFormBasisVectors(NumPoints  : integer;
  34.                                     var XData      : TNColumnVector;
  35.                                     var YData      : TNColumnVector;
  36.                                     var Multiplier : Float;
  37.                                     var Constant   : Float;
  38.                                     var WData      : TNColumnVector;
  39.                                     var ZData      : TNColumnVector;
  40.                                     var NumTerms   : integer;
  41.                                     var Solution   : TNRowVector;
  42.                                     var Basis      : TNmatrix;
  43.                                     var Error      : byte);
  44.  
  45. {-------------------------------------------------------}
  46. {- Input: NumPoints, XData, NumTerms                   -}
  47. {- Output: Solution, Error                             -}
  48. {-                                                     -}
  49. {- This procedure initializes Solution and Error       -}
  50. {- to zero.  It also checks the data for errors.       -}
  51. {-------------------------------------------------------}
  52. begin
  53.   Error := 0;
  54.   if NumPoints < 2 then
  55.     Error := 1;   { Less than 2 data points  }
  56.   if NumTerms < 1 then
  57.     Error := 2;   { Less than 1 coefficient in the fit  }
  58.   if NumTerms > NumPoints then
  59.     Error := 3;   { Number of data points less than        }
  60.                   { number of terms in Least Squares fit!  }
  61.   FillChar(Solution, SizeOf(Solution), 0);
  62.   if Error = 0 then
  63.   begin
  64.     { The next two procedures are particular to each        }
  65.     { basis.  Consequently, they are included in each       }
  66.     { module, not in this include file.                     }
  67.  
  68.     { The Transform procedure transforms the input data to  }
  69.     { fit the particular basis.  This may mean taking the   }
  70.     { logarithm, or linearly tranforming the data to a      }
  71.     { particular interval. XData is transformed to WData    }
  72.     { and YData is transformed to ZData.  For some of the   }
  73.     { modules, Multiplier and Constant are used to pass     }
  74.     { information, for others they are dummy variables.     }
  75.     { See the code listing of the appropriate module for    }
  76.     { more information.                                     }
  77.     case Fit of
  78.       Poly    : PolyTransform(NumPoints, XData, YData, Multiplier,
  79.                               Constant, WData, ZData, Error);
  80.       Fourier : FourierTransform(NumPoints, XData, YData, Multiplier,
  81.                                  Constant, WData, ZData, Error);
  82.       Power   : PowerTransform(NumPoints, XData, YData, Multiplier,
  83.                                Constant, WData, ZData, Error);
  84.       Expo    : ExpoTransform(NumPoints, XData, YData, Multiplier,
  85.                               Constant, WData, ZData, Error);
  86.       Log     : LogTransform(NumPoints, XData, YData, Multiplier,
  87.                              Constant, WData, ZData, Error);
  88.       User    : UserTransform(NumPoints, XData, YData, Multiplier,
  89.                               Constant, WData, ZData, Error);
  90.     end;
  91.  
  92.     if Error = 0 then
  93.  
  94.       { The CreateBasis procedure creates the matrix of       }
  95.       { basis vectors, Basis.  The elements of Basis are:     }
  96.       { Basis[i, j] = Tj(w[i]) where Tj is the jth basis      }
  97.       { and w[i] is the ith data element of WData.            }
  98.       case Fit of
  99.         Poly    : PolyCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  100.         Fourier : FourierCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  101.         Power   : PowerCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  102.         Expo    : ExpoCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  103.         Log     : LogCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  104.         User    : UserCreateBasisFunctions(NumPoints, NumTerms, WData, Basis);
  105.       end;
  106.   end;
  107. end; { procedure InitializeAndFormBasisVectors }
  108.  
  109. procedure CreateAndSolveEquations(NumPoints : integer;
  110.                                   NumTerms  : integer;
  111.                               var Basis     : TNmatrix;
  112.                               var ZData     : TNColumnVector;
  113.                               var Solution  : TNRowVector;
  114.                               var Error     : byte);
  115.  
  116.  
  117. var
  118.   Coefficients : TNSquareMatrix;
  119.   Constants : TNRowVector;
  120.  
  121. {------------------------------------------------------------}
  122. {- Input: NumPoints, NumTerms, Basis, ZData                 -}
  123. {- Output: Solution, Error                                  -}
  124. {- This procedure computes and solves the normal equations. -}
  125. {- The normal equations are represented in matrix notation  -}
  126. {- as      Coefficients - Solution = Constants              -}
  127. {- This matrix equation is solved by Gaussian Elimination   -}
  128. {- with partial pivoting (TNToolbox routine: PARTPIVT.INC). -}
  129. {- If no solution exists, Error 3 is returned.              -}
  130. {------------------------------------------------------------}
  131.  
  132. procedure ComputeNormalEquations(NumPoints, NumTerms : integer;
  133.                              var Basis               : TNmatrix;
  134.                              var YData               : TNColumnVector;
  135.                              var Coefficients        : TNSquareMatrix;
  136.                              var Constants           : TNRowVector);
  137.  
  138. {---------------------------------------------------------}
  139. {- Input: NumPoints, NumTerms, Basis, YData              -}
  140. {- Output: Coefficients, Constants                       -}
  141. {-                                                       -}
  142. {- This procedure calculates the normal equations.  The  -}
  143. {- normal equations are of the form Ax=b, where A is the -}
  144. {- Coefficients matrix, b is the Constants vector and X  -}
  145. {- is the least squares solution to our problem in the   -}
  146. {- given basis.                                          -}
  147. {- The normal equations are derived from the basis       -}
  148. {- functions and the condition of least squares.  The    -}
  149. {- algorithm to create them is:                          -}
  150. {-      Coefficients[i, j] = Sum from k=1 to NumPoints   -}
  151. {-                            of Basis[k, i]-Basis[k, j] -}
  152. {-                                                       -}
  153. {-     Constants[i] = Sum from k=1 to NumPoints          -}
  154. {-                     YData[k] - Basis[k, i]            -}
  155. {---------------------------------------------------------}
  156.  
  157. var
  158.   Row, Column, Index : integer;
  159.   Sum : Float;
  160.  
  161. begin
  162.   for Column := 1 to NumTerms do
  163.   begin
  164.     Sum := 0;
  165.     for Index := 1 to NumPoints do
  166.     Sum := Sum + YData[Index] * Basis[Index, Column];
  167.     Constants[Column] := Sum;
  168.     for Row := Column to NumTerms do
  169.     begin
  170.       Sum := 0;
  171.       for Index := 1 to NumPoints do
  172.         Sum := Sum + Basis[Index, Row] * Basis[Index, Column];
  173.       Coefficients[Row, Column] := Sum;
  174.       Coefficients[Column, Row] := Sum;
  175.     end;
  176.   end;
  177. end; { procedure ComputeNormalEquations }
  178.  
  179. {---------------------------------------------------------------------------}
  180.  
  181. procedure Partial_Pivoting(Dimen        : integer;
  182.                            Coefficients : TNSquareMatrix;
  183.                            Constants    : TNRowVector;
  184.                        var Solution     : TNRowVector;
  185.                        var Error        : byte);
  186.  
  187. {--------------------------------------------------------------------------}
  188. {-                                                                        -}
  189. {-              Input: Dimen, Coefficients, Constants                     -}
  190. {-             Output: Solution, Error                                    -}
  191. {-                                                                        -}
  192. {-           Purpose : calculate the solution of a linear set of          -}
  193. {-                     equations using Gaussian elimination, maximal      -}
  194. {-                     pivoting and backwards substitution.               -}
  195. {-                                                                        -}
  196. {-  User-defined Types : TNRowVector = array[1..TNArraySize] of real;     -}
  197. {-                 TNSquareMatrix = array[1..TNArraySize] of TNRowVector  -}
  198. {-                                                                        -}
  199. {-  Global Variables : Dimen        : integer;     Dimension of the       -}
  200. {-                                                 square matrix          -}
  201. {-                     Coefficients : TNSquareMatrix; Square matrix       -}
  202. {-                     Constants    : TNRowVector; Constants of           -}
  203. {-                                                 each equation          -}
  204. {-                     Solution     : TNRowVector; Unique solution to     -}
  205. {-                                                 the set of equations   -}
  206. {-                     Error        : integer;     Flags if something     -}
  207. {-                                                 goes wrong.            -}
  208. {-                                                                        -}
  209. {-            Errors : 0: No errors;                                      -}
  210. {-                     1: Dimen < 2                                       -}
  211. {-                     2: no solution exists                              -}
  212. {-                                                                        -}
  213. {--------------------------------------------------------------------------}
  214.  
  215. procedure Initial(Dimen        : integer;
  216.               var Coefficients : TNSquareMatrix;
  217.               var Constants    : TNRowVector;
  218.               var Solution     : TNRowVector;
  219.               var Error        : byte);
  220.  
  221. {----------------------------------------------------------}
  222. {- Input: Dimen, Coefficients, Constants                  -}
  223. {- Output: Solution, Error                                -}
  224. {-                                                        -}
  225. {- This procedure test for errors in the value of Dimen.  -}
  226. {- This procedure also finds the solution for the         -}
  227. {- trivial case Dimen = 1.                                -}
  228. {----------------------------------------------------------}
  229.  
  230. begin
  231.   Error := 0;
  232.   if Dimen < 1 then
  233.     Error := 1
  234.   else
  235.     if Dimen = 1 then
  236.       if ABS(Coefficients[1, 1]) < TNNearlyZero then
  237.         Error := 2
  238.       else
  239.         Solution[1] := Constants[1] / Coefficients[1, 1];
  240. end; { procedure Initial }
  241.  
  242. procedure EROswitch(var Row1 : TNRowVector;
  243.                     var Row2 : TNRowVector);
  244.  
  245. {-------------------------------------------------}
  246. {- Input: Row1, Row2                             -}
  247. {- Output: Row1, Row2                            -}
  248. {-                                               -}
  249. {- Elementary row operation - switching two rows -}
  250. {-------------------------------------------------}
  251.  
  252. var
  253.   DummyRow : TNRowVector;
  254.  
  255. begin
  256.   DummyRow := Row1;
  257.   Row1 := Row2;
  258.   Row2 := DummyRow;
  259. end; { procedure EROswitch }
  260.  
  261. procedure EROmultAdd(Multiplier   : Float;
  262.                      Dimen        : integer;
  263.                  var ReferenceRow : TNRowVector;
  264.                  var ChangingRow  : TNRowVector);
  265.  
  266. {-----------------------------------------------------------}
  267. {- Input: Multiplier, Dimen, ReferenceRow, ChangingRow     -}
  268. {- Output: ChangingRow                                     -}
  269. {-                                                         -}
  270. {- row operation - adding a multiple of one row to another -}
  271. {-----------------------------------------------------------}
  272.  
  273. var
  274.   Term : integer;
  275.  
  276. begin
  277.   for Term := 1 to Dimen do
  278.     ChangingRow[Term] := ChangingRow[Term] + Multiplier * ReferenceRow[Term];
  279. end; { procedure EROmult&Add }
  280.  
  281. procedure UpperTriangular(Dimen        : integer;
  282.                       var Coefficients : TNSquareMatrix;
  283.                       var Constants    : TNRowVector;
  284.                       var Error        : byte);
  285.  
  286. {-----------------------------------------------------------------}
  287. {- Input: Dimen, Coefficients, Constants                         -}
  288. {- Output: Coefficients, Constants, Error                        -}
  289. {-                                                               -}
  290. {- This procedure makes the coefficient matrix upper triangular. -}
  291. {- The operations which perform this are also performed on the   -}
  292. {- Constants vector.                                             -}
  293. {- If one of the main diagonal elements of the upper triangular  -}
  294. {- matrix is zero, then the Coefficients matrix is singular and  -}
  295. {- no solution exists (Error = 2 is returned).                   -}
  296. {-----------------------------------------------------------------}
  297.  
  298. var
  299.   Multiplier : Float;
  300.   Row, ReferenceRow : integer;
  301.  
  302. procedure Pivot(Dimen        : integer;
  303.                 ReferenceRow : integer;
  304.             var Coefficients : TNSquareMatrix;
  305.             var Constants    : TNRowVector;
  306.             var Error        : byte);
  307.  
  308. {----------------------------------------------------------------}
  309. {- Input: Dimen, ReferenceRow, Coefficients                     -}
  310. {- Output: Coefficients, Constants, Error                       -}
  311. {-                                                              -}
  312. {- This procedure searches the ReferenceRow column of the       -}
  313. {- Coefficients matrix for the largest non-zero element below   -}
  314. {- the diagonal. If it finds one, then the procedure switches   -}
  315. {- rows so that the largest non-zero element is on the          -}
  316. {- diagonal. It also switches the corresponding elements in     -}
  317. {- the Constants vector. If it doesn't find a non-zero element, -}
  318. {- the matrix is singular and no solution exists                -}
  319. {- (Error = 2 is returned).                                     -}
  320. {----------------------------------------------------------------}
  321.  
  322. var
  323.   PivotRow, Row : integer;
  324.   Dummy : Float;
  325.  
  326. begin
  327.   { First, find the row with the largest element  }
  328.   PivotRow := ReferenceRow;
  329.   for Row := ReferenceRow + 1 to Dimen do
  330.     if ABS(Coefficients[Row, ReferenceRow]) >
  331.        ABS(Coefficients[PivotRow, ReferenceRow]) then
  332.       PivotRow := Row;
  333.   if PivotRow <> ReferenceRow then
  334.     { Second, switch these two rows  }
  335.     begin
  336.       EROswitch(Coefficients[PivotRow], Coefficients[ReferenceRow]);
  337.       Dummy := Constants[PivotRow];
  338.       Constants[PivotRow] := Constants[ReferenceRow];
  339.       Constants[ReferenceRow] := Dummy;
  340.     end
  341.   else
  342.     { If the diagonal element is zero, no solution exists  }
  343.     if ABS(Coefficients[ReferenceRow, ReferenceRow]) < TNNearlyZero then
  344.       Error := 2;     { No solution  }
  345. end; { procedure Pivot }
  346.  
  347. begin  { procedure UpperTriangular }
  348.   { Make Coefficients matrix upper triangular  }
  349.   ReferenceRow := 0;
  350.   while (Error = 0) and (ReferenceRow < Dimen - 1) do
  351.   begin
  352.     ReferenceRow := Succ(ReferenceRow);
  353.     { Find row with largest element in this column  }
  354.     { and switch this row with the ReferenceRow     }
  355.     Pivot(Dimen, ReferenceRow, Coefficients, Constants, Error);
  356.  
  357.     if Error = 0 then
  358.       for Row := ReferenceRow + 1 to Dimen do
  359.         { Make the ReferenceRow element of these rows zero  }
  360.         if ABS(Coefficients[Row, ReferenceRow]) > TNNearlyZero then
  361.         begin
  362.           Multiplier := -Coefficients[Row, ReferenceRow] /
  363.                          Coefficients[ReferenceRow,ReferenceRow];
  364.           EROmultAdd(Multiplier, Dimen,
  365.                      Coefficients[ReferenceRow], Coefficients[Row]);
  366.           Constants[Row] := Constants[Row] +
  367.                             Multiplier * Constants[ReferenceRow];
  368.         end;
  369.   end; { while }
  370.   if ABS(Coefficients[Dimen, Dimen]) < TNNearlyZero then
  371.     Error := 2;    { No solution  }
  372. end; { procedure UpperTriangular }
  373.  
  374. procedure BackwardsSub(Dimen        : integer;
  375.                    var Coefficients : TNSquareMatrix;
  376.                    var Constants    : TNRowVector;
  377.                    var Solution     : TNRowVector);
  378.  
  379. {----------------------------------------------------------------}
  380. {- Input: Dimen, Coefficients, Constants                        -}
  381. {- Output: Solution                                             -}
  382. {-                                                              -}
  383. {- This procedure applies backwards substitution to the upper   -}
  384. {- triangular Coefficients matrix and Constants vector. The     -}
  385. {- resulting vector is the solution to the set of equations and -}
  386. {- is stored in the vector Solution.                            -}
  387. {----------------------------------------------------------------}
  388.  
  389. var
  390.   Term, Row : integer;
  391.   Sum : Float;
  392.  
  393. begin
  394.   Term := Dimen;
  395.   while Term >= 1 do
  396.   begin
  397.     Sum := 0;
  398.     for Row := Term + 1 to Dimen do
  399.       Sum := Sum + Coefficients[Term, Row] * Solution[Row];
  400.     Solution[Term] := (Constants[Term] - Sum) / Coefficients[Term, Term];
  401.     Term := Pred(Term);
  402.   end;
  403. end; { procedure BackwardsSub }
  404.  
  405. begin { procedure Partial_Pivoting }
  406.   Initial(Dimen, Coefficients, Constants, Solution, Error);
  407.   if Dimen > 1 then
  408.   begin
  409.     UpperTriangular(Dimen, Coefficients, Constants, Error);
  410.     if Error = 0 then
  411.       BackwardsSub(Dimen, Coefficients, Constants, Solution);
  412.   end;
  413. end; { procedure Partial_Pivoting }
  414.  
  415. {---------------------------------------------------------------------------}
  416.  
  417. begin { procedure CreateAndSolveEquations }
  418.  
  419.   { The following procedure computes Coefficients and    }
  420.   { Constants of the normal equations.  The exact        }
  421.   { solution to the square system of normal equations    }
  422.   { will be the least squares fit to the data.           }
  423.   ComputeNormalEquations(NumPoints, NumTerms, Basis, ZData,
  424.                          Coefficients, Constants);
  425.   Partial_Pivoting(NumTerms, Coefficients, Constants, Solution, Error);
  426.   if Error = 2 then { Returned from Partial_Pivoting  }
  427.     Error := 4; { No solution  }
  428. end; { procedure CreateAndSolveEquations }
  429.  
  430. procedure TransformSolutionAndFindResiduals(NumPoints         : integer;
  431.                                             NumTerms          : integer;
  432.                                         var YData             : TNColumnVector;
  433.                                         var Solution          : TNRowVector;
  434.                                             Multiplier        : Float;
  435.                                             Constant          : Float;
  436.                                         var Basis             : TNmatrix;
  437.                                         var YFit              : TNColumnVector;
  438.                                         var Residuals         : TNColumnVector;
  439.                                         var StandardDeviation : Float;
  440.                                         var Variance          : Float);
  441.  
  442. {-------------------------------------------------------------------}
  443. {- Input: NumPoints, NumTerms, YData, Solution, Multiplier,        -}
  444. {-        Constant, Basis                                          -}
  445. {- Output: Solution, YFit, Residuals, StandardDeviation            -}
  446. {-                                                                 -}
  447. {- This procedure computes the goodness of fit of the least        -}
  448. {- squares solution.  The residuals and standard deviation of the  -}
  449. {- fit are returned.  Also, this procedure transforms the solution -}
  450. {- according to the procedure TransformSolution in the include     -}
  451. {- module.  See the particular module for details on the           -}
  452. {- transformation.                                                 -}
  453. {-------------------------------------------------------------------}
  454.  
  455. procedure ComputeYFitAndResiduals(NumPoints         : integer;
  456.                                   NumTerms          : integer;
  457.                                   Multiplier        : Float;
  458.                                   Constant          : Float;
  459.                               var YData             : TNColumnVector;
  460.                               var Solution          : TNRowVector;
  461.                               var Basis             : TNmatrix;
  462.                               var YFit              : TNColumnVector;
  463.                               var Residuals         : TNColumnVector;
  464.                               var StandardDeviation : Float;
  465.                               var Variance          : Float);
  466.  
  467. {---------------------------------------------------------------}
  468. {- Input: NumPoints, NumTerms,                                 -}
  469. {- Multiplier, Constant, YData, Solution, Basis                -}
  470. {- Output: YFit, Residuals, StandardDeviation                  -}
  471. {-                                                             -}
  472. {- This procedure computes the value of the least squares      -}
  473. {- approximation at the data points, WData.  The difference    -}
  474. {- between the approximation and the actual values are also    -}
  475. {- computed and are returned in the variable Residuals.  The   -}
  476. {- standard deviation is calculated with the formula:          -}
  477. {-                                                             -}
  478. {-      StandardDeviation = SQRT(Variance)                     -}
  479. {-                                                             -}
  480. {-                                        2                    -}
  481. {-      Variance = SUM(YData[i] - YFit[i]) /                   -}
  482. {-                               (degrees of freedom)          -}
  483. {-                                                             -}
  484. {-      degrees of freedom = NumPoints - NumTerms - 2          -}
  485. {-                                                             -}
  486. {---------------------------------------------------------------}
  487.  
  488. var
  489.   Index, Term : integer;
  490.   Sum : Float;
  491.  
  492. begin
  493.   Sum := 0;
  494.   for Index := 1 to NumPoints do
  495.   begin
  496.     YFit[Index] := 0;
  497.     for Term := 1 to NumTerms do
  498.       YFit[Index] := YFit[Index] + Solution[Term]*Basis[Index, Term];
  499.  
  500.     { The next procedure undoes the transformation of    }
  501.     { the YFit values.  For example, if ZData=Ln(YData)  }
  502.     { then InverseTransform performs the function        }
  503.     { YFit[Index] := Exp(YFit[Index]) so that YFit may   }
  504.     { be compared to YData.                              }
  505.     case Fit of
  506.       Poly    : PolyInverseTransform(Multiplier, Constant, YFit[Index]);
  507.       Fourier : FourierInverseTransform(Multiplier, Constant, YFit[Index]);
  508.       Power   : PowerInverseTransform(Multiplier, Constant, YFit[Index]);
  509.       Expo    : ExpoInverseTransform(Multiplier, Constant, YFit[Index]);
  510.       Log     : LogInverseTransform(Multiplier, Constant, YFit[Index]);
  511.       User    : UserInverseTransform(Multiplier, Constant, YFit[Index]);
  512.     end;
  513.     Residuals[Index] := YFit[Index] - YData[Index];
  514.     Sum := Sum + Sqr(Residuals[Index]);
  515.   end;
  516.   Variance := Sum;
  517.   if NumPoints = NumTerms then
  518.     StandardDeviation := 0
  519.   else
  520.     StandardDeviation := Sqrt(Sum/(NumPoints - NumTerms));
  521. end; { procedure ComputeYFitAndResiduals }
  522.  
  523. begin  { procedure TransformSolutionAndFindResiduals }
  524.   ComputeYFitAndResiduals(NumPoints, NumTerms, Multiplier, Constant,
  525.                           YData, Solution, Basis, YFit,
  526.                           Residuals, StandardDeviation, Variance);
  527.   case Fit of
  528.     Poly    : PolyTransformSolution(NumTerms, Solution, Multiplier, Constant,
  529.               Solution);
  530.     Fourier : FourierTransformSolution(NumTerms, Solution, Multiplier, Constant,
  531.               Solution);
  532.     Power   : PowerTransformSolution(NumTerms, Solution, Multiplier, Constant,
  533.               Solution);
  534.     Expo    : ExpoTransformSolution(NumTerms, Solution, Multiplier, Constant,
  535.               Solution);
  536.     Log     : LogTransformSolution(NumTerms, Solution, Multiplier, Constant,
  537.               Solution);
  538.     User    : UserTransformSolution(NumTerms, Solution, Multiplier, Constant,
  539.               Solution);
  540.   end;
  541. end; { procedure TransformSolutionAndFindResiduals }
  542.  
  543. begin { procedure LeastSquares }
  544.   InitializeAndFormBasisVectors(NumPoints, XData, YData,
  545.                                 Multiplier, Constant, WData, ZData,
  546.                                 NumTerms, Solution, Basis, Error);
  547.   if Error = 0  then
  548.     CreateAndSolveEquations(NumPoints, NumTerms, Basis, ZData,
  549.                             Solution, Error);
  550.  
  551.   if Error = 0 then
  552.     TransformSolutionAndFindResiduals(NumPoints, NumTerms, YData, Solution,
  553.                                       Multiplier, Constant, Basis, YFit,
  554.                                       Residuals, StandardDeviation, Variance);
  555.  
  556. end; { procedure LeastSquares }
  557.