Home Page

R. T. RUSSELL

BBC BASIC for Windows

Polynomial Fitting



This program fits an order-five polynomial to a set of 20000 experimental data points. It demonstrates the power of BBC BASIC's built-in array and matrix operations to perform high-speed calculations. It could be adapted to carry out other least-squares fitting tasks.

Download POLYFIT.BBC Run POLYFIT.EXE

     REM POLYFIT - fit a polynomial to a set of experimental data
     REM demonstrating the use of BBC BASIC's matrix operations.
     REM In this version the maximum order of polynomial is five.
     REM Richard T. Russell, richard@rtrussell.co.uk, 12-Apr-2011

     
HIMEM = PAGE + 5000000
     INSTALL @lib$+"ARRAYLIB"
     INSTALL @lib$+"FNUSING"
     INSTALL @lib$+"WINLIB5"
     *FLOAT 64

     file$ = @dir$+"polyfit.csv"
     max% = 20000

     REM Initialise screen:
     
SYS "SetWindowText", @hwnd%, "Least squares polynomial fitting"
     VDU 23,22,720;480;8,16,16,128
     VDU 5
     ORIGIN 140,168
     COLOUR 2,0,100,0
     PROCaxes

     REM Create controls:
     
button1% = FN_button("Load && plot file", 190, 12, 120, 20, FN_setproc(PROCload), 0)
     button2% = FN_button("Fit polynomial", 390, 12, 120, 20, FN_setproc(PROCfit), 0)
     SYS "EnableWindow", button2%, 0

     REM Declare arrays:
     
DIM vector(5), matrix(5,5)
     DIM x(max%), x2(max%), x3(max%), x4(max%), x5(max%)
     DIM x6(max%), x7(max%), x8(max%), x9(max%), x10(max%)
     DIM y(max%), xy(max%), x2y(max%), x3y(max%), x4y(max%), x5y(max%)

     REM Idle loop:
     
REPEAT
       WAIT
1
     UNTIL FALSE
     END

     
REM Draw axes and labels:
     
DEF PROCaxes
     CLS
     GCOL
0
     FOR x = 0.0 TO 1.0 STEP 0.1
       MOVE x*1200, 0 : PLOT 21, x*1200, 700
       MOVE x*1200-24, -24 : PRINT FNusing("#.#", x);
     NEXT
     FOR
y = 0 TO 6
       MOVE 0, 700*y/6 : PLOT 21, 1198, 700*y/6
       MOVE -80, 700*y/6+16 : PRINT FNusing("#.#", y);
     NEXT
     RECTANGLE
0, 0, 1198, 700
     ENDPROC

     
REM Load and plot file:
     
DEF PROCload
     file% = OPENIN(file$)
     IF file% = 0 ERROR 0, "Could not open file " + file$

     PROCaxes
     SYS "EnableWindow", button2%, 0
     index% = 0
     x() = 0.0
     y() = 0.0
     GCOL 4
     WHILE NOT EOF#file% AND index% <= max%
       record$ = GET$#file%
       comma% = INSTR(record$, ",")
       IF comma% THEN
         
x(index%) = VAL(record$)
         y(index%) = VAL(MID$(record$,comma%+1))
         LINE x(index%)*1200, y(index%)*700/6, x(index%)*1200, y(index%)*700/6
         index% += 1
       ENDIF
     ENDWHILE
     CLOSE
#file%
     npts% = index%
     SYS "EnableWindow", button2%, 1
     ENDPROC

     
REM Fit and plot polynomial:
     
DEF PROCfit
     TIME = 0

     sum_x = SUM(x())
     x2()  = x() * x()   : sum_x2  = SUM(x2())
     x3()  = x() * x2()  : sum_x3  = SUM(x3())
     x4()  = x2() * x2() : sum_x4  = SUM(x4())
     x5()  = x2() * x3() : sum_x5  = SUM(x5())
     x6()  = x3() * x3() : sum_x6  = SUM(x6())
     x7()  = x3() * x4() : sum_x7  = SUM(x7())
     x8()  = x4() * x4() : sum_x8  = SUM(x8())
     x9()  = x4() * x5() : sum_x9  = SUM(x9())
     x10() = x5() * x5() : sum_x10 = SUM(x10())

     sum_y = SUM(y())
     xy()  = x() * y()   : sum_xy  = SUM(xy())
     x2y() = x2() * y()  : sum_x2y = SUM(x2y())
     x3y() = x3() * y()  : sum_x3y = SUM(x3y())
     x4y() = x4() * y()  : sum_x4y = SUM(x4y())
     x5y() = x5() * y()  : sum_x5y = SUM(x5y())

     matrix() = \
     
\ npts%,  sum_x,   sum_x2,  sum_x3,  sum_x4,  sum_x5, \
     
\ sum_x,  sum_x2,  sum_x3,  sum_x4,  sum_x5,  sum_x6, \
     
\ sum_x2, sum_x3,  sum_x4,  sum_x5,  sum_x6,  sum_x7, \
     
\ sum_x3, sum_x4,  sum_x5,  sum_x6,  sum_x7,  sum_x8, \
     
\ sum_x4, sum_x5,  sum_x6,  sum_x7,  sum_x8,  sum_x9, \
     
\ sum_x5, sum_x6,  sum_x7,  sum_x8,  sum_x9,  sum_x10

     vector() = \
     
\ sum_y,  sum_xy,  sum_x2y, sum_x3y, sum_x4y, sum_x5y

     PROC_invert(matrix())
     vector() = matrix().vector()

     took = TIME / 100

     GCOL 1
     MOVE 80, -72
     PRINT "y = " FNusing("##.###", vector(0)) FNusing("+##.###", vector(1)) " x" \
     
\    FNusing("+##.###", vector(2)) " x^2" FNusing("+##.###", vector(3)) " x^3" \
     
\    FNusing("+##.###", vector(4)) " x^4" FNusing("+##.###", vector(5)) " x^5"

     GCOL 2
     MOVE 80, -120
     PRINT "Fitting order-five polynomial to " ;npts% " points took " ;
     PRINT FNusing("#.##", took) " seconds"

     GCOL 9
     FOR x = 0.0 TO 1.0 STEP 0.001
       y = 0
       FOR power% = 0 TO 5
         y += vector(power%) * x^power%
       NEXT
       PLOT
x*1200, y*700/6
     NEXT x

     ENDPROC


Home - Products - Contact us

Best viewed with Any Browser Valid HTML 3.2!
© Richard Russell 2011