TweetFollow Us on Twitter

Curve Fitting 3
Volume Number:1
Issue Number:13
Column Tag:Forth Forum

Curve Fitting, Part III

By Jörg Langowski, Chemical Engineer, Grenoble, France, MacTutor Editorial Board

Last time I promised you to add some input/output to the curve fitter program so that it becomes a useful application. We'll do this here today.

A lot of basic graphic routines which you would have to write yourself on other machines are included in the Quickdraw ROM. This makes life very easy; we can use the screen like we would use a plotter (of course, we can do much better than that, but this is what we are dealing with today). What is not included in the ROM, of course, are utilities that plot coordinate axes, draw lines through pairs of x/y points, add symbols etc.

Most computer systems that are used for numerical calculation purposes contain a set of standard plotting routines, mostly callable from FORTRAN, that will help you generating a 'nice' graphical output with not too much effort. This column gives you some similar routines in FORTH; I have tried to stick closely to the Calcomp plotting routines, since they are something of a standard.

Our objective is to produce something like the curve in Fig. 1. The data points that the model is fitted to will be displayed using some symbols, while the fitted curve is plotted as a smooth line. X- and Y-axes are added to the plot.

The numbers that are to be plotted will be given in floating point format (in this case, single precision arrays as defined previously). So first of all we have to know how to scale the data to the integer values of the bit map that we are going to plot to.

The Calcomp convention is, for an array of N floating point numbers, to store the minimum of these numbers in cell N+1 of the array and the difference between the minimum and the maximum in cell N+2. These two numbers are then rounded to one significant figure. Given this information, one can write routines that automatically draw an axis that spans the range of the data values.

The rounding to one significant figure is done by the word next.int, which given the address of an extended number on the stack returns with the address of the rounded number (which is a local variable of next.int).

fscale finds the minimum and maximum values of an array and stores the scaling numbers above the last data point after rounding them to one significant digit.

