hp41programs

DataSmoothing

Data Smoothing for the HP-41


Overview
 

 1°)  Least-Squares Parabola
 2°)  Smoothing & Differentiation
 3°)  Moving Window Average
 

-We assume that the set of n data points
 

       x1        x2    ...........        xn
       y1        y2    ...........        yn

 verifies   h = xk+1 - xk = Constant  ( equally-spaced abscissas )
 

1°)  Least-Squares Parabola
 

-Given a set of n data points  y1 , y2 , ............. , yn  we want to smooth noisy data.
-The following program uses a 5-point least-squares-parabola and replaces each  yk  by the value  zk  of this quadratic polynomial at this point.

  Formulae:

   zk = (1/35) ( -3 yk-2 + 12 yk-1 + 17 yk + 12 yk+1 - 3 yk+2 )

   z1 = (1/35) ( 31 y1 + 9 y2 - 3 y3 - 5 y4 + 3 y5 )                     and 2 similar expressions
   z2 = (1/35) ( 9 y1 + 13 y2 + 12 y3 + 6 y4 - 5 y5 )                   for zn-1  and  zn
 

Data Registers:           •  R00 = n > 4                                ( Registers R00 thru Rnn are to be initialized before executing "SMOOTH" )

                                      •  R01 = y1  •  R02 = y2  .......................  •  Rnn = yn                 Rnn+1 & Rnn+2:  temp

   >>>>  when the program stops:     R01 = z1   R02 = z2  .......................  Rnn = zn

Flags: /
Subroutines: /
 
 

 01  LBL "SMOOTH"
  02  RCL 00
  03  STO M
  04  31
  05  RCL IND Y
  06  *
  07  9
  08  LASTX
  09  *
  10  DSE M
  11  RCL IND M
  12  13
  13  *
  14  +
  15  X<>Y
  16  RCL IND M
  17  9
  18  *
  19  +
  20  DSE M
  21  RCL IND M
  22  3
  23  *
  24  -
  25  X<>Y
  26  RCL IND M
  27  12
  28  *
  29  +
  30  DSE M
  31  RCL IND M
  32  6
  33  *
  34  +
  35  X<>Y
  36  RCL IND M      
  37  5
  38  *
  39  -
  40  DSE M
  41  RCL IND M
  42  3
  43  *
  44  +
  45  X<>Y
  46  RCL IND M
  47  5
  48  ST+ M
  49  *
  50  -
  51  35
  52  ST/ Z
  53  /
  54  STO IND M
  55  ISG M
  56  CLX
  57  X<>Y
  58  STO IND M
  59  RCL 00
  60  STO M
  61  LBL 01
  62  RCL IND X       
  63  3
  64  *
  65  DSE Y
  66  RCL IND Y
  67  12
  68  *
  69  X<>Y
  70  -
  71  DSE Y
  72  RCL IND Y
  73  17
  74  *
  75  +
  76  DSE Y
  77  RCL IND Y
  78  12
  79  *
  80  +
  81  DSE Y
  82  RCL IND Y
  83  3
  84  *
  85  -
  86  35
  87  /
  88  X<> IND M       
  89  STO N
  90  DSE M
  91  4
  92  RCL M
  93  X>Y?
  94  GTO 01
  95  RCL 01
  96  9
  97  *
  98  RCL 02
  99  13
100  *
101  +
102  RCL 03
103  12
104  *
105  +
106  RCL 04
107  6
108  *
109  +
110  RCL N
111  5
112  *
113  -
114  RCL 01
115  31
116  *
117  RCL 02             
118  9
119  *
120  +
121  RCL 04
122  5
123  *
124  -
125  RCL N
126  RCL 03
127  -
128  3
129  *
130  +
131  35
132  ST/ Z
133  /
134  STO 03
135  X<>Y
136  STO 04
137  3.001
138  RCL 00
139   E6
140  /
141  +
142  REGMOVE
143  CLA
144  END

 
   ( 210 bytes / SIZE nnn+3 )
 
 

      STACK        INPUTS      OUTPUTS
           X             /             /

 
