an automated linear least squares solution generator - alpheratz

22
An Automated Linear Least Squares Solution Generator Marc A. Murison Astronomical Applications Department U.S. Naval Observatory Washington, DC [email protected] http://aa.usno.navy.mil/murison/ 26 May, 1999 1. Introduction In day-to-day work, one often has need to perform a quick linear least squares calculation for some model which approximates a physical process. Since the model is likely to be something other than simple linear regression, one winds up (often re-) deriving the appropriate normal equations and solving for the model parameters. This is wasted effort, thanks to the availability of computer algebra systems, in which it is easy to automate this process. In the section which follows, I illustrate the basic "quick and dirty" linear least squares process by means of a simple example. In section 3, I present a Maple procedure that performs the algebra autmatically for any model that is linear in the parameters, and in section 4 are a few examples of its usage. 2. A Linear Least Squares Example Start with a simple second degree polynomial as our model: := model A Bt i Ct i 2 . Then the χ 2 statistic is = χ 2 = i 1 N ( ) - y i model 2 . = χ 2 = i 1 N - - - y i A Bt i Ct i 22 where the sum is over N available data points, and the y i are the data values, measured at times t i . In keeping with the "quick and dirty" premise, we do not take into account a priori any weighting of the data. It is a simple matter to add weight factors into the solutions afterwards; including them now would serve only to clutter up the notation. Page 1

Upload: others

Post on 03-Feb-2022

3 views

Category:

Documents


0 download

TRANSCRIPT

An Automated Linear Least Squares Solution Generator

Marc A. Murison

Astronomical Applications Department U.S. Naval Observatory

Washington, [email protected] http://aa.usno.navy.mil/murison/

26 May, 1999

1. Introduction

In day-to-day work, one often has need to perform a quick linear least squares calculation for some model which approximates a physical process. Since the model is likely to be something other than simple linear regression, one winds up (often re-) deriving the appropriate normal equations and solving for the model parameters. This is wasted effort, thanks to the availability of computer algebra systems, in which it is easy to automate this process. In the section which follows, I illustrate the basic "quick and dirty" linear least squares process by means of a simple example. In section 3, I present a Maple procedure that performs the algebra autmatically for any model that is linear in the parameters, and in section 4 are a few examples of its usage.

2. A Linear Least Squares Example

Start with a simple second degree polynomial as our model: := model + + A B ti

C ti

2. Then the χ

2

statistic is = χ2 ∑

= i 1

N( ) − y

imodel

2.

= χ2 ∑ = i 1

N

− − − y

iA B t

iC t

i

2 2

where the sum is over N available data points, and the yi are the data values, measured at times t

i. In

keeping with the "quick and dirty" premise, we do not take into account a priori any weighting of the data. It is a simple matter to add weight factors into the solutions afterwards; including them now would serve only to clutter up the notation.

Page 1

Next, we calculate the partial derivatives of χ2 with respect to the model parameters, setting these

derivatives to zero and thus forming the normal equations.

= ∂∂A

( )rhs % 0

= ∂∂B

( )rhs %% 0

= ∂

C( )rhs %%% 0

= ∑ = i 1

N

− + + + 2 y

i2 A 2 B t

i2 C t

i

20

= ∑ = i 1

N

−2

− − − y

iA B t

iC t

i

2ti

0

= ∑ = i 1

N

−2

− − − y

iA B t

iC t

i

2ti

20

:= NormalEqs { }, ,% %% %%%

Finally, we solve the normal equations for the parameter values. These values are the linear least squares solution.

:= sols ( )sortsols ,( )solve ,( )value NormalEqs { }, ,A B C [ ], ,A B C

for in do odp sols ( )print p

A

= i 1

Nyi

= i 1

Nti

3 2

= i 1

Nyi

= i 1

Nti

4

= i 1

Nti

2

= i 1

Nti

= i 1

Nti

yi

= i 1

Nti

4 − +

=

= i 1

Nti

= i 1

Nti

3

= i 1

Nti

2yi

= i 1

Nti

2

= i 1

Nti

3

= i 1

Nti

yi

− −

= i 1

Nti

2 2

= i 1

Nti

2yi

+ 2

= i 1

Nti

= i 1

Nti

2

= i 1

Nti

3N

= i 1

Nti

3 2− +

= i 1

Nti

2 3

= i 1

Nti

4

= i 1

Nti

2

= i 1

Nti

4N

= i 1

Nti

2 + + −

B

= i 1

Nti

4

= i 1

Nyi

= i 1

Nti

= i 1

Nti

= i 1

Nti

2yi

= i 1

Nti

2 −

=

= i 1

Nti

yi

N

= i 1

Nti

4

= i 1

Nyi

= i 1

Nti

2

= i 1

Nti

3N

= i 1

Nti

3

= i 1

Nti

2yi

− − +

Page 2

= i 1

Nti

2 2

= i 1

Nti

yi

+ 2

= i 1

Nti

= i 1

Nti

2

= i 1

Nti

3N

= i 1

Nti

3 2− +

= i 1

Nti

2 3

= i 1

Nti

4

= i 1

Nti

2

= i 1

Nti

4N

= i 1

Nti

2 + + −

C

= i 1

Nti

= i 1

Nti

2

= i 1

Nti

yi

N

= i 1

Nti

3

= i 1

Nti

yi

− +

=

= i 1

Nti

3

= i 1

Nyi

= i 1

Nti

= i 1

Nti

2yi

= i 1

Nti

2

= i 1

Nti

2yi

N

= i 1

Nti

2 − + −

= i 1

Nti

2 2

= i 1

Nyi

+ 2

= i 1

Nti

= i 1

Nti

2

= i 1

Nti

3N

= i 1

Nti

3 2− +

= i 1

Nti

2 3

= i 1

Nti

4

= i 1

Nti

2

= i 1

Nti

4N

= i 1

Nti

2 + + −

This is a bit easier to look at if we make a few substitutions.

subs , ,

seq , = ∑

= i 1

Nti

kT

k = k .. 1 4

