home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Applications / Calculators / NumberCrunch 1.41 / Number Crunch II Demo / Library Routines / Text Examples / Fitting Functions to Arrays < prev    next >
Encoding:
Text File  |  1992-09-03  |  17.9 KB  |  480 lines  |  [TEXT/NCII]

  1. ################
  2. # Fitting Functions to Arrays
  3. #
  4. #  program FitLine(xData,yData, A,B, r,ErrorEstimate)#Finds A,B for y=A x + b
  5. #  program FitPoly(xData,yData,Sigma, J,A,  Prob) #Find A to fit x,yData[1…N] with G(x)=A[1]+A[2]x+…+A[J] x^(J-1). 
  6. #   function Poly(A,x) # Returns A[1] + A[2] x + … + A[J] x^(J-1).
  7. #  program FitLegendre(xData,yData,Sigma, J,A,  Prob) #Find A[1…J] such that G(x) = A[j] • P_j(x) fits yData[1…N].
  8. #   function CalcLegendre(J, x)  # Returns P[l,1…size(x)] = P_l(x) for l=1…J. 
  9. #   function LegendreModel(A,x) # ReturnsG(x) = sum over i=1…J { A[i] P_i(x) }
  10. #  program FitUser(xData,yData,Sigma, J,A,  Prob, BasisUser) # Fits yData to a sum of user supplied basis functions.
  11. #  program SampleBasisUser(Jp1, zIO) # Sample BasisUser. See program FitUser.
  12. #  This text file explains and gives examples of
  13. #  some of the routines in the file All Library Routines, which
  14. #  should be Opened before trying any of these examples.
  15. #
  16. #################
  17.  
  18. #############
  19. # Here are the xCOD's :
  20.  
  21. xFIT_FUNCS
  22.   # xCOD xFIT_FUNCS(prog BasisFuncs(Jp1:num; zIO:array); n:num; x,y,dy:array; j:num; A,Avar, w1,w2,w3:array; chisq,err:num), fits y=sum over j A(j)*Fj(x) to x[1…n], y[1…n]±dy[1…n]. BasisFuncs calculates J=Jp1-1 functions zIO[1…j]=Fj(x) for single x=zIO[Jp1]. Work arrays: w1[1…n,1…j],w2[1…j,1…j],w3[1…j]. Output: A[1…j]=coeffs, Avar[1…j,1…j]=covariance o fA, ChiSquare of fit. Err: -1=> didn't converge; an external program.
  23.  
  24. xBASIS_POLY
  25.   # xCOD xBASIS_POLY(Jp1:num; zIO:array), calculates J=Jp1-1 polynomial basis functions for a single value of x. Input: x=zIO(jp1). Output: zIO(1…j)=x^j. Used with xFIT_FUNCS; an external program.
  26.  
  27. xBASIS_LEGENDRE
  28.   # xCOD xBASIS_LEGENDRE(Jp1:num; zIO:array), calculates J=Jp1-1 Legendre basis functions for a single value of x. Input: x=zIO(jP1). Output: zIO(1…j)=P_j(x). Legendre definition: P1(x)=1; P2(x)=x; (n+1) P[n+1](x)=(2n+1) x Pn(x) - n P[n-1](x). Used with xFIT_FUNCS; an external program.
  29.  
  30.  
  31. #############
  32. # All the routines in this file are based on xFIT_FUNCS, which finds the 
  33. # coefficients A[1…j] such that G(x)= sum over j of  { A[j] Fj(x) } best
  34. # fits xData[1…N], yData[1…N], sigma[1…n] = uncertainties in yData, 
  35. # where Fj(x) are basis functions defined by either another xCOD 
  36. # or an NCII user program. Examples of both are given below.
  37. #
  38. # Besides A[1…j],  the ChiSqaure (c2) "goodness"  of the fit is returned,
  39. # which is ChiSq = sum( yData - G(xData))^2, 
  40. # as well as a co-variance matrix Avar[1…j,1…j] describing 
  41. # the uncertainties in the fit.   The square root of the diagonal elements 
  42. # of this matrix are the standard deviations (sigmas) of the expected 
  43. # errors in the coefficients A. 
  44. #
  45. # Note that if we assume the model curve fits the data, then
  46. # an estimate of the uncertainties inherent in yData is
  47. #    SigmaGuess = sqrt( ChiSq/ size(yData) ).
  48. ###############
  49.  
  50.  
  51. #   Fit a line through some data points.
  52. #
  53.  program FitLine(xData,yData, A,B, r,ErrorEstimate)#Finds A,B for y=A x + b
  54. .   var N,J,jj,nn,Sigma,C,Cvar,w1,w2,w3,ChiSq, err
  55. . #  Inputs:    
  56. . #       xData[1…n], yData[1…n]
  57. . #  Outputs:
  58. . #       A = slope,  B = intercept of best fit line    y = A x + b
  59. . #       r = correlation coefficient, -1<=r<=1.  
  60. . #          (r  near zero implies that the data is not correlated, i.e. not linear.)
  61. . #       ErrorEstimate = approximate errors in yData assuming fit to line is OK.
  62. .   begin
  63. .     J = 2;                        # number of coeffients to fine
  64. .     jj=1…J;
  65. .     N = size(xData);         # number of data points.
  66. .     nn = 1…N;
  67. .     if size(yData)<>N then 
  68. .         Print(" ERROR: xData,yData not same size")
  69. .     else 
  70. .       begin
  71. .       C[jj] = 0;                   # space for coefficients
  72. .       Cvar[jj,jj]=0;            #   and co-variance array.
  73. .       w1[nn,jj] = 0;            # work space
  74. .       w2[jj,jj] = 0;
  75. .       w3[jj] = 0;
  76. .       ChiSq = 0; err=0;
  77. .       Sigma[nn] = 1;           # assume uniform y uncertainties
  78. .       xFIT_FUNCS(xBASIS_POLY, N,xData,yData,Sigma, J,C,Cvar, w1,w2,w3, ChiSq, err)
  79. .       if err<>0 then Print(" ERROR in xFIT_FUNCS = "+err)
  80. .       A = C(2);  B=C(1);     # return coefficients 
  81. .       r = -Cvar(1,2)/sqrt( Cvar(1,1)*Cvar(2,2) )   # and correlation coeff r.
  82. .       ErrorEstimate = sqrt(ChiSq/(N-J))
  83. .       end  # of else
  84. .   end
  85. .   
  86.  
  87.  
  88. # Fit a general polynomial of degree J-1 to xData, yData, Sigma.
  89. # This essentially just calls xFIT_FUNCS with xBASIS_POLY.
  90. # The covariance of the A polynomial coefficients isn't used in
  91. # this interface routine; modify it if you want this information.
  92. #
  93. # Prob = the probability that a fit to the data this poor could have
  94. # been caused by random chance alone, assuming that the errors
  95. # are distributed normally with the given Sigma.  A tiny value
  96. # of Prob means that this degree polynomial does not fit the data within
  97. # the given uncertainties.
  98. #
  99.  program FitPoly(xData,yData,Sigma, J,A,  Prob) #Find A to fit x,yData[1…N] with G(x)=A[1]+A[2]x+…+A[J] x^(J-1). 
  100. .   var N,nn,jj,Avar,w1,w2,w3,ChiSq, err
  101. . # Inputs: 
  102. . #     xData, yData, Sigma = yData errors, 
  103. . #     J = number of parameters A[j] to fit, 
  104. . #          ( with model G(x) = A[1] + A[2] x + a[3] x^2 + … + a[J] x^(J-1)  )
  105. . # Outputs:
  106. . #     A[1…J] = best fit coefficients,
  107. . #     Prob = probability that a fit this bad could be normal errors with
  108. . #                stnd. devs. Sigma.
  109. .   begin
  110. .     jj=1…J;
  111. .     N = size(xData);         # number of data points.
  112. .     nn = 1…N
  113. .     if size(Sigma)=1 then
  114. .       Sigma[nn]=Sigma     # make sure sigma is an array
  115. .     if size(Sigma)<>N then
  116. .         Print("ERROR: xData, Sigma not same size")
  117. .     else if size(yData)<>N then 
  118. .         Print(" ERROR: xData,yData not same size")
  119. .     else 
  120. .       begin
  121. .       A[jj] = 0;
  122. .       Avar[jj,jj]=0;            #   and co-variance array.
  123. .       w1[nn,jj] = 0;            # work space
  124. .       w2[jj,jj] = 0;
  125. .       w3[jj] = 0;
  126. .       ChiSq = 0; err=0;
  127. .       xFIT_FUNCS(xBASIS_POLY, N,xData,yData,Sigma, J,A,Avar, w1,w2,w3, ChiSq, err)
  128. .       if err<>0 then Print(" ERROR in xFIT_FUNCS = "+err)
  129. .       Prob = ChiSqProbability( ChiSq, J)   # see below.
  130. .       end  # of else
  131. .   end
  132. .   
  133.  
  134. # Evaluate the Polynomial given by the A[1…J] coefficients.
  135.   function Poly(A,x) # Returns A[1] + A[2] x + … + A[J] x^(J-1).
  136. .   var jj, J, ans
  137. . # Inputs: A[1…J] coeffs., 
  138. . #             x = number or array
  139. . # Output :      
  140. . #            Poly = A[1] + A[2] x + A[3] x^2 + … + A[J] x^(J-1)
  141. .   begin
  142. .     J = size(A)
  143. .     ans = A[J];
  144. .     for jj= 1 … J-1 do ans= A[J-jj] + x*ans
  145. .     Poly = ans
  146. .   end
  147.     
  148. #  ( IncompleteGamma and ChiSqProbability are in the Special Functions file. )
  149. #
  150.  
  151. # Fit a sum of J Legendre polynomials to xData, yData, Sigma.
  152. # This essentially just calls xFIT_FUNCS with xBASIS_LEGENDRE.
  153. # The covariance of the A polynomial coefficients isn't used in
  154. # this interface routine; modify it if you want this information.
  155. #
  156. # Prob = the probability that a fit to the data this poor could have
  157. # been caused by random chance alone, assuming that the errors
  158. # are distributed normally with the given Sigma.  A tiny value
  159. # of Prob means that this degree polynomial does not fit the data within
  160. # the given uncertainties.
  161. #
  162.  program FitLegendre(xData,yData,Sigma, J,A,  Prob) #Find A[1…J] such that G(x) = A[j] • P_j(x) fits yData[1…N].
  163. .   var N,nn,jj,Avar,w1,w2,w3,ChiSq, err
  164. .  #  Inputs:
  165. .  #     xData[1…N], yData[1…N]   data points,
  166. .  #     Sigma  (real or array) = yData errors, 
  167. .  #     J = number of parameters A[j] to fit, 
  168. .  #         ( with g(x) = A[1] P_1(x) + A[2] P_2(x) +  … + A[J] P_j(x)  )
  169. .  # Outputs:
  170. .  #     A[1…J] = best fit coefficients,
  171. .  #     Prob = probability of this fit matching data with given Sigma.
  172. .  # 
  173. .  # Note that here the Legendre polys. are P_j with j=1,2,3,…,
  174. .  #      NOT j=0,1,2,… as is the convention sometimes.
  175. .  #
  176. .   begin
  177. .     jj=1…J;
  178. .     N = size(xData);         # number of data points.
  179. .     nn = 1…N
  180. .     if size(Sigma)=1 then
  181. .       Sigma[nn]=Sigma     # make sure sigma is an array
  182. .     if size(Sigma)<>N then
  183. .         Print("ERROR: xData, Sigma not same size")
  184. .     else if size(yData)<>N then 
  185. .         Print(" ERROR: xData,yData not same size")
  186. .     else 
  187. .       begin
  188. .       Avar[jj,jj]=0;            #   and co-variance array.
  189. .       w1[nn,jj] = 0;            # work space
  190. .       w2[jj,jj] = 0;
  191. .       w3[jj] = 0;
  192. .       ChiSq = 0; err=0;
  193. .       A[jj] = 0;
  194. .       xFIT_FUNCS(xBASIS_LEGENDRE, N,xData,yData,Sigma, J,A,Avar, w1,w2,w3, ChiSq, err)
  195. .       if err<>0 then Print(" ERROR in xFIT_FUNCS = "+err)
  196. .       Prob = ChiSqProbability( ChiSq, J)   # see below.
  197. .       end  # of else
  198. .   end
  199. .   
  200.  
  201. # Find J Legendre polynomials, P[1…J, 1…size(x)].
  202. # This could also be done with xBASIS_LEGENDRE, but
  203. # that would mean looping over x, rather than j, which is probably smaller.
  204. #
  205.   function CalcLegendre(J, x)  # Returns P[l,1…size(x)] = P_l(x) for l=1…J. 
  206. .   var Pz, n
  207. .   #  Input:   x = array of points to calulate Legendre polynomials on.
  208. .   #             J = positive integer > 0 
  209. .   #  Output: CalcLegendre = P[1…J, 1…size(x)] with
  210. .   #              P[j,] = one of the polynomials = P_j(x)
  211. .   # NOTE that here the lowest possible J is 1, rather than 0 
  212. .   # as is sometimes done. Thus P_j is a (j-1)'th order polynomial in x.
  213. .   begin
  214. .     Pz[1…J, 1…size(x)] = 0  # reserve space
  215. .     Pz[1,] = 1;
  216. .     if J>1 then
  217. .     begin
  218. .       Pz[2,] = x
  219. .       for n= 2…(J-1) do Pz[n+1,] = 1/(n+1) { (2n+1)*x*Pz[n,] - n*Pz[n-1,] }
  220. .     end
  221. .     CalcLegendre = Pz
  222. .   end
  223. .   
  224.  
  225. # Evaluate the sum of the Legendre polynomials P_l(x) times the A[l] coefficients
  226. # on the vector x. This gives the "best fit" curve that FitLegendre calculates.
  227.   function LegendreModel(A,x) # ReturnsG(x) = sum over i=1…J { A[i] P_i(x) }
  228. .   var  P
  229. . #   Input:  A[j] coefficients
  230. . #              x = array
  231. . #  Output:
  232. . #             LegendreModel = G(x) = sum over i=1…J  A[i] P_i(x)
  233. .   begin
  234. .     P = CalcLegendre(size(A), x)
  235. .     LegendreModel = A • P   # dot product does sum j A[j]*P[j,]
  236. .   end
  237.  
  238.  
  239. # Fit a linear combination of user supplied functions
  240. # to xData, yData, just like the routines above. 
  241. #
  242. # See below or the last example for a sample of BasisUser.
  243. #
  244.  program FitUser(xData,yData,Sigma, J,A,  Prob, BasisUser) # Fits yData to a sum of user supplied basis functions.
  245. .   var N,nn,jj,Avar,w1,w2,w3,ChiSq, err
  246. . #  Input:  
  247. . #            BasisUser     =  program to calculate the basis, F_j(x),
  248. . #                                like SampleBasisUser or xBASI_POLY.
  249. . #            xData[1…N], yData[1…N] = data points 
  250. . #            Sigma (real or array) = uncertainties in yData
  251. . #            J = number of A[1…J] parameters in basis
  252. . #  Output:
  253. . #            A[1…J] best-fit parameters,  such that
  254. . #                  G(x) = sum over i=1…J { A[i] F_i(x) } fits yData.
  255. . #            Prob = probability that the poorness of the fit is due to chance.
  256. .   begin
  257. .     jj=1…J;
  258. .     N = size(xData);         # number of data points.
  259. .     nn = 1…N
  260. .     if size(Sigma)=1 then
  261. .       Sigma[nn]=Sigma     # make sure sigma is an array
  262. .     if size(Sigma)<>N then
  263. .         Print("ERROR: xData, Sigma not same size")
  264. .     else if size(yData)<>N then 
  265. .         Print(" ERROR: xData,yData not same size")
  266. .     else 
  267. .       begin
  268. .       Avar[jj,jj]=0;            #   and co-variance array.
  269. .       w1[nn,jj] = 0;            # work space
  270. .       w2[jj,jj] = 0;
  271. .       w3[jj] = 0;
  272. .       ChiSq = 0; err=0;
  273. .       A[jj] = 0;
  274. .       xFIT_FUNCS(BasisUser, N,xData,yData,Sigma, J,A,Avar, w1,w2,w3, ChiSq, err)
  275. .       if err<>0 then Print("ERROR in xFIT_FUNCS = "+err)
  276. .       Prob = ChiSqProbability( ChiSq, J)   # see below.
  277. .       end  # of else
  278. .   end
  279. .   
  280.  
  281. #
  282. # This SampleBasisUser is here only to show the format
  283. # of a user routine that FitUser needs.  
  284. #
  285.  program SampleBasisUser(Jp1, zIO) # Sample BasisUser. See program FitUser.
  286. .   var x, y, J
  287. .   #  Input:
  288. .   #          Jp1 = J+1 = size of zIO array
  289. .   #          zIO[Jp1] = x
  290. .   #  Output:
  291. .   #         zIO[1…J] = F_j(x)
  292. .   #   (This one a demo which does F_j(x) = x^(j-1), 
  293. .   #     exactly the same as xCOD xBASIS_POLY does, only much slower.)
  294. .   begin
  295. .     x = zIO(Jp1)
  296. .     J = Jp1 - 1
  297. .     zIO[1] = 1
  298. .     for jj=2…J do zIO[jj] = x*zIO[jj-1]
  299. .   end
  300. .     
  301.   
  302.  
  303.  
  304. #######
  305. # Examples:
  306. ######
  307.  
  308.  
  309. ##############
  310. # Fitting a line to some data points:
  311. #
  312. xData=[1,2,3,4]; 
  313. yData=[1.1, 1.9, 3.2, 3.9];   # Here are some points.
  314. #
  315. FitLine(xData, yData, a,b,r, ApproxError)       # calulcate the best fit line.
  316. #       This returns:
  317. a
  318.   a = 0.97        # slope
  319. b
  320.   b = 0.1          # intercept.
  321. r
  322.   r = 0.91287093     # correlation coeff:  yes, this data is almost a perfect line.
  323. ApproxError
  324.   ApproxError = 0.17748239    # approximate errors in y.
  325. #
  326. yFit = a xData + b
  327.   yFit[1…4] = [1.07, 2.04, 3.01, 3.98]   # The line y(xData). 
  328. #      table(xData, yData, yFit)
  329. # xData           yData           yFit
  330. # - - - - - - - - - - - - - - - - - - -
  331.    1                  1.1               1.07
  332.    2                  1.9               2.04
  333.    3                  3.2               3.01
  334.    4                  3.9               3.98
  335. #
  336. #   To see a plot of this, plot :
  337. #     [x,y]:   [xData, yData] # as a point plot , and       ( Item 1 )
  338. #                          or
  339. #                    [xData, yData, 0, 2 ApproxError]     # as points with error bars.
  340. #
  341. #     Range:   x = xMin…xMax@3xPix      # as a curve.  ( Item 2 )
  342. #     [x,y]:   [x, a x + b]       
  343. #
  344.  
  345.  
  346. ##############
  347. # A quadratic to these same points, with some fairly small error bars:
  348. #
  349.   sigma = [0.2, 0.04, 0.04, 0.2] ;          # errors on yData.
  350. # Now fit guess(x) = C(1) + C(2)*x + C(3)*x^2.
  351. FitPoly(xData,yData,Sigma, 3,C, prob) 
  352. prob
  353.   prob = 0.0110876    # a fit this bad would happen ~ 1% of the time by chance.
  354. c
  355.   C[1…3] = [0.09826, 0.8713, 0.02522] 
  356. quadFit = c[1] + c[2] xData + c[3] xData^2
  357.   quadFit[1…4] = [0.99478, 1.94174, 2.93914, 3.98698] 
  358. # ( Or use quadFit = Poly(C,xData), which does the same thing.)
  359. #
  360. # Table(xData, yData, sigma, quadFit)  # evaluate this without front "#" 
  361. # xData    ,      yData     ±     sigma     ,      quadFit
  362. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  363.    1                  1.1               0.2               0.99478
  364.    2                  1.9               0.04             1.94174
  365.    3                  3.2               0.04             2.93914
  366.    4                  3.9               0.2               3.98698
  367. # So, with these errors, the data are NOT well fit by a quadratic.
  368. #
  369. #   To see a plot of this, plot :
  370. #     [x,y]:     [xData, yData, 0, 2Sigma] # as a point plot with error bars, and
  371. #
  372. #     Range:   x = xMin…xMax@3xPix      # as a curve.
  373. #     [x,y]:   [x, Poly(C,x)]        
  374. #
  375.  
  376.  
  377. ##############
  378. # Some Legendre polynomials, which are meaningful for -1<=x<=1:
  379. #
  380. xData = -.8….8@.2
  381.   xData[1…9] = [-0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8] 
  382. yData = [0, .2,.2,.2, 0, -.2,-.2,-.2,0];    # a semi-sinusoid.
  383. Sigma = 0.05;   # errors for yData
  384. FitLegendre(xData, yData, sigma, 4, Al, prob)
  385. #
  386. prob
  387.   prob = 0.51972608     # so this fit is reasonable.
  388. #
  389. Al
  390.   Al[1…4] = [ 1.7294e-21, -0.04377, -1.3042e-20, 0.48822]  
  391. # Notice that A[2] and A[4], which are the coefficients fo the
  392. # odd polynomials, are the only significant ones, since yData is
  393. # also odd.
  394. #
  395. yLeg = LegendreModel(Al,xData)
  396.   yLeg[1…9] = [0.05455, 0.28013, 0.30067, 0.18451,  1.0424e-20, -0.18451, -0.30067, -0.28013, -0.05455] 
  397. #
  398. #   table(xData, yData,sigma, yLeg)
  399. # xData    ,     yData     ±     Sigma     ,     yLeg
  400. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  401.    -0.8             0                  0.05             0.05455
  402.    -0.6             0.2               0.05             0.28013
  403.    -0.4             0.2               0.05             0.30067
  404.    -0.2             0.2               0.05             0.18451
  405.    0                  0                  0.05              1.0424e-20
  406.    0.2               -0.2             0.05             -0.18451
  407.    0.4               -0.2             0.05             -0.30067
  408.    0.6               -0.2             0.05             -0.28013
  409.    0.8               0                  0.05             -0.05455
  410. #
  411. #  To see the Legendre polynomials themselves, define
  412. x=-1…1@.05;
  413. P = CalcLegendre(4,x);
  414. # and plot
  415. #  [x,y]:      [x,P[1,]]; [x,P[2,]] ; [x,P[3,]] ; [x,P[4,]] 
  416. # from x=-1 to 1, which shows the first 4.
  417. #
  418. #  Note that if dx= x[2] - x[1], then these arrays have
  419. #     P[i,] • P[j,] * dx   =   0                  if i<>j  (i.e. they are orthogonal).
  420. #                                   =   2/(2j+3)     if  i=j.
  421. #
  422. #  To plot the data and the fit, plot
  423. #     [x,y]:    [xData,yData,0,2Sigma]     # as a point plot with error bars,
  424. #
  425. #  and
  426. #     Range:    x=xMin…xMax@3xPix
  427. #     [x,y]:     [x, LegendreModel(Al, x)]    # as a curve.
  428. #
  429.  
  430.  
  431. ##############
  432. # Finally, an example of calling xFIT_FUNCS with 
  433. # an NC user program as a fitting function.
  434. #
  435. # Suppose we wish to fit a function of the form
  436. #   G(x) = A[1] sin(x) + A[2] exp(x)
  437. # to the data points
  438. xData = [1,2,3,4]; yData=[1,2,3,4];   Sigma = 1;  Jparam=2;
  439. #
  440. #
  441. # Then the routine to evalute G(x) should be 
  442.   program Basis_Strange(jP1, zIO)
  443. .   var x
  444. .   begin  # n = number of basis functions to evaluate at zIO[n+1].
  445. .     x = zIO[jP1] # jP1=J+1 should = 3 here.
  446. .     zIO[1] = sin(x)
  447. .     zIO[2] = exp(x)
  448. .   end
  449. .   
  450. #
  451. # Then, just as for the polynomial and Legendre examples above,
  452. # Find Auser:
  453.  FitUser(xData,yData,Sigma, Jparam,Auser,  Prob, Basis_Strange)
  454. prob # probability of this fit :
  455.    Prob = 0.61348783      # This fit is OK (since the errors are large).
  456. Auser
  457.   Auser[1…2] = [1.3807, 0.09774]   # the coefficients
  458. yFit = Auser[1] sin(xData) + Auser[2] exp(xData)    # the fit to the data
  459.   yFit[1…4] = [1.4275, 1.97767, 2.158, 4.29149] 
  460. #
  461. # Table(xData,yData,sigma, yFit)
  462. # xData           yData           Sigma           yFit
  463. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  464.    1                  1                  1                  1.4275
  465.    2                  2                  1                  1.97767
  466.    3                  3                  1                  2.158
  467.    4                  4                  1                  4.29149
  468.  
  469.