Example:    Smooth the following data
 
 

     x      1      2      3      4      5      6      7      8      9     10
     y   0.071   0.613   1.112   1.395   1.511   1.795   1.944   2.141   2.153   2.334

 
-Store the ten yk  into registers R01 thru R10
-Store the number of data points ( i-e 10 ) into R00 and XEQ "SMOOTH"  The results - in R01 thru R10 - are:
 
 

     z   0.055   0.650   1.093   1.370   1.566   1.753   1.980   2.091   2.211   2.314

 
-The first array was obtained by adding random "errors" between -0.1 and +0.1 to  Y = Ln x
 
 

     Y   0.000   0.693   1.099   1.386   1.609   1.792   1.946   2.079   2.197   2.303

 
-So, we can compare the root-mean-square errors:          RMS error of yk = 0.053      ,      RMS error of zk = 0.032
 

2°)  Smoothing & Differentiation
 

-The formulae used in "Numerical Differentiation for the HP-41" produce accurate results when the data are exact.
-But if there are roundoff or observational errors, data smoothing may give better estimations of dy/dx

-The following routine also uses a 5-point least-squares-quadratic polynomial to calculate the derivatives.
 

  Formulae:

   y'k ~ (1/10.h) ( -2 yk-2 - yk-1 + yk+1 + 2 yk+2 )                                    where  h = xk+1 - xk

   y'1 ~ (1/70.h) ( -54 y1 + 13 y2 + 40 y3 + 27 y4 - 26 y5 )                     and 2 similar expressions
   y'2 ~ (1/70.h) ( -34 y1 + 3 y2 + 20 y3 - 17 y4 - 6 y5 )                          for y'n-1  and  y'n
 

Data Registers:           •  R00 = n > 4                                        ( Registers R00 thru Rnn are to be initialized before executing "SMDV" )

                                      •  R01 = y1  •  R02 = y2  .......................  •  Rnn = yn                 Rnn+1 & Rnn+2:  temp

   >>>>  when the program stops:     R01 = y'1   R02 = y'2  .......................  Rnn = y'n

Flags: /
Subroutines: /
 
 

  01  LBL "SMDV"
  02  10
  03  *
  04  STO O
  05  RCL 00
  06  STO M
  07  34
  08  RCL IND Y
  09  *
  10  54
  11  LASTX
  12  *
  13  DSE M
  14  RCL IND M
  15  13
  16  *
  17  -
  18  X<>Y
  19  RCL IND M
  20  3
  21  *
  22  -
  23  DSE M
  24  RCL IND M
  25  20
  26  *
  27  ST- Z
  28  ST- Z
  29  -
  30  DSE M
  31  RCL IND M 
  32  17
  33  *
  34  -
  35  X<>Y
  36  RCL IND M
  37  27
  38  *
  39  -
  40  DSE M
  41  RCL IND M
  42  26
  43  *
  44  +
  45  X<>Y
  46  RCL IND M
  47  6
  48  ST+ M
  49  *
  50  +
  51  7
  52  RCL O
  53  *
  54  ST/ Z
  55  /
  56  X<>Y
  57  STO IND M 
  58  DSE M
  59  X<>Y
  60  STO IND M
  61  RCL 00
  62  STO M
  63  LBL 01
  64  RCL IND X
  65  ST+ X
  66  DSE Y
  67  RCL IND Y
  68  +
  69  DSE Y
  70  DSE Y
  71  RCL IND Y
  72  -
  73  DSE Y
  74  RCL IND Y
  75  ST+ X
  76  -
  77  RCL O
  78  /
  79  X<> IND M
  80  STO N
  81  DSE M
  82  4
  83  RCL M
  84  X>Y?
  85  GTO 01
  86  RCL 02         
  87  3
  88  *
  89  RCL 01
  90  34
  91  *
  92  -
  93  RCL 03
  94  20
  95  *
  96  +
  97  RCL 04
  98  17
  99  *