seq , = ∑

= i 1

Nyi

ti

kSk

= k .. 0 2 sols

= A

− + − − + S0

T3

2S

0T

4T

2T

1S

1T

4T

1T

3S2

T2

T3

S1

T22

S2

− + + + − 2 T1

T2

T3

N T3

2T

2

3T

4T

1

2T

4N T

2

,

= B

− − − + + T4

S0

T1

T1

S2

T2

S1

N T4

S0

T2

T3

N T3

S2

T2

2S1

− + + + − 2 T1

T2

T3

N T3

2T

2

3T

4T

1

2T

4N T

2

,

= C

− + − + − + T1

T2

S1

N T3

S1

T3

S0

T1

S2

T12

S2

N T2

T2

2S0

− + + + − 2 T1

T2

T3

N T3

2T

2

3T

4T

1

2T

4N T

2

Collecting on the mixed terms Sk, we have the result

( )collect , ,% [ ],( )seq ,Sk

= k .. 0 2 N factor

for in do odp % ( )print p

Page 3

A

− T

3

2T

4T

2S0

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 =

( )− + T3

T2

T1

T4

S1

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

− T

22

T1

T3

S2

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

B

( )− + T3

T2

T1

T4

S0

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 =

− + N T

4T

2

2S1

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

( ) − N T3

T1

T2

S2

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

C

− T

22

T1

T3

S0

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 =

( ) − N T3

T1

T2

S1

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

− T

1

2N T

2S2

− + +

− T

3

2T

4T

2N 2 T

1T

2T

3T

2

3T

4T

1

2 +

3. An Automated Linear Least Squares Solution Generator

Here is a procedure that automates the process outlined in the example of the previous section.

#---------------------------------------------------------------------

Page 4

# model must be of the form Y = F(t[k],P), where P are parameters # and t is the independent variable. The sumindex subscript [k] MUST # be attached to t in the model equation. For example, # leastsqrs( y=a+b*x[k], x, k, [a,b] ); # Also valid is # leastsqrs( y[k]=a+b*x[k], x, k, [a,b] ); #--------------------------------------------------------------------- leastsqrs := proc( model::`=`, indepvar::name, sumindex::name, params::list ) local chi2, y, i, t, partials, k, eqs, solset, T, Y, replace_denominators, sums, YTsums, n, p, nmax, N, Tcount, Scount, ispoly, Delta, delta, tmp, goodsols; global _subslist, time0; if not has(model,sumindex) then ERROR("model must be of the form Y=F(t[i],P)"); fi; time0 := time(); i := sumindex; t := indepvar; if not type(t,indexed) then t := t[i]; fi; y := lhs(model); if not type(y,indexed) then y := y[i]; fi; chi2 := Sum((y-rhs(model))^2,i=1..N); if type(rhs(model),polynom) then ispoly := true; else ispoly := false; fi; debug_print(procname,"i,t,y,ispoly,chi2",4,i,t,y,ispoly,chi2); #----------------------- # calculate the partials #----------------------- debug_print(procname,"Forming the normal equations...",3); partials := []; for k from 1 to nops(params) do partials := [ op(partials), diff(chi2,params[k])=0 ]; od; if printlevel >= 4 then debug_print(procname,"partials",4); for p in partials do print(p); od; fi; #------------------------------------------- # form the summation substitutions variables #------------------------------------------- sums := convert( select( (x,y)->op(0,x)=y,

Page 5

indets(value(expand(partials)),function), sum ), list ); #degree() can't handle summation subscripts, so remove them YTsums := subs( t=T, y=Y, sums ); _subslist := []; nmax := 0; debug_print(procname,"summation terms",4,sums); debug_print(procname,"YT terms",5,YTsums); Tcount := 0; Scount := 0; for k from 1 to nops(YTsums) do if ispoly then select(has,[op(YTsums[k])],T); if %=[] then n := 0; else n := degree( op(%), T ); fi; nmax := max(n,nmax); fi; if has(YTsums[k],Y) then if not ispoly then n := Scount; nmax := max(n,nmax); Scount := Scount + 1; fi; _subslist := [op(_subslist),sums[k]='S'[n]]; else if not ispoly then n := Tcount; Tcount := Tcount + 1; fi; _subslist := [op(_subslist),sums[k]='T'[n]]; fi; od; #--------------------------------------------------- # substitute for the summation terms in the partials #--------------------------------------------------- partials := collect( eval( value(expand(partials)), _subslist ), [seq(S[k],k=1..nmax),N], factor ); #put substitution list into form suitable for putting the sums back _subslist := map( (x)->rhs(x)=lhs(x), _subslist ); #-------------------------- # form the normal equations #-------------------------- eqs := collect( partials, [op(params),sum], factor ); if printlevel >= 1 then debug_print(procname,"normal equations",1); for p in eqs do print(p); od; fi; #---------------------------

Page 6

# solve the normal equations #--------------------------- debug_print(procname,"Solving the normal equations...",1); _EnvAllSolutions := true; map( allvalues, [solve( convert(eqs,set), convert(params,set) )] ); map( sortsols, %, params ); if nops(%)=1 then solset := op(%); else solset := %; debug_print(procname,"There are ".(nops(solset))." solutions",1); fi; debug_print(procname,"raw solution(s)",4,solset); #--------------------------------------------------- # replace the denominators with another substitution #--------------------------------------------------- #first define a workhorse procedure replace_denominators := proc( expr, N, nmax, S, Delta ) local k, p, d; global _subslist; #--------------------------------- # determine the common denominator #--------------------------------- #grab and filter denominators from solution parameter expressions map( denom, { seq(op(rhs(expr[k])),k=1..nops(expr)) } ); map( (x)->if type(x,{integer,fraction}) then 0 else x fi, % ); d := % minus {0}; if nops(d) > 1 then debug_print(procname,"denominator set",0,d); ERROR("Unable to determine a unique denominator!"); elif d={} then debug_print(procname,"no denominator for solution",2,expr); RETURN(expr); else d := op(d); fi; #-------------------------------------- # make the substitution in the solution #-------------------------------------- _subslist := [ Delta=eval(d,_subslist), op(_subslist) ]; collect( algsubs(d=Delta,expr), [Delta,seq(S[k],k=0..nmax),N], factor ); end; #now make the substitutions if type(solset,list(list)) then #multiple solutions for k from 1 to nops(solset) do subsop(k=replace_denominators(solset[k],N,nmax,S,Delta),solset); solset := subs( Delta=delta[k], % ); _subslist := subs( Delta=delta[k], _subslist ); od; else #only one solution solset := replace_denominators(solset,N,nmax,S,Delta);