xaxis and yaxis draw coordinate axes in x- and y-direction. Input parameters are (#ticks\length\array\npts), #ticks gives the number of ticks to be drawn (to the bottom of the x- and to the left of the y-axis), length is the total axis length in points, array the address of the scaled data array and npts the number of points in array.

Given two scaled arrays, line draws a line through the (x y) pairs defined by the two arrays. The symbol defined by the global symbol is plotted at each of the data points. Symbols could be e.g. '+' or '*'. Setting symbol to zero will draw no symbols (how could you have guessed). Depending on the setting of the global flag connecting, the symbols are either connected by a line or not.

For all the plotting routines cartesian has to be switched on and the origin to be defined within the output window by xyoffset. init.plot is used to do this job.

The main curve fitter program now consists of the following:

- the data arrays xdat and ydat are initialized with the simulated 'experimental data' (init). In this month's example, we use a sum of two exponentials as our model; this gives us five parameters to fit.

- a routine is called in which one can deliberately change the values of the parameters (for this we need floating point input, see below), so that one can see how the correct curve is fitted through the data starting from wrong parameters. One may also change the total number of parameters to be fitted; for instance, fitting three parameters only will force a single exponential fit to the data points. In this case, parameters 4 and 5 will have to be set to zero.

- the main loop calculates theoretical function values from xdat and the parameters and stores them in zdat. The data arrays are scaled and the plot displayed (like in Fig. 1); then one iteration of the fitting routine is taken, the parameters changed accordingly, displayed and the process repeated until parameter changes are below 1 part in 104.

Floating point input

As I mentioned, the program would not be very useful without floating point input routines. In order to be independent of any particular Forth implementation, I am including a simple floating point input routine here which accepts a string and converts it to the decimal string format used by the SANE conversion routines.

Any such routine would mainly consist of taking successive characters from the input string, generating a decimal mantissa and keeping track of the number of digits behind the decimal point, then looking for an 'e' or 'E' to indicate an exponent and converting the exponent finally. In that aspect, the routine written here is very similar to the MacForth floating input routine. There is one difference, in that numbers without an exponent will be accepted and converted to floating point numbers, too. Therefore, you won't be able to use this routine as an extension of the Forth interpreter, as MacForth level 2 does. But in entering a lot of data, it can be very tedious always having to type an exponent.

fnumber takes a string as its input parameter and leaves on the stack:

( addr of float\true ) if a valid floating point number was read from 
the string,
( false ) if the conversion was not successful.

In the latter case, an error message is printed.

input.float reads a string from the keyboard into pad, then calls fnumber to convert it.

With the additions from this column, the curve fitter should finally be a utility that is useful to you (in case you have any curves to fit). Changing the function to be fitted is easy, and you might even install a make switch for vectored execution (V1#7) so that you can easily switch between different functions within one program.

Data input still has to be done manually, number by number. However, input.float may easily be extended to read input from a file. To transfer data to/from other applications through the scrap requires some more work; I'll deal with that problem soon.

Feedback dept.

Re: finding object code of unnamed tokens

The procedure to decompile the object code of an axed token is the following (V1#2):

- convert the token to an absolute address, using token>addr. If the word contained there is $4e4f (TRAP $F), the next words will be Forth code. Start decompiling at the following word. Of course, different versions of MacForth will give different addresses for the individual words due to different dictionary arrangements; but this procedure should work for any version of Level 1 or Level 2.

Re: MacModula floating point

Shortly after my comment on errors in MacModula 2's 32-bit floating point arithmetic, I received a letter from the author of those routines, Daan Strebe:

" A few weeks ago I followed several bug reports to find two fundamental errors in the floating-point routines, one a conceptual error in the rounding and the other a misunderstanding about the 68000 processor instruction set. These two errors affected the multiply routine most, although the others were somewhat affected also. I revamped those routines and then ran a complex set of comprehensive tests, and the results allow me to state with a margin of confidence that the floating point in the latest rev is now not only slightly faster than it was, but also that the only errors in the basic routines (not necessarily including those in the math library) are from rounding. The rounding as it is now implemented yields 3 downward, 4 upward, and 1 non-round per 8 random floating-point operations. This should be satisfactory for most users; full IEEE rounding would considerably decrease the speed. I believe the compromise was successful. "

So everything should be fixed now. Let's hope that the new update will be distributed soon (it probably is when this goes to the printer's).

Listing 1: Plotting routines and floating point input for the curve fitter 
program

( Additions to the curve fitting program) 
( for graphical output and floating point input.)
( © 1985 J. Langowski for MacTutor)
( Again, only the parts that have been changed) 
( or added with respect to the last two columns )
( are printed here)

: s> 1008 fp68k @sr 10 and ;

: numstring create 24 allot ;  
numstring zzs1 ( internal conversion string )

: dec. ( float\format# -- )
       zzformat ! zzformat swap zzs1 b2d
       zzs1 dup w@ 255 > if ." -" else ."  " then
       dup 4+ count over 1 type ." ."
       swap 1+ swap 1- type ( mantissa )
       2+ w@ ( get exponent )
            1 w* zzformat @ + 1- 
            ." E" 0 .r ;

create xdat 400 allot   create ydat 400 allot
create zdat 400 allot   create residues 400 allot
100 10 matrix derivmat    10 11 matrix resmat
     5 constant npars        80 constant npts
create par 5 10 * allot   
create delta 5 4*  allot

float logten  ten logten x2x  logten lnx
: log10x dup lnx logten swap f/ ;

( define function )                               ( 090485 jl )
                                     float temp ( local to func)

 func ( x -- f[x] = par[1] + par[2] * exp[par[3]*x]
                                       + par[4] * exp[par[5]*x] )
  dup temp x2x
  par 40 + temp f* temp expx  par 30 + temp f*
  par 20 + over f* dup expx  par 10 + over f*
  par over f+  temp over f+ ;
                                     axe temp
: >fa1  fa1 s2x ;
: init_pars   one par x2x  two par 10+ x2x 
                 -one par 20 + x2x  two par 20 + f/
                   one par 30 + x2x  
                 -one par 40 + x2x ten par 40 + f/ ;
init_pars

: one_iter
  make_derivmat  residuals  
  make_resmat     delta 0 0 resmat npars gauss ;

: new_pars 16 ( true if no significant changes)
  npars 0 do par i 10 * +
    delta i 4* +  over  s+
    delta i 4* + fa1 s2x  fa1 f/
    fa1 fabs  eps fa1 f> and loop ;

80 ' npts !    5 ' npars !

: init ( initialize data arrays)
          npts 0 do i sp@ fa1 in2x 4*
          xdat over + fa1 swap x2s
          ydat over + fa1 func  ranf fa2 x2x
          ten fa2 f/  fa2 over f+  swap x2s
          drop  loop ;

( plotting routines)                        ( 092385 jl )
float 1/2  1 sp@ 1/2 in2x drop  2 sp@ 1/2 in/ drop
float small  ten small x2x  -200 sp@ fa1 in2x drop
fa1 small x^y  
( anything smaller than small will be zero)
float sc.aux  float sc.exp
: next.int ( float -- rounded to 1 dec. place )
  dup small f>
  if dup sc.aux x2x  sc.aux  dup fabs  dup log10x
     dup 1/2 swap f- frti
     ten sc.exp x2x  sc.aux sc.exp x^y   sc.aux x2x
     sc.exp sc.aux f/  sc.aux frti  sc.exp sc.aux f*
     sc.aux
  else drop zero then  ;

float xlow  float xhi  float sc.factor
: fscale 
    ( array \ n -- | start, scale -> array[n+1..n+2] )
  over xlow s2x  over xhi s2x
  over over 1 do
    dup i 4* + dup xlow s> not if dup xlow s2x then
               dup xhi  s> if xhi s2x  else drop then  loop
  xlow xhi f-
  over 4*  +  xlow next.int swap x2s
     1+ 4* +  xhi  next.int swap x2s  ;

: .fscale ( array \ n -- )
  4* + dup fa1 s2x ." min = " fa1 7 dec.
  4+ fa1 s2x ." , scale = " fa1 7 dec. cr ;

( xtick, ytick )                                  ( 092385 jl )

: xtick ( rx x -- ) dup 0 move.to
  dup -5 draw.to  dup 15 - -16 move.to
  get.textsize >r 9 textsize swap 2 dec. r> textsize
  0 move.to ;

: ytick ( ry y -- ) -45 over 4- move.to
  get.textsize >r 9 textsize swap 2 dec. r> textsize
  0 over move.to    -5 over draw.to
  0 over 6- move.to  0 swap draw.to ;

( xaxis)                                           ( 092385 jl )
float start  float del
: xaxis 
   ( #ticks\length\array\npts -- | starts at origin )
  0 0 move.to
  4* + dup  start s2x  4+ delta s2x
  over /  ( #ticks\length/tick -- )
  over 0 do dup i 1+ * dup 0 draw.to
         delta fa1 x2x i 1+ sp@ fa1 in* drop
                    3 pick sp@ fa1 in/ drop
         start fa1 f+    fa1 swap xtick loop
  drop drop ;

( yaxis)                                          ( 092385 jl )
: yaxis 
  ( #ticks\length\array\npts -- | starts at origin )
  0 0 move.to
  4* + dup  start s2x  4+ delta s2x
  over /  ( #ticks\length/tick -- )
  over 0 do dup i 1+ * 0 over draw.to
            delta fa1 x2x i 1+ sp@ fa1 in* drop
                    3 pick sp@ fa1 in/ drop
         start fa1 f+    fa1 swap ytick loop
  drop drop ;

( line, variables )                               ( 092585 jl )
variable xline.length variable yline.length
variable xpos  variable ypos  variable symbol
variable connecting  connecting off
float xstart float ystart float xdel float ydel

( line)                                           ( 092585 jl )
: line ( xarray\yarray\npts\xlength\ylength -- )
  yline.length !  xline.length !   0 0 move.to
    over over 4* + dup ystart s2x 4+ ydel s2x
  3 pick over 4* + dup xstart s2x 4+ xdel s2x
  0 do over i 4* + fa1 s2x  xstart fa1 f-  xdel fa1 f/
       dup  i 4* + fa2 s2x  ystart fa2 f-  ydel fa2 f/
       xline.length fa1 in*  fa1 xpos x2in
       yline.length fa2 in*  fa2 ypos x2in
       xpos @  ypos @  over over
       connecting @ if draw.to else move.to then
       -4 -4 rmove symbol @ emit move.to
    loop   drop drop ;

( calc.theor, disp.theor, disp.data, scale.all)   
( 092585 jl )
: calc.theor
          npts 0 do xdat i 4* + fa1 s2x fa1 func
                    zdat i 4* + x2s  loop ;
: disp.theor
    0 symbol !  connecting on
    xdat zdat npts 400 250 line ;
: disp.data
    43 symbol !  connecting off
    xdat ydat npts 400 250 line ;
: scale.all
    xdat npts fscale  ydat npts fscale
    ydat npts 4* + @  zdat npts 4* + !
    ydat npts 1+ 4* + @  zdat npts 1+ 4* + !  ;


( disp.axes)                                      ( 092585 jl )
: disp.axes
    5 400 xdat npts xaxis  5 250 ydat npts yaxis ;
: init.plot
    page 50 255 xyoffset cartesian on ;

( floating point input)                           ( 092385 jl )
: fsign zzs1 ;  : fexpo zzs1 2+ ;
: fmant zzs1 4+ ;  variable frac   float float.out
variable decimals
: input.sign 0 fsign !
  dup c@ case 45 of -1 fsign w! 1+ endof
              43 of             1+ endof endcase ;
: input.mantissa   0 decimals !   0 frac !
  fmant 21 +  fmant 1+ do  i fmant 1+ -  fmant c!
          dup c@ dup
             case 48 57 range.of ic! frac @ decimals +!
                                              1+ 1 endof
                     46 of   drop 1 frac !    1+ 0 endof
             20 swap endcase  +loop drop ;
: input.exponent
  dup c@ dup bl = not
      if dup 69 =  swap 101 =  or not
         if  drop 0
         else dup 1+ c@ 43 = 1 and +
              number decimals @ - fexpo w! -1
         then
      else  decimals @ -1 * fexpo w! -1  2drop
      then  ;

: fnumber zzs1 24 blanks
   input.sign input.mantissa input.exponent
   if fsign float.out d2b float.out -1
   else ." floating input error!" cr 0 then ;

: input.float pad 22 blanks pad 22 expect pad fnumber ;

: get.pars
  npars 0 do
          begin cr ." par[" i 1+ . ." ] = " input.float until
          par i 10 * + x2x loop
  cr begin cr ." total # of parameters to be fitted "
           5 input.number until 
  ' npars !  cr ;

: .pars npars 0 do
      ." par[" i 1+ . ." ] = " i 10 * par + 7 dec. cr loop ;

( main curve fitter program)                 ( 092685 jl )
: fit.curve  page
  init_pars ." initializing data arrays..." cr init
  5 ' npars ! init.plot get.pars .pars
  ." fitting " npars . ." parameters to "
               npts . ." data points "
  calc.theor scale.all page
  disp.data disp.axes disp.theor
  begin  one_iter new_pars not while
    page .pars
    calc.theor page disp.data disp.axes disp.theor
  repeat
  300 300 move.to ;

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Hopper Disassembler 4.2.13- - Binary dis...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
iFFmpeg 6.4.3 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
Firefox 55.0.2 - Fast, safe Web browser.
Firefox offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and casual... Read more
FileZilla 3.27.1 - Fast and reliable FTP...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.27.1: Fixed Vulnerabilities: Change client... Read more
Merlin Project 4.2.7 - $289.00
Merlin Project is the leading professional project management software for OS X. If you plan complex projects on your Mac, you won’t get far with a simple list of tasks. Good planning raises... Read more
Dashlane 4.8.4 - Password manager and se...
Dashlane is an award-winning service that revolutionizes the online experience by replacing the drudgery of everyday transactional processes with convenient, automated simplicity - in other words,... Read more
f.lux 39.984 - Adjusts the color of your...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
Sketch 46.2 - Design app for UX/UI for i...
Sketch is an innovative and fresh look at vector drawing. Its intentionally minimalist design is based upon a drawing space of unlimited size and layers, free of palettes, panels, menus, windows, and... Read more
Microsoft Office 2016 15.37 - Popular pr...
Microsoft Office 2016 - Unmistakably Office, designed for Mac. The new versions of Word, Excel, PowerPoint, Outlook and OneNote provide the best of both worlds for Mac users - the familiar Office... Read more
Slack 2.7.1 - Collaborative communicatio...
Slack is a collaborative communication app that simplifies real-time messaging, archiving, and search for modern working teams. Version 2.7.1: You're nearly finished signing in when suddenly – bonk... Read more

Bottom of the 9th (Games)
Bottom of the 9th 1.0.1 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Play the most exciting moment of baseball in this fast-paced dice and card game! | Read more »
The best apps for viewing the solar ecli...
If you somehow missed the news, many parts of the United States will be witness to a total solar eclipse on August 21 for the first time in over 90 years. It'll be possible to see the eclipse in at least some capacity throughout the continental U... | Read more »
The 5 best mobile survival games
Games like ARK: Survival Evolved and Conan Exiles have taken the world of gaming by storm. The market is now flooded with hardcore survival games that send players off into the game's world with nothing but maybe the clothes on their back. Never... | Read more »
Portal Walk (Games)
Portal Walk 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Portal Walk is adventure and relaxing platform game about Eugene. Eugene stuck between worlds and trying to find way back home.... | Read more »
Technobabylon (Games)
Technobabylon 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: City of Newton, 2087. Genetic engineering is the norm, the addictive Trance has replaced almost any need for human interaction,... | Read more »
5 reasons why 2v2 is the best mode in Cl...
Supercell has been teasing fans with 2v2 windows that allow players to team up for limited periods of time. The Summer of 2v2 was just this past July, but players are already clamoring for more of that sweet, sweet team-based action. The fans have... | Read more »
The best deals on the App Store this wee...
It seems like the week's only just started, and yet here we are with a huge pile of discounted games to sort through. There are some real doozies on sale this week. We're talking some truly stellar titles. Let's take a look at four of the best... | Read more »
Cat Quest Guide - How to become a purrfe...
Cat Quest is an absolutely charming open-world RPG that's taken the gaming world quite by storm. This game about a world populated by furry kitty warriors is actually a full-length RPG with sturdy mechanics and a lovely little story. It's certainly... | Read more »
Silly Walks Guide - How to strut your st...
Silly Walks is an all new adventure game that lives up to its name. It sees you playing as a variety of snack foods as you teeter-totter your way to rescue your friends from the evil blender and his villainous minions. It's all very . . . well... | Read more »
The best mobile point-and-click adventur...
Nostalgia for classic point-and-click adventure games has reached an all-time high in recent years, and the rise of mobile games have provided a perfect platform for this old-school genre. This week we're going to take a look at some of the best... | Read more »

Price Scanner via MacPrices.net

New iOS 11 Productivity Features Welcome But...
The iOS community is in late summer holding mode awaiting the September arrival of the iPhone 8 and iOS 11. iOS 11 public betas have been available for months — number six was released this week —... Read more
Samsung Electronics Launches New Portable SSD...
Samsung Electronics America, Inc. has announced the launch of Samsung Portable SSD T5 – its newest portable solid state drive (PSSD) that raises the bar for the performance of external memory... Read more
TrendForce Reports YoY Gain of 3.6% for 2Q17...
Market research firm TrendForce reports that the global notebook shipments for this second quarter registered a sequential quarterly increase of 5.7% and a year-on-year increase of 3.6%, totaling 39.... Read more
Sale! 10-inch iPad Pros for $50 off MSRP, no...
B&H Photo has 10.5″ iPad Pros in stock today and on sale for $50 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $599, save $... Read more
Sale! 2017 13-inch Silver 2.3GHz MacBook Pro...
Amazon has new 2017 13″ 2.3GHz/128GB Silver MacBook Pro on sale today for $100 off MSRP including free shipping. Their price is the lowest available for this model from any reseller: – 13″ 2.3GHz/... Read more
WaterField Unveils Collaboratively-Designed,...
In collaboration with customers and seasoned travelers, San Francisco maker WaterField Designs set out to create the preeminent carry-on system to improve the experience of frequent fliers. The... Read more
Miya Notes Mac-Client for Google Keep (Launch...
MacPlus Software has announced te launch of Miya Notes for Google Keep 1.0, a powerful Mac-client for Google Keep. Millions of people use Google Keep on their phones and online, but a convenient Mac... Read more
Apple refurbished iMacs available starting at...
Apple has previous-generation Certified Refurbished 2015 21″ & 27″ iMacs available starting at $849. Apple’s one-year warranty is standard, and shipping is free. The following models are... Read more
2017 13-inch MacBook Airs on sale for $100 of...
B&H Photo new 2017 13″ MacBook Airs on sale today for $100 off MSRP, starting at $899: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100 off MSRP – 13″ 1.8GHz/256GB MacBook Air (MQD42LL/A... Read more
12-inch MacBooks on sale for $100 off MSRP
Amazon has 2017 12″ Retina MacBooks on sale for $100 off MSRP. Shipping is free: 12″ 1.2GHz Space Gray MacBook: $1199.99 $100 off MSRP 12″ 1.2GHz Silver MacBook: $1198 $101 off MSRP 12″ 1.2GHz Gold... Read more

Jobs Board

*Apple* Customer Experience (ACE) Leader - A...
…management to deliver on business objectivesTraining partner store staff on Apple products, services, and merchandising guidelinesCoaching partner store staff on Read more
*Apple* Solutions Consultant (ASC) - Poole -...
Job Summary The people here at Apple don't just create products - they create the kind of wonder that's revolutionised entire industries. It's the diversity of those Read more
Business Development Manager, *Apple* iClou...
Job Summary Apple is seeking an entrepreneurial person to help grow the Apple iCloud business, a service that is integral to the Apple customer experience. Read more
Product Metrics Manager - *Apple* Media Pro...
Job Summary Apple is seeking a product manager responsible for overseeing the instrumentation and analysis of usage data, in order to make data driven product Read more
iOS Wallet & *Apple* Pay Engineer - App...
Job Summary The iOS Apple Pay & Wallet team is looking for talented,...now add credit and debit cards to Wallet using Apple Pay. You can use Apple Pay in Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.