100  +
101  RCL N
102  6
103  *
104  -
105  RCL 02
106  13
107  *
108  RCL 01
109  54
110  *
111  -
112  RCL 03
113  40
114  *
115  +
116  RCL 04         
117  27
118  *
119  +
120  RCL N
121  26
122  *
123  -
124  7
125  RCL O
126  *
127  ST/ Z
128  /
129  STO 03
130  X<>Y
131  STO 04
132  3.001
133  RCL 00
134   E6
135  /
136  +
137  REGMOVE
138  CLA
139  END

 
   ( 213 bytes / SIZE nnn+3 )
 
 

      STACK        INPUTS      OUTPUTS
           X             h             /

    where  h = xk+1 - xk

Example:    With the same data, evaluate y'(1) , y'(2) , .............. , y'(10)
 
 

     x      1      2      3      4      5      6      7      8      9     10
     y   0.071   0.613   1.112   1.395   1.511   1.795   1.944   2.141   2.153   2.334

-Store the ten yk  into registers R01 thru R10
-Store the number of data points ( i-e 10 ) into R00

  h = 1  XEQ "SMDV"  The results - in R01 thru R10 - are:
 

   y'(x)   0.671   0.519   0.366   0.276   0.206   0.193   0.163   0.129   0.111   0.094

-The exact values should be 1/x  i-e:
 

   y'(x)      1   0.500   0.333   0.250   0.200   0.167   0.143   0.125   0.111   0.100

-The accuracy is relatively good - except  y'(1) !
-If we use a collocation polynomial, for instance the 5-point formula:     y'k ~ (1/12.h) (  yk-2 - 8 yk-1 + 8 yk+1 - yk+2 )

  it yields:   y'(3) ~ 0.401   y'(4) ~ 0.168   y'(5) ~ 0.197   y'(6) ~ 0.227  y'(7) ~ 0.177   y'(8) ~ 0.094

-All these values are much less accurate except y'(5)
 

3°)  Moving Window Average
 
 