Page 7

fi; debug_print(procname,"substitution list",2,_subslist); #---------------------- # check the solution(s) #---------------------- if type(solset,list(list)) then #multiple solutions debug_print(procname,"Verifying the ".(nops(solset))." solutions...",1); goodsols := []; for k from 1 to nops(solset) do tmp := expand(subs(_subslist,eval(eqs,solset[k]))); if not type(tmp,list(0=0)) then debug_print(procname,"Solution ".k." is invalid!",0,solset[k]); debug_print(procname,"Solution ".k." substituted into normal eqs",0,eqs); debug_print(procname,"Throwing out solution ".k,0); else goodsols := [op(goodsols),solset[k]]; fi; od; solset := goodsols; if nops(solset)=1 then solset := op(solset); fi; else #single solution debug_print(procname,"Verifying the solution...",1); eqs := factor(expand(subs(_subslist,eval(eqs,solset)))); if not type(eqs,list(0=0)) then debug_print(procname,"Solution substituted into normal eqs",0,eqs); ERROR("Invalid solution!"); fi; fi; if time()-time0 > 10 then debug_print(procname,"Done!",1); fi; solset; end:

4. Examples

Polynomial of degree 1

We start with simple linear regression to check the program. We set the procedure's "chattiness" to maximum verbosity. The solution appears as the last bracketed expression.

:= printlevel 4

( )leastsqrs , , , = y + A B ti

t i [ ],A B

leastsqrs[0]: i,t,y,ispoly,chi2

, , , ,i ti

yi

true ∑ = i 1

N( ) − − y

iA B t

i

2

Page 8

leastsqrs[0]: Forming the normal equations...leastsqrs[0]: partials

= ∑ = i 1

N( )− + + 2 y

i2 A 2 B t

i0

= ∑ = i 1

N( )−2 ( ) − − y

iA B t

iti

0

leastsqrs[0]: summation terms

, , ,∑

= i 1

Nyi

∑ = i 1

Nti

yi

∑ = i 1

Nti

∑ = i 1

Nti

2

leastsqrs[0]: normal equations

= − + + 2 S0

2 A N 2 B T1

0

= − + + 2 S1

2 A T1

2 B T2

0

leastsqrs[0]: Solving the normal equations...leastsqrs[0]: raw solution(s)

, = A

− S0

T2

T1

S1

− + T1

2T

2N

= B −− + S

1N T

1S0

− + T1

2T

2N

leastsqrs[0]: substitution list

, , , , = ∆ − +

∑ = i 1

Nti

2

∑ = i 1

Nti

2N = S

0∑

= i 1

Nyi

= S1

∑ = i 1

Nti

yi

= T1

∑ = i 1

Nti

= T2

∑ = i 1

Nti

2

leastsqrs[0]: Verifying the solution...

, = A

− S0

T2

T1

S1

∆ = B

− S1

N T1

S0

The substitutions are stored in the global variable _subslist. Hence, the full solution is

( )eval ,% _subslist

, = A

= i 1

Nyi

= i 1

Nti

2

= i 1

Nti

= i 1

Nti

yi

− +

= i 1

Nti

2

= i 1

Nti

2N

= B

= i 1

Nti

yi

N

= i 1

Nti

= i 1

Nyi

− +

= i 1

Nti

2

= i 1

Nti

2N

We can convert the solution into an optimized Maple procedure. This procedure can then be used to evaluate the model with a set of data. It is easily saved to disk for conversion into a C or fortran procedure — also quite easy.

:= tmp ( )array ( )map , → x ( )rhs x %

Page 9

:= foo ( )optimize ( )makeproc ,tmp = parameters [ ], ,N y t

foo , ,N y tproc( ) :=

local ;, , , , , ,t8 t11 t4 t5 t1 tmp t2

:= tmp ( )array .. 1 2 ;

:= t1 ( )sum ,[ ]y i = i .. 1 N ;

:= t2 ( )sum ,^[ ]t i 2 = i .. 1 N ;

:= t4 ( )sum ,[ ]t i = i .. 1 N ;

:= t5 ( )sum ,∗[ ]t i [ ]y i = i .. 1 N ;

:= t8 ^t4 2;

:= t11 / ( )1 − + t8 ∗t2 N ;

:= [ ]tmp 1 ∗( ) − ∗t1 t2 ∗t4 t5 t11;

:= [ ]tmp 2 ∗( ) − ∗t5 N ∗t4 t1 t11;

tmp

end

( )writeto "d:/Maple/test.p"

( )print foo

( )writeto terminal

This is simple and straightforward in this example. Later on, we will see that the solutions can get rather unwieldy, but that the optimized procedures created from them are still relatively simple.

Polynomial of degree 2

:= printlevel 2

leastsqrs , , , = Y + + A B t

iC t

i

2t i [ ], ,A B C

leastsqrs[0]: normal equations

= − + + + 2 S0

2 A N 2 B T1

2 C T2

0

= − + + + 2 S1

2 A T1

2 B T2

2 C T3

0

= − + + + 2 S2

2 A T2

2 B T3

2 C T4

0

leastsqrs[0]: Solving the normal equations...leastsqrs[0]: substitution list

∆ 2

= i 1

Nti

= i 1

Nti

2

= i 1

Nti

3

= i 1

Nti

3 2N

= i 1

Nti

2 3

= i 1

Nti

4N

= i 1

Nti

2− + + − =

