cdeagle Senior Member
 Joined: 22/06/2014 Location: United StatesPosts: 266 |
| Posted: 03:20am 30 Mar 2017 |
Copy link to clipboard |
 Print this post |
|
This post describes an MMBASIC program for the Micromite eXtreme that can be used to first "fit" and then interpolate three-dimensional data provided by the user. The degree of the surface fit, up to order 10, can also be specified by the user.
Here's a typical user interaction with the software. It uses an analytic three-dimensional surface to demonstrate how to use the software. The difference between the analytic equation and the interpolated value is printed at the end of the scientific simulation.
program demo_sfit ----------------- this program demonstrates the procedure for calling the subroutine surfit.bas which calculates fitting coefficients for 3-dimensional surfaces of the form z = f(x,y) from x, y and z data points input by the user. this program demonstrates the use of surfit to find fitting coefficients for the surface defined by z = -cos(3*pi*x/10)*cos(pi*y/10) for -5 <= x <= +5 and -5 <= y <= +5 please input the degree of the surface fit (degree <= 10) ? 10 please wait, computing coefficients fitting coefficients coef( 0, 0) =-0.999206 fitting coefficients coef( 1, 0) = 5.38498e-16 coef( 0, 1) =-5.79029e-16 fitting coefficients coef( 2, 0) = 0.442671 coef( 1, 1) = 5.07139e-16 coef( 0, 2) = 0.0490698 fitting coefficients coef( 3, 0) = 5.18700e-16 coef( 2, 1) = 7.06358e-17 coef( 1, 2) =-5.34561e-16 coef( 0, 3) = 1.45522e-16 fitting coefficients coef( 4, 0) =-0.0323963 coef( 3, 1) =-3.35196e-17 coef( 2, 2) =-0.0215217 coef( 1, 3) =-1.86050e-16 coef( 0, 4) =-0.000388245 fitting coefficients coef( 5, 0) =-1.31389e-16 coef( 4, 1) =-3.18267e-18 coef( 3, 2) = 3.92482e-17 coef( 2, 3) =-1.27874e-17 coef( 1, 4) = 6.00305e-17 coef( 0, 5) =-9.04811e-18 fitting coefficients coef( 6, 0) = 0.000913117 coef( 5, 1) = 6.27277e-19 coef( 4, 2) = 0.00152308 coef( 3, 3) = 7.99553e-18 coef( 2, 4) = 0.000161127 coef( 1, 5) = 2.06673e-17 coef( 0, 6) = 9.80403e-07 fitting coefficients coef( 7, 0) = 9.10733e-18 coef( 6, 1) = 7.74537e-20 coef( 5, 2) =-1.25844e-18 coef( 4, 3) = 2.39623e-19 coef( 3, 4) =-1.91547e-18 coef( 2, 5) = 7.44808e-19 coef( 1, 6) =-2.70286e-18 coef( 0, 7) = 8.51186e-20 fitting coefficients coef( 8, 0) =-1.19697e-05 coef( 7, 1) =-1.01718e-21 coef( 6, 2) =-3.85934e-05 coef( 5, 3) =-1.01276e-19 coef( 4, 4) =-9.76504e-06 coef( 3, 5) =-4.96569e-19 coef( 2, 6) =-3.28361e-07 coef( 1, 7) =-9.21900e-19 coef( 0, 8) =-2.18460e-10 fitting coefficients coef( 9, 0) =-1.88583e-19 coef( 8, 1) =-6.91317e-22 coef( 7, 2) = 1.67106e-20 coef( 6, 3) =-2.32910e-21 coef( 5, 4) = 1.77301e-20 coef( 4, 5) =-4.51179e-21 coef( 3, 6) = 3.39661e-20 coef( 2, 7) =-1.39360e-20 coef( 1, 8) = 4.20262e-20 coef( 0, 9) = 3.24655e-21 fitting coefficients coef( 10, 0) = 6.02420e-08 coef( 9, 1) = 1.26586e-23 coef( 8, 2) = 3.58607e-07 coef( 7, 3) = 2.94099e-23 coef( 6, 4) = 1.57525e-07 coef( 5, 5) = 3.16482e-21 coef( 4, 6) = 1.16010e-08 coef( 3, 7) = 9.07642e-21 coef( 2, 8) = 6.38069e-11 coef( 1, 9) = 1.44452e-20 coef( 0, 10) =-4.43318e-13 would you like to interpolate an x, y data point (y = yes, n = no) ? y
please input the x data point (-5 <= x <= +5) ? -3.45675
please input the y data point (-5 <= y <= +5) ? 3.45675 x data point = -3.45675 y data point = 3.45675 z data point = 0.462422 z_analytic - z_fit = 0.000483485
Here's the MMBASIC source code for this numerical method.
' program demo_sfit.bas March 30, 2017 ' this program demonstrates the procedure for calling ' the subroutine surfit.bas which calculates fitting ' coefficients for 3-dimensional surfaces of the form ' z = f(x,y) from x, y and z data points input by the ' user. It also illustrates how to interpolate an x-y ' data pair provided by the user. ' this program demonstrates the use of surfit to find ' fitting coefficients for the surface defined by ' z = -cos(3*pi*x/10)*cos(pi*y/10) ' for -5 <= x <= +5 and -5 <= y <= +5 '''''''''''''''''''''''''''''''''''''''' option default float option base 1 ' dimension data and coefficient arrays dim xdata(121), ydata(121), zdata(121), coef(11, 11) print " " print "program demo_sfit" print "-----------------" print " " print "this program demonstrates the procedure for calling" print "the subroutine surfit.bas which calculates fitting" print "coefficients for 3-dimensional surfaces of the form" print "z = f(x,y) from x, y and z data points input by the" print "user." print " " print "this program demonstrates the use of surfit to find" print "fitting coefficients for the surface defined by" print " " print " z = -cos(3*pi*x/10)*cos(pi*y/10)" print " " print " for -5 <= x <= +5 and -5 <= y <= +5" ' generate data points for the surface defined by ' z = -cos(3*pi*x/10)*cos(pi*y/10) ' for -5 <= x <= +5 and -5 <= y <= +5 ndata% = 0 for i% = -5 to 5 step 1 for j% = -5 to 5 step 1 ndata% = ndata% + 1 x = i% xdata(ndata%) = i% y = j% ydata(ndata%) = j% z = -cos(3.0 * pi * x / 10.0) * cos(pi * y / 10.0) zdata(ndata%) = z next j% next i% do print " " print "please input the degree of the surface fit (degree <= 10)" input ndeg% loop until (ndeg% >= 0 and ndeg% <= 10) print " " print "please wait, computing coefficients"; print " " surfit(ndeg%, ndata%, xdata(), ydata(), zdata(), coef()) ' print fitting coefficients for i% = 1 to ndeg% + 1 print " " print "fitting coefficients" print " " i1% = i% + 1 for j% = 1 to i% print "coef("; i1% - j% - 1; ","; j% - 1; ") ="; print coef(j%, i1% - j%) next j% next i% do print " " print "would you like to interpolate an x, y data point" print "(y = yes, n = no)" input fit$ loop until (fit$ = "y" or fit$ = "n") if (fit$ = "y") then do print print "please input the x data point (-5 <= x <= +5)" input x loop until (abs(x) <= 5.0) do print print "please input the y data point (-5 <= y <= +5)" input y loop until (abs(y) <= 5.0) ' perform interpolation sfunction(ndeg%, coef(), x, y, z) ' print results of interpolation print " " print "x data point = ", x print " " print "y data point = ", y print " " print "z data point = ", z print " " ' analytic z-value za = -cos(3.0 * pi * x / 10.0) * cos(pi * y / 10.0) print "za = ", za print "z_analytic - z_fit = ", za - z print " " end if end ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' sub surfit (ndeg%, ndata%, xdata(), ydata(), zdata(), coef()) ' surface fit subroutine ' input ' ndeg% = degree of surface fit (ndeg% <= 10) ' ndata% = number of x, y and z data points ' xdata() = vector of x data values (ndata% rows) ' ydata() = vector of y data values (ndata% rows) ' zdata() = vector of z data values (ndata% rows) ' output ' coef() = array of surface fit coefficients (11 rows by 11 columns) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' local ndeg1% = ndeg% + 1 local ndeg2% = ndeg% + 2 local nrow% = ndeg1% * ndeg2% / 2 local ncol% = nrow% + 1 local nalf% = 2 * ndeg% local nalf1% = nalf% + 1 local nalf2% = nalf% + 2 local xa(ndeg1% * ndeg2% / 2) local zadd(ndeg1%, ndeg1%) local hsmg(2 * ndeg1%, 2 * ndeg1%) local xmatrix(ndeg1% * ndeg2% / 2, ndeg1% * ndeg2% / 2 + 1) for i% = 1 to nalf1% for j% = 1 to nalf2% - i% hsmg(i%, j%) = 0.0 next j% next i% for i% = 1 to ndeg1% for j% = 1 to ndeg2% - i% zadd(i%, j%) = 0.0 next j% next i% z1 = 0.0 for i% = 1 to ndata% z1 = z1 + zdata(i%) next i% if (ndeg% <> 0) then for i% = 1 to ndata% a = 1.0 xa(1) = 1.0 x = xdata(i%) y = ydata(i%) z = zdata(i%) for j% = 2 to nalf1% a = a * x xa(j%) = a if (j% <= ndeg1%) then zadd(1, j%) = zadd(1, j%) + a * z hsmg(1, j%) = hsmg(1, j%) + a next j% for l% = 2 to nalf1% for m% = 1 to nalf2% - l% xa(m%) = xa(m%) * y hsmg(l%, m%) = hsmg(l%, m%) + xa(m%) next m% if (l% <= ndeg1%) then for n% = 1 to ndeg2% - l% zadd(l%, n%) = zadd(l%, n%) + xa(n%) * z next n% end if next l% next i% end if hsmg(1, 1) = ndata% zadd(1, 1) = z1 m% = 0 for i% = 1 to ndeg1% for j% = 1 to ndeg2% - i% n% = 0 m% = m% + 1 xmatrix(m%, ncol%) = zadd(i%, j%) for k% = i% to ndeg% + i% for l% = j% to ndeg% + i% + j% - k% n% = n% + 1 xmatrix(m%, n%) = hsmg(k%, l%) next l% next k% next j% next i% if (ndeg% = 0) then xa(1) = xmatrix(1, 2) / xmatrix(1, 1) return end if nr1% = nrow% - 1 for k% = 1 to nr1% nb% = 0 amax = xmatrix(k%, k%) i1% = k% + 1 for ki% = i1% to nrow% if (abs(xmatrix(ki%, k%)) > abs(amax)) then amax = xmatrix(ki%, k%) nb% = ki% end if next ki% if (nb% <> 0) then for nl% = k% to ncol% xsave = xmatrix(nb%, nl%) xmatrix(nb%, nl%) = xmatrix(k%, nl%) xmatrix(k%, nl%) = xsave next nl% end if const1 = xmatrix(k%, k%) for i% = i1% to nrow% xa(i%) = -xmatrix(i%, k%) / const1 next i% for j% = i1% to ncol% const1 = xmatrix(k%, j%) for i% = i1% to nrow% xmatrix(i%, j%) = xmatrix(i%, j%) + const1 * xa(i%) next i% next j% next k% xa(nrow%) = xmatrix(nrow%, ncol%) / xmatrix(nrow%, nrow%) for i% = 1 to nr1% k% = nrow% - i% sum = 0.0 const1 = xmatrix(k%, k%) for j% = k% + 1 to i% + k% sum = sum + xmatrix(k%, j%) * xa(j%) next j% xa(k%) = (xmatrix(k%, ncol%) - sum) / const1 next i% ' load coef array k% = 0 for i% = 1 to ndeg1% for j% = 1 to ndeg2% - i% k% = k% + 1 coef(i%, j%) = xa(k%) next j% next i% end sub ''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''' sub sfunction(ndeg%, coef(), x, y, z) ' interpolate surface function subroutine ' z = f(x,y) ' input ' ndeg% = degree of surface fit ' coef() = array of surface fit coefficents ' (up to 11 rows by 11 columns) ' x = x data value ' y = y data value ' output ' z = interpolated z data value of surface at x, y ''''''''''''''''''''''''''''''''''''''''''''''''''' local a, y1 local ndeg1% = ndeg% + 1 local ndeg2% = ndeg% + 2 local work(ndeg1% * ndeg2% / 2) if (ndeg% = 0) then z = coef(1, 1) exit sub end if a = 1.0 y1 = 0.0 work(1) = 1.0 for i% = 2 to ndeg1% a = a * x work(i%) = a y1 = y1 + a * coef(1, i%) next i% for i% = 2 to ndeg1% for j% = 1 to ndeg2% - i% work(j%) = work(j%) * y y1 = y1 + work(j%) * coef(i%, j%) next j% next i% z = y1 + coef(1, 1) end sub
|