-Given n values   y1 , y2 , ............. , yn  and  k coefficients   c1 , c2 , ....... , ck ,
  "MWAV" computes   z1 , z2 , ............. , zm  where the z's  are defined by

         z1 = ( c1 y1 + ............ + ck yk ) / c
         z2 = ( c1 y2 + ............ + ck yk+1 ) / c

          .................................................................                    with  c =  c1 + ............ + ck   ( we assume that c # 0 )

        zm = ( c1 yn-k+1 + ............ + ck yn ) / c
 
 

Data Registers:              R00 = c                     ( Registers Rbb thru Ree & Rbb' thru Ree' are to be initialized before executing "MWAV" )

                                         R01 = bbb.eee
                                         R02 = bbb.eee'           R04-R05-R06: temp
                                         R03 = bbb.eee"

                                      •  Rbb = y1  •  Rbb+1 = y2  .......................  •  Ree = yn
                                      •  Rbb' = c1 •  Rbb'+1 = c2  .........  •  Ree' = ck

   >>>>  when the program stops:     Rbb" = z1   Rbb"+1 = z2  .......................  Ree" = zm

Flags:  /
Subroutines:  /

-If you want that this routine also works when  c = 0  ( for numerical differentiation ) ,  add   X=0?   SIGN   after line 47
-Lines 50-51 may be replaced by   CLX   SIGN   ST+ 05   ( slightly faster )
 
 

01  LBL "MWAV"
02  STO 03
03  RDN
04  STO 02
05  INT
06  X<>Y
07  STO 01
08  INT
09  STO 05
10  -
11  RCL 03
12  +
13   E3
14  /
15  RCL 01          
16  FRC
17  RCL 02
18  FRC
19  -
20  +
21  RCL 03
22  +
23  STO 03
24  STO 04
25  RCL 02
26  0
27  LBL 00
28  RCL IND Y
29  +
30  ISG Y
31  GTO 00
32  STO 00          
33  LBL 01
34  RCL 02
35  RCL 05
36  STO 06          
37  CLX
38  LBL 02
39  RCL IND Y
40  RCL IND 06
41  *
42  +
43  ISG 06
44  CLX
45  ISG Y
46  GTO 02
47  RCL 00          
48  /
49  STO IND 04
50  ISG 05
51  CLX
52  ISG 04
53  GTO 01
54  RCL 03
55  END

 
   ( 77 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Z        bbb.eee             /
           Y        bbb.eee'            zm
           X           bbb"       bbb.eee"

        bbb.eee  is the control number of the y's
        bbb.eee' is the control number of the c's                                           All the  bbb's > 006
        bbb"  is the first register of the block that will contain the z's

Example:

    { y } = {  1  2  5  9  14  16  13  9  4  1  0 }    that we store in registers  R12  R13 ..................  R22
    { c } = {  1  3  4  1  1 }                                  that we store in registers  R07  R08 ..................  R11

-If we choose  bbb" = 31

      12.022   ENTER^
       7.011    ENTER^
         31       XEQ "MWAV"   >>>>   31.037   --- in 15 seconds ---

-And we have in registers R31 to R37:    { z } = { 5  8.3  11.7  13.7  12.7  9.6  5.7 }

Notes:

-These smoothing filters are defined by  zi = wi-L yi-L + wi-L+1 yi-L+1 + ....... + wi yi + ........... + wi+R-1 yi+R-1 + wi+R yi+R    ( wj = cj/c )
  L is the number of points used to the left of yi
  R is the number of points used to the right of yi

-So, you can interpret the results according to your choice:    { 5  8.3  11.7  13.7  12.7  9.6  5.7 }

    may represent the smoothed values of  { 14  16  13  9  4  1  0  }  if  R = 0  ( causal filters )
                     or  the smoothed values of  {  1  2  5  9  14  16  13 }  if  L = 0
                     or  the smoothed values of  {  5  9  14  16  13  9  4 }  if  L = R

  and 2 other possibilities in this example.

-Usually, the "moving window averaging" assumes that all cj's = 1, but this program is more general.

-With n = 100 & k = 9 , execution time = 5mn13s
-You can choose bbb" = bbb ,  the y-values will be gradually overwritten but the z-values will be correctly calculated.
-So, a set of 300 data points may be smoothed in about 16 minutes.

-The variant below uses synthetic registers to increase the number of data registers available:
 

Data Registers:              R00 = c                     ( Registers Rbb thru Ree & Rbb' thru Ree' are to be initialized before executing "MWAV" )

                                      •  Rbb = y1  •  Rbb+1 = y2  .......................  •  Ree = yn
                                      •  Rbb' = c1 •  Rbb'+1 = c2  .........  •  Ree' = ck

   >>>>  when the program stops:     Rbb" = z1   Rbb"+1 = z2  .......................  Ree" = zm

Flags: /
Subroutines: /

-If you want that this routine also works when  c = 0  ( for numerical differentiation ) ,  add   X=0?   SIGN   after line 45
-Lines 48-49 may be replaced by   CLX   SIGN   ST+ M   ( slightly faster )
 
 

01  LBL "MWAV"
02  RDN
03  STO N
04  INT
05  X<>Y
06  STO Z
07  INT
08  STO M
09  -
10  R^
11  +
12   E3
13  /
14  X<>Y
15  FRC
16  +
17  RCL N           
18  STO T
19  FRC
20  -
21  +
22  STO O
23  STO P
24  CLX
25  LBL 00
26  RCL IND Y   
27  +
28  ISG Y
29  GTO 00
30  STO 00
31  LBL 01
32  RCL N
33  RCL M
34  STO Q
35  CLX
36  LBL 02
37  RCL IND Y
38  RCL IND Q   
39  *
40  +
41  ISG Q
42  CLX
43  ISG Y
44  GTO 02
45  RCL 00
46  /
47  STO IND P   
48  ISG M
49  CLX
50  ISG P
51  GTO 01
52  RCL O
53  CLA
54  END

 
   ( 87 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Z        bbb.eee             /
           Y        bbb.eee'            zm
           X           bbb"       bbb.eee"

      bbb.eee  is the control number of the y's
      bbb.eee' is the control number of the c's                                           All the  bbb's > 000
      bbb"  is the first register of the block that will contain the z's

-Of course, the same example gives the same results, but we can choose  bbb = 1
 

References:

[1]  F. Scheid -  "Numerical Analysis" - Mc Graw Hill   ISBN 07-055197-9
[2]  Press , Vetterling , Teukolsky , Flannery - "Numerical Recipes in C++" - Cambridge University Press - ISBN  0-521-75033-4