= i 1

Nti

4

= i 1

Nti

2 + = S

0∑

= i 1

NY

i = T

1∑

= i 1

Nti

= T2

∑ = i 1

Nti

2 = S

1∑

= i 1

Nti

Yi

= T3

∑ = i 1

Nti

3, , , , , ,

Page 10

= S2

∑ = i 1

Nti

2Y

i = T

4∑

= i 1

Nti

4,

leastsqrs[0]: Verifying the solution...

= A

+ +

− T

3

2T

4T

2S0

( )− + T2

T3

T1

T4

S1

− + T

3T

1T

2

2S2

∆,

= B

+ + ( )− + T2

T3

T1

T4

S0

− T

2

2T

4N S

1( )− + T

1T

2T

3N S

2

∆,

= C

+ +

− + T

3T

1T

2

2S

0( )− + T

1T

2T

3N S

1

− + T

2N T

1

2S2

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,% _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

, ,N Y tproc( )

local ;, , , , , , , , , , , , , , , ,t7 t26 t31 t12 t16 t28 t17 t13 t21 t18 t36 t4 t10 tmp t3 t1 t2

:= tmp ( )array .. 1 3 ;

:= t1 ( )sum ,^[ ]t i 3 = i .. 1 N ;

:= t2 ^t1 2;

:= t3 ( )sum ,^[ ]t i 4 = i .. 1 N ;

:= t4 ( )sum ,^[ ]t i 2 = i .. 1 N ;

:= t7 ( )sum ,[ ]Y i = i .. 1 N ;

:= t10 ( )sum ,[ ]t i = i .. 1 N ;

:= t12 − + ∗t4 t1 ∗t10 t3;

:= t13 ( )sum ,∗[ ]t i [ ]Y i = i .. 1 N ;

:= t16 ^t4 2;

:= t17 − + ∗t1 t10 t16;

:= t18 ( )sum ,∗^[ ]t i 2 [ ]Y i = i .. 1 N ;

:= t21 ∗t10 t4;

:= t26 ∗t3 N;

:= t28 ^t10 2;

:= t31 / ( )1 − ∗ + + − + 2 ∗t21 t1 ∗t2 N ∗t16 t4 ∗t26 t4 ∗t3 t28 ;

:= [ ]tmp 1 ∗( ) + + ∗( ) − t2 ∗t3 t4 t7 ∗t12 t13 ∗t17 t18 t31;

:= t36 − + t21 ∗t1 N;

:= [ ]tmp 2 ∗( ) + + ∗t12 t7 ∗( ) − t16 t26 t13 ∗t36 t18 t31;

:= [ ]tmp 3 ∗( ) + + ∗t17 t7 ∗t36 t13 ∗( )− + ∗t4 N t28 t18 t31;

tmp

Page 11

end

Polynomial of degree 3

In this example, we will not show the solution, since it is a bit unwieldy.

leastsqrs , , , = Y + + + A B t

iC t

i

2D t

i

3t i [ ], , ,A B C D

leastsqrs[0]: normal equations

= − + + + + 2 S0

2 A N 2 B T1

2 C T2

2 D T3

0

= − + + + + 2 S1

2 A T1

2 B T2

2 C T3

2 D T4

0

= − + + + + 2 S2

2 A T2

2 B T3

2 C T4

2 D T5

0

= − + + + + 2 S3

2 A T3

2 B T4

2 C T5

2 D T6

0

leastsqrs[0]: Solving the normal equations...leastsqrs[1]: substitution list

= i 1

Nti

6

= i 1

Nti

2 32

= i 1

Nti

2 2

= i 1

Nti

3

= i 1

Nti

5

= i 1

Nti

2 2

= i 1

Nti

4 2 − − =

= i 1

Nti

2

= i 1

Nti

5 2N

= i 1

Nti

2

= i 1

Nti

6

= i 1

Nti

4N + −

2

= i 1

Nti

2

= i 1

Nti

= i 1

Nti

4

= i 1

Nti

53

= i 1

Nti

2

= i 1

Nti

3 2

= i 1

Nti

4 + +

2

= i 1

Nti

2

= i 1

Nti

= i 1

Nti

6

= i 1

Nti

3

= i 1

Nti

4 3N

= i 1

Nti

6

= i 1

Nti

3 2N − + +

2

= i 1

Nti

4N

= i 1

Nti

3

= i 1

Nti

52

= i 1

Nti

= i 1

Nti

3

= i 1

Nti

4 2 − −

2

= i 1

Nti

= i 1

Nti

3 2

= i 1

Nti

5

= i 1

Nti

2

= i 1

Nti

6

= i 1

Nti

4

= i 1

Nti

2

= i 1

Nti

5 2 + + −

= i 1

Nti

3 4 − = T

6∑

= i 1

Nti

6 = T

5∑

= i 1

Nti

5 = S

0∑

= i 1

NY

i = T

2∑

= i 1

Nti

2 = T

1∑

= i 1

Nti

= T3

∑ = i 1

Nti

3, , , , , , ,

= S1

∑ = i 1

Nti

Yi

= S3

∑ = i 1

Nti

3Y

i = T

4∑

= i 1

Nti

4 = S

2∑

= i 1

Nti

2Y

i, , ,

leastsqrs[2]: Verifying the solution...

( )map ,cost %

Page 12

+ + + 21 additions 50 multiplications divisions assignments,[

+ + + 22 additions 48 multiplications divisions assignments,

+ + + 22 additions 48 multiplications divisions assignments,

+ + + 21 additions 47 multiplications divisions assignments ]

The following commands produce an optimized procedure, which we will not show here.

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,%% _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

Sinusoid — Representation 1

:= printlevel 1

( )leastsqrs , , , = Y A ( )cos + 2 π ν ti

φ t i [ ],A φ

leastsqrs[0]: normal equations

8 ( )cos φ 2 T0

8 ( )cos φ 2 T1

16 ( )cos φ ( )sin φ T2

2 ( )cos φ 2 N 8 ( )cos φ ( )sin φ T3

− − + + (

8 ( )sin φ 2 T4

+ ) A 4 ( )cos φ S0

2 ( )cos φ S1

4 ( )sin φ S2

− + + 0 =

2 ( )cos φ ( )sin φ N 8 ( )cos φ ( )sin φ T0

4 ( )cos φ 2 T3

8 ( )cos φ 2 T2

8 ( )cos φ ( )sin φ T4

− − + − + (

8 ( )cos φ ( )sin φ T1

4 ( )sin φ 2 T3

8 ( )sin φ 2 T2

+ − + ) A2

( )− + + 2 ( )sin φ S1

4 ( )cos φ S2

4 ( )sin φ S0

A + 0 =

leastsqrs[0]: Solving the normal equations...leastsqrs[2]: There are 3 solutionsleastsqrs[4]: Verifying the 3 solutions...leastsqrs[18]: Solution 2 is invalid!

A1

2sqrt 16 T

2S2

S1

T4

16 T3

S2

S0

T4

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S2

2T

3 + − − −

=

16 S0

T4

2S

116 T

2

2S

2

24 T

2S1

2T

34 T

3

2S0

S1

16 T2

S0

T3

S1

8 S2

T1

T3

S1

− + − − + +

8 S2

T0

T3

S1

32 S2

T1

T2

S0

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

− + − − −

2 S2

N T3

S1

32 S2

T0

T2

S0

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

− − + + +

4 S2

N T3

S0

16 T2

S0

2T

38 S

2

2N T

08 S

2

2N T

132 S

2

2T

0T

1S2

2N2 + − + − − +

16 S2

2T

0

216 S

2

2T

1

216 T

2

2S0

24 T

2

2S1

24 T

3

2S0

2T

3

2S1

28 S

2N T

2S

0 + + + + + + −

Page 13

4 T3

2S

2

216 S

0

2T

4

24 S

1

2T

4

2 + + +

δ

2φ arctan (

= ,

− − + + − − + S2

N 4 S2

T0

4 S2

T1

4 T2

S0

2 T2

S1

2 T3

S0

T3

S1

sqrt 16 T2

S2

S1

T4

)

16 T3

S2

S0

T4

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S2

2T

316 S

0T

4

2S1

16 T2

2S

2

2 + − − − − +

4 T2

S1

2T

34 T

32

S0

S1

16 T2

S0

T3

S1

8 S2

T1

T3

S1

8 S2

T0

T3

S1

− − + + −

32 S2

T1

T2

S0

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

2 S2

N T3

S1

+ − − − −

32 S2

T0

T2

S0

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

4 S2

N T3

S0

− + + + +

16 T2

S0

2T

38 S

22

N T0

8 S22

N T1

32 S22

T0

T1

S22

N2 16 S22

T02

16 S2

2T

12

− + − − + + +

16 T2

2S

0

24 T

2

2S

1

24 T

3

2S0

2T

3

2S1

28 S

2N T

2S0

4 T3

2S2

216 S

0

2T

4

2 + + + + − + +

4 S1

2T

4

2 +

2 − + + − 2 T

2S

2T

3S2

2 S0

T4

S1

T4

sqrt 16 T2

S2

S1

T4

16 T3

S2

S0

T4

+ ( ),

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S2

2T

316 S

0T

4

2S1

16 T2

2S2

24 T

2S

1

2T

3 − − − − + −

4 T3

2S

0S

116 T

2S

0T

3S1

8 S2

T1

T3

S1

8 S2

T0

T3

S1

32 S2

T1

T2

S0

− + + − +

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

2 S2

N T3

S1

32 S2

T0

T2

S0

− − − − −

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

4 S2

N T3

S0

16 T2

S0

2T

38 S

22

N T0

+ + + + − +

8 S2

2N T

132 S

2

2T

0T

1S2

2N2 16 S

2

2T

0

216 S

2

2T

1

216 T

2

2S0

24 T

2

2S

1

2 − − + + + + +

4 T3

2S

0

2T

3

2S

1

28 S

2N T

2S0

4 T3

2S2

216 S

0

2T

4

24 S

1

2T

4

2 + + − + + +

2 π _Z +

leastsqrs[18]: Solution 2 substituted into normal eqs

8 ( )cos φ 2 T0

8 ( )cos φ 2 T1

16 ( )cos φ ( )sin φ T2

2 ( )cos φ 2 N 8 ( )cos φ ( )sin φ T3

− − + + ([

8 ( )sin φ 2T

4 + ) A 4 ( )cos φ S

02 ( )cos φ S

14 ( )sin φ S

2 − + + 0 = 2 ( )cos φ ( )sin φ N−(,

8 ( )cos φ ( )sin φ T0

4 ( )cos φ 2T

38 ( )cos φ 2

T2

8 ( )cos φ ( )sin φ T4

8 ( )cos φ ( )sin φ T1

− + − + +

4 ( )sin φ 2T

38 ( )sin φ 2

T2

− + ) A2

( )− + + 2 ( )sin φ S1

4 ( )cos φ S2

4 ( )sin φ S0

A + 0 = ]

leastsqrs[18]: Throwing out solution 2leastsqrs[31]: Solution 3 is invalid!

Page 14

A1

2sqrt 16 T

2S

2S1

T4

16 T3

S2

S0

T4

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S2

2T

3 + − − −

− =

16 S0

T4

2S

116 T

2

2S

2

24 T

2S1

2T

34 T

3

2S0

S1

16 T2

S0

T3

S1

8 S2

T1

T3

S1

− + − − + +

8 S2

T0

T3

S1

32 S2

T1

T2

S0

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

− + − − −

2 S2

N T3

S1

32 S2

T0

T2

S0

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

− − + + +

4 S2

N T3

S0

16 T2

S0

2T

38 S

2

2N T

08 S

2

2N T

132 S

2

2T

0T

1S2

2N

2 + − + − − +

16 S2

2T

0

216 S

2

2T

1

216 T

2

2S0

24 T

2

2S1

24 T

3

2S0

2T

3

2S1

28 S

2N T

2S

0 + + + + + + −

4 T3

2S

22

16 S0

2T

42

4 S12

T42

+ + + δ

3φ arctan (−

= ,

− − + + − − + S2

N 4 S2

T0

4 S2

T1

4 T2

S0

2 T2

S1

2 T3

S0

T3

S1

sqrt 16 T2

S2

S1

T4

)

16 T3

S2

S0

T4

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S2

2T

316 S

0T

4

2S1

16 T2

2S

2

2 + − − − − +

4 T2

S1

2T

34 T

3

2S

0S

116 T

2S0

T3

S1

8 S2

T1

T3

S1

8 S2

T0

T3

S1

− − + + −

32 S2

T1

T2

S0

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

2 S2

N T3

S1

+ − − − −

32 S2

T0

T2

S0

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

4 S2

N T3

S0

− + + + +

16 T2

S0

2T

38 S

2

2N T

08 S

2

2N T

132 S

2

2T

0T

1S2

2N

216 S

2

2T

0

216 S

2

2T

1

2 − + − − + + +

16 T2

2S

0

24 T

2

2S

1

24 T

3

2S0

2T

3

2S1

28 S

2N T

2S0

4 T3

2S2

216 S

0

2T

4

2 + + + + − + +

4 S1

2T

4

2 +

2 − + + − 2 T

2S

2T

3S2

2 S0

T4

S1

T4

sqrt 16 T2

S2

S1

T4

( )−,

16 T3

S2

S0

T4

8 T3

S2

S1

T4

32 T2

S2

S0

T4

16 T2

S22

T3

16 S0

T42

S1

16 T2

2S

22

+ − − − − +

4 T2

S1

2T

34 T

3

2S

0S

116 T

2S0

T3

S1

8 S2

T1

T3

S1

8 S2

T0

T3

S1

− − + + −

32 S2

T1

T2

S0

16 S2

T1

T2

S1

16 S2

T1

T3

S0

16 T2

2S0

S1

2 S2

N T3

S1

+ − − − −

32 S2

T0

T2

S0

16 S2

T0

T2

S1

16 S2

T0

T3

S0

4 S2

N T2

S1

4 S2

N T3

S0

− + + + +

16 T2

S0

2T

38 S

2

2N T

08 S

2

2N T

132 S

2

2T

0T

1S2

2N2 16 S

2

2T

0

216 S

2

2T

1

2 − + − − + + +

Page 15

16 T2

2S

0

24 T

2

2S

1

24 T

3

2S0

2T

3

2S1

28 S

2N T

2S0

4 T3

2S2

216 S

0

2T

4

2 + + + + − + +

4 S1

2T

4

2 +

2 π _Z +

leastsqrs[31]: Solution 3 substituted into normal eqs

8 ( )cos φ 2T

08 ( )cos φ 2

T1

16 ( )cos φ ( )sin φ T2

2 ( )cos φ 2N 8 ( )cos φ ( )sin φ T

3 − − + + ([

8 ( )sin φ 2T

4 + ) A 4 ( )cos φ S

02 ( )cos φ S

14 ( )sin φ S

2 − + + 0 = 2 ( )cos φ ( )sin φ N−(,

8 ( )cos φ ( )sin φ T0

4 ( )cos φ 2 T3

8 ( )cos φ 2 T2

8 ( )cos φ ( )sin φ T4

8 ( )cos φ ( )sin φ T1

− + − + +

4 ( )sin φ 2 T3

8 ( )sin φ 2 T2

− + ) A2 ( )− + + 2 ( )sin φ S1

4 ( )cos φ S2

4 ( )sin φ S0

A + 0 = ]

leastsqrs[31]: Throwing out solution 3leastsqrs[31]: Done!

, = A 0 = φ +

arctan1

2

− 2 S0

S1

S2

π _Z

As we can see, = Y A ( )cos + 2 π ν ti

φ is not a particularly good choice of representation, since the

solution involves inverse trigonometric functions and is particularly useless ( = A 0). The next, equivalent, example leads to a useful solution.

Sinusoid — Representation 2

:= printlevel 2

( )leastsqrs , , , = Y + A ( )cos 2 π ν ti

B ( )sin 2 π ν ti

t i [ ],A B

leastsqrs[0]: normal equations

= + − + ( )− + + 8 T1

2 N 8 T0

A ( )− + 4 T3

8 T2

B 4 S2

2 S0

0

= − + ( )− + 4 T3

8 T2

A 4 S1

8 B T4

0

leastsqrs[0]: Solving the normal equations...leastsqrs[1]: substitution list

∆ 4

= i 1

N( )cos π ν t

i

4

= i 1

N( )sin π ν t

i

2( )cos π ν t

i

2 =

4

= i 1

N( )cos π ν t

i

2

= i 1

N( )sin π ν t

i

2( )cos π ν t

i

2N

= i 1

N( )sin π ν t

i

2( )cos π ν t

i

2 − +

4

= i 1

N( )cos π ν t

i

3( )sin π ν t

i

2 −

Page 16

4

= i 1

N( )sin π ν t

i( )cos π ν t

i

= i 1

N( )cos π ν t

i

3( )sin π ν t

i +

= i 1

N( )sin π ν t

i( )cos π ν t

i

2 − = S

0∑

= i 1

NY

i = T

0∑

= i 1

N( )cos π ν t

i

4 = T

1∑

= i 1

N( )cos π ν t

i

2, , , ,

= T2

∑ = i 1

N( )cos π ν t

i

3( )sin π ν t

i = T

3∑

= i 1

N( )sin π ν t

i( )cos π ν t

i, ,

= S1

∑ = i 1

NY

i( )sin π ν t

i( )cos π ν t

i = T

4∑

= i 1

N( )sin π ν t

i

2( )cos π ν t

i

2 = S

2∑

= i 1

NY

i( )cos π ν t

i

2, ,

leastsqrs[1]: Verifying the solution...

= A

− + + S0

T4

( )− + 2 T2

T3

S1

2 S2

T4

∆,

= B

+ +

− T

21

2T

3S

0

− + 2 T

02 T

11

2N S

1( )− + 2 T

2T

3S2

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,% _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

, ,N Y tproc( )

local ;, , , , , , , , , , , ,tmp t1 t2 t8 t14 t7 t6 t4 t10 t17 t21 t27 t25

:= tmp ( )array .. 1 2 ;

:= t1 ( )sum ,[ ]Y i = i .. 1 N ;

:= t2 ( )sum ,∗^( )sin ∗ ∗π ν [ ]t i 2 ^( )cos ∗ ∗π ν [ ]t i 2 = i .. 1 N ;

:= t4 ( )sum ,∗^( )cos ∗ ∗π ν [ ]t i 3 ( )sin ∗ ∗π ν [ ]t i = i .. 1 N ;

:= t6 ( )sum ,∗( )sin ∗ ∗π ν [ ]t i ( )cos ∗ ∗π ν [ ]t i = i .. 1 N ;

:= t7 − ∗ + 2 t4 t6;

:= t8 ( )sum ,∗ ∗[ ]Y i ( )sin ∗ ∗π ν [ ]t i ( )cos ∗ ∗π ν [ ]t i = i .. 1 N ;

:= t10 ( )sum ,∗[ ]Y i ^( )cos ∗ ∗π ν [ ]t i 2 = i .. 1 N ;

:= t14 ( )sum ,^( )cos ∗ ∗π ν [ ]t i 4 = i .. 1 N ;

:= t17 ( )sum ,^( )cos ∗ ∗π ν [ ]t i 2 = i .. 1 N ;

:= t21 ^t4 2;

:= t25 ^t6 2;

:= t27 / ( )1 ∗ − ∗ + − ∗ + ∗ − 4 ∗t2 t14 4 ∗t17 t2 ∗N t2 4 t21 4 ∗t6 t4 t25 ;

:= [ ]tmp 1 ∗( )− + + ∗∗t1 t2 ∗t7 t8 2 ∗t10 t2 t27;

Page 17

:= [ ]tmp 2 ∗( ) + + ∗( ) − ∗t4 / 1 2 t6 t1 ∗( )∗ − ∗ + ∗2 t14 2 t17 / 1 2 N t8 ∗t7 t10 t27;

tmp

end

Logarithm

( )leastsqrs , , , = Y + A B ( )log ti

t i [ ],A B

leastsqrs[0]: normal equations

= − + + 2 S0

2 A N 2 B T1

0

= − + + 2 S1

2 A T1

2 B T0

0

leastsqrs[0]: Solving the normal equations...leastsqrs[0]: substitution list

= ∆ − +

= i 1

N( )ln t

i

2

= i 1

N( )ln t

i

2N = S

0∑

= i 1

NY

i = T

0∑

= i 1

N( )ln t

i

2 = T

1∑

= i 1

N( )ln t

i, , , ,

= S1

∑ = i 1

N( )ln t

iY

i

leastsqrs[0]: Verifying the solution...

, = A

− S0

T0

T1

S1

∆ = B

− S1

N T1

S0

( )eval ,% _subslist

= A

= i 1

NY

i

= i 1

N( )ln t

i

2

= i 1

N( )ln t

i

= i 1

N( )ln t

iY

i

− +

= i 1

N( )ln t

i

2

= i 1

N( )ln t

i

2N

,

= B

∑ = i 1

N( )ln t

iY

iN

∑ = i 1

N( )ln t

i

∑ = i 1

NY

i

− +

= i 1

N( )ln t

i

2

= i 1

N( )ln t

i

2N

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,%% _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

, ,N Y tproc( )

local ;, , , , , ,tmp t5 t11 t4 t8 t1 t2

:= tmp ( )array .. 1 2 ;

Page 18

:= t1 ( )sum ,[ ]Y i = i .. 1 N ;

:= t2 ( )sum ,^( )ln [ ]t i 2 = i .. 1 N ;

:= t4 ( )sum ,( )ln [ ]t i = i .. 1 N ;

:= t5 ( )sum ,∗( )ln [ ]t i [ ]Y i = i .. 1 N ;

:= t8 ^t4 2;

:= t11 / ( )1 − + t8 ∗t2 N ;

:= [ ]tmp 1 ∗( ) − ∗t2 t1 ∗t4 t5 t11;

:= [ ]tmp 2 ∗( ) − ∗t5 N ∗t1 t4 t11;

tmp

end

Exponential

leastsqrs , , , = Y + A B e

ti

t i [ ],A Bleastsqrs[0]: normal equations

= − + + 2 S0

2 A N 2 B T0

0

= − + + 2 S1

2 A T0

2 B T1

0

leastsqrs[0]: Solving the normal equations...leastsqrs[0]: substitution list

= ∆ − +

= i 1

Ne

ti

2

= i 1

N

e

ti

2N = S

0∑

= i 1

NY

i = T

0∑

= i 1

Ne

ti

= S1

∑ = i 1

Ne

ti

Yi

, , , ,

= T1

∑ = i 1

N

e

ti

2

leastsqrs[0]: Verifying the solution...

, = A

− S0

T1

T0

S1

∆ = B

− S1

N T0

S0

( )eval ,% _subslist

= A

= i 1

NY

i

= i 1

N

e

ti

2

= i 1

Ne

ti

= i 1

Ne

ti

Yi

− +

= i 1

Ne

ti

2

= i 1

N

e

ti

2

N

,

Page 19

= B

= i 1

Ne

ti

Yi

N

= i 1

Ne

ti

= i 1

NY

i

− +

= i 1

Ne

ti

2

= i 1

N

e

ti

2

N

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,%% _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

, ,N Y tproc( )

local ;, , , , , ,t5 t11 t1 t2 tmp t4 t8

:= tmp ( )array .. 1 2 ;

:= t1 ( )sum ,[ ]Y i = i .. 1 N ;

:= t2 ( )sum ,^( )exp [ ]t i 2 = i .. 1 N ;

:= t4 ( )sum ,( )exp [ ]t i = i .. 1 N ;

:= t5 ( )sum ,∗( )exp [ ]t i [ ]Y i = i .. 1 N ;

:= t8 ^t4 2;

:= t11 / ( )1 − + t8 ∗t2 N ;

:= [ ]tmp 1 ∗( ) − ∗t1 t2 ∗t4 t5 t11;

:= [ ]tmp 2 ∗( ) − ∗t5 N ∗t4 t1 t11;

tmp

end

Exponentially Decaying Sinusoid

The substitution list for this case is quite long, so its output will be suppressed.

:= printlevel 1

leastsqrs , , , = Y + A e

( )−ti

( ) + B ( )cos 2 π ν ti

C ( )sin 2 π ν ti

t i [ ], ,A B C

leastsqrs[0]: normal equations

= + − + 2 A N ( ) − 4 T0

2 T2

B 2 S0

4 C T3

0

= + + − + ( ) − 4 T0

2 T2

A ( ) − + 8 T4

8 T6

2 T5

B ( )− + 4 T8

8 T7

C 4 S1

2 S2

0

= + − + 4 A T3

( )− + 4 T8

8 T7

B 4 S3

8 C T1

0

leastsqrs[0]: Solving the normal equations...leastsqrs[2]: Verifying the solution...

:= soln %

for in do odp soln ( )print p

Page 20

A

+ − − − + 4 T

7

2T

8

24 T

7T

8T

5T

14 T

4T

14 T

6T

1S0

=

( )− + + − 4 T7

T3

4 T0

T1

2 T8

T3

2 T2

T1

S1

( ) + − − T2

T1

2 T7

T3

T8

T3

2 T0

T1

S2

+ +

( )− + + − + + − 4 T3

T6

T3

T5

4 T3

T4

4 T0

T7

2 T7

T2

2 T0

T8

T2

T8

S3

+ ∆ /

B ( )− + + − 2 T7

T3

2 T0

T1

T8

T3

T2

T1

S0

− + 2 T

1N 2 T

3

2S1

− T

1N T

3

2S2

+ + =

( ) − ( )− + T8

2 T7

N T3

( ) − 2 T0

T2

S3

+ ∆ /

C

− − + + − + +

1

2T

2T

82 T

0T

7T

0T

8T

7T

22 T

3T

61

2T

3T

52 T

3T

4S0

=

( ) − ( )− + T8

2 T7

N T3

( ) − 2 T0

T2

S1

+

1

2T

8T

7N

1

2T

3( ) − 2 T

0T

2S2

+ +

+

− − 2 T

61

2T

52 T

4N

1

2( ) − 2 T

0T

2

2S3

+ ∆

/

The following commands produce an optimized procedure, which we will not show here.

:= tmp ( )array ( )map , → x ( )rhs x ( )eval ,soln _subslist

( )optimize ( )makeproc ,tmp = parameters [ ], ,N Y t

Sinusoid with Exponentially Decaying Component

:= model = Y + + + A B ( )cos 2 π ν1

ti

C ( )sin 2 π ν1

ti

e

( )−ti

( ) + D ( )cos 2 π ν2

ti

E ( )sin 2 π ν2

ti

( )leastsqrs , , ,model t i [ ], , , ,A B C D Eleastsqrs[4]: normal equations

= + + + − + 2 N A ( )− + 2 N 4 T11

B 4 C T12

( ) − 4 T13

2 T15

D 2 S3

4 E T18

0

( )− + 2 N 4 T11

A ( )− + + 8 T11

2 N 8 T3

B ( ) − 8 T6

4 T12

C + +

( )− − + + 4 T13

4 T9

2 T15

8 T7

D ( ) − 8 T10

4 T18

E 2 S3

4 S5

+ + + − 0 =

= + + + − + 4 A T12

( ) − 8 T6

4 T12

B 8 C T16

( ) − 8 T17

4 T19

D 4 S4

8 E T8

0

( ) − 4 T13

2 T15

A ( )− − + + 4 T13

4 T9

2 T15

8 T7

B ( ) − 8 T17

4 T19

C + +

( ) − + 8 T14

8 T0

2 T1

D ( ) − 8 T2

4 T4

E 4 S0

2 S1

+ + − + 0 =

= + + + − + 4 A T18

( ) − 8 T10

4 T18

B 8 C T8

( ) − 8 T2

4 T4

D 4 S2

8 E T5

0

Page 21

leastsqrs[4]: Solving the normal equations...leastsqrs[46]: Verifying the solution...leastsqrs[569]: Done!

:= soln %

As we can see, the solution for this model is quite complicated:

( )cost soln

+ + + 2188 additions 7749 multiplications 5 divisions 5 assignments

( )map ,cost soln

+ + + 789 additions 2864 multiplications divisions assignments,[

+ + + 394 additions 1382 multiplications divisions assignments,

+ + + 394 additions 1382 multiplications divisions assignments,

+ + + 217 additions 739 multiplications divisions assignments,

+ + + 394 additions 1382 multiplications divisions assignments ]

( )cost _subslist

+ + + 254 additions 1249 multiplications 1108 sums 27 assignments

( )map ,cost ( )eval ,soln _subslist

+ + + + 1043 additions 4113 multiplications 3968 sums divisions assignments,[

+ + + + 648 additions 2631 multiplications 2487 sums divisions assignments,

+ + + + 648 additions 2631 multiplications 2487 sums divisions assignments,

+ + + + 471 additions 1988 multiplications 1842 sums divisions assignments,

+ + + + 648 additions 2631 multiplications 2487 sums divisions assignments ]

However, it optimizes well:

:= optsoln ( )optimize ,soln tryhard

( )cost optsoln

+ + + + 739 additions 1061 multiplications divisions 26 subscripts 447 assignments

The following command produces an optimized procedure, which we will not show here.

( )makeproc , ,( )eval ,[ ]optsoln _subslist = parameters [ ], ,N Y t = globals [ ], , , ,A B C D E

Page 22