[18846] in s-news-athena
[S] summary: kalman filter in splus
daemon@ATHENA.MIT.EDU (Verena RESSEL)
Wed Aug 4 07:47:17 1999
Message-Id: <199908041130.NAA21354@mail.boku.ac.at>
From: "Verena RESSEL" <vressel@edv2.boku.ac.at>
To: s-news@wubios.wustl.edu
Date: Wed, 4 Aug 1999 13:43:24 +0100
Mime-Version: 1.0
Content-Type: text/enriched; charset=ISO-8859-1
Content-Transfer-Encoding: Quoted-printable
<color><param>0100,0100,0100</param>Thanks to everyone who replied. Here i=
s a summary of the answers
I received.
Verena
-----------------------------------------------------------
<color><param>0000,0000,0000</param>Mrigesh Kshatriya <<<underline><colo=
r><param>0000,8000,0000</param>mkshatriya@zoology.up.ac.za </underline>> <=
color><param>0000,0000,0000</param>wrote:<underline><color><param>0000,800=
0,0000</param>
</underline><color><param>0000,0000,0000</param>I found a time series pack=
age at
<underline><color><param>0000,8000,0000</param>http://anson.ucdavis.edu/~s=
humway/tsa.html</underline><color><param>0000,0000,0000</param> which seem=
s to apply
kalman filter for S.S. analysis.
-----------------------------------------------------------
Don McKenzie <<<underline><color><param>0000,8000,0000</param>dmck@u.washi=
ngton.edu</underline>> <color><param>0000,0000,0000</param>wrote:
There is a posting on statlib that uses EM for the variance estimates.
Also see below for a helpful reply I got to this question (I haven't
done anything about it yet).
---------- Forwarded message ----- Date: Fri, 21 May 1999 09:21:33
From: Paul Gilbert <<<underline><color><param>0000,8000,0000</param>pgilbe=
rt@bank-banque-canada.ca</underline><color><param>0000,0000,0000</param>> =
To: Jorge de la Vega Gongora <<<underline><color><param>0000,8000,0000</pa=
ram>jvega@stat.umn.edu</underline><color><param>0000,0000,0000</param>>
Subject: Re: [S] State space models
There is an old version of my DSE library on Statlib, but you can
find
more recent versions at <<<underline><color><param>0000,8000,0000</param>h=
ttp://www.bank-banque-
canada.ca/pgilbert</underline><color><param>0000,0000,0000</param>> along =
with a User Guide and an HTML version
of the documentation. The library handles multivariate state space
models. The library is not yet working properly with Splus 5. I work
in Unix and am using R and Splus 3.3, though it should work fine
with 3.4. To improve speed the library calls fortran routines for some
calculations, so for reasonable speed you need to be able to
compile fortran, but in theory everything works without the fortran.
I have not implemented EM, but it could be added fairly easily if you
are interested. In general I don't recommend hill climbing
procedures for multivariate state space model estimation.
-------------------------------------------------------------
Paul Gilbert <<<underline><color><param>0000,8000,0000</param>pgilbert@ba=
nk-banque-canada.ca</underline><color><param>0000,0000,0000</param>> wrot=
e:
Below is a copy of the Kalman filter routine clipped from a much
larger time series library I have available at
<<<underline><color><param>0000,8000,0000</param>http://www.bank-banque-ca=
nada.ca/pgilbert</underline><color><param>0000,0000,0000</param>>. One par=
t of this
function sets up parameters to call compiled code which is faster (if
compiled=3D=3DT). You can delete this and use the S code as your
model. It is set up to be called from some other functions, but I think
you will be able to figure out what you need. It also does a few other
things you are probably not interested in doing. I hope it is helpful,
but it will require a lot of changes in order to use for adaptive
estimation.
Please let me know if you get something that works well.
Paul Gilbert
______
KF <<- function (model, data, sampleT =3D NULL, predictT =3D NULL,
error.weights =3D 0, return.state =3D F, return.track =3D F, result =3D N=
ULL,
compiled =3D .DSECOMPILED, warn =3D T, return.debug.info =3D F)
# end of KF
{
# ref. B.D.O.Anderson & J.B.Moore "Optimal Filtering" p.39,44.
# sampleT is the length of data which should be used for
calculating
# one step ahead predictions. y must be at least as
# long as sampleT. If predictT is large than sampleT then the
model is simulated to
# predictT. y is used if it is long enough. u must be at least as
long
as predictT.
# The default result=3D0 returns a list of all the results. Otherwise
only the
# indicated list element is return (eg. result=3D1 return the
likelihood and
# result=3D3 returns the one step ahead predictions.
# Calculate the state, residuals, and likelihood value for the
model:
#
# z(t) =3D Fz(t-1) + Gu(t) + Qe(t)
# y(t) =3D Hz(t) + Rw(t)
#
# or the innovations model:
# z(t) =3D Fz(t-1) + Gu(t)+ Kw(t-1)
# y(t) =3D Hz(t) + w(t)
#
# FF (nxn) is the state transition matrix F.
# H (pxn)is the output matrix H.
# Q (nxn) is the input matrix of the system noise and the noise is
assumed to be white.
# Some authors (eg. Harvey) modify this as rt*qt*rt' where rt is
the matrix for the
# system noise and qt is the noise cov, but that is redundant.
# R (pxp) is the input matrix of the output (measurement) noise,
which is assumed white.
# probably need R if p>n ??
# G (nxp)is the control (input) matrix.
# K (nxp)is the Kalman gain.
# y is the p dimensional output data.
# u is the m dimensional exogenous (input) data.
# z is the n dimensional (estimated) state at time t, E[z(t)|y(t-1), =
u(t)] denoted E[z(t)|t-1].
# Note: In the case where there is no input u this corresponds
to
what
# would usually be called the predicted state - not the
filtered state.
# state is the history of the state.
# Om is the estimated output cov matrix.
# vt is the prediction error.
# pred is the history of the one-step ahead predictions, E[y(t)|y(t-
1),u(t)] denoted E[y(t)|t-1].
# The history of the prediction error is given by y-
pred[1:predictT,]or y-pred[1:sampleT,]
# If error.weights is greater than zero then weighted prediction
# errors are calculated up to the horizon indicated
# by the length of error.weights. The weights are applied to the
squared
# error at each period ahead.
# P is the one step ahead estimate of the state tracking error
matrix at each
# period. Cov{z(t)-E[z(t)|t-1]}
# trackError is the history of P.
# Tracking error pt can only be calculated if Q and R are
provided (gain FALSE).
# Using the Kalman gain K directly these are not necessary
# for the likelihood calculation,
# but the tracking error cannot be calculated.
# If z0 is supplied it is used as the estimate of the state at time 0.=
# If not supplied it is set to zero. # If P0 is supplied it is used as=
the initial tracking error P(t=3D1|t=3D0). # If not supplied it is set to=
I.
# could check that Q is symmetric or positive definite but ...
if (!is.TSm.or.em(model))
TS.error.exit()
if (is.TSestModel(model))
model <<- model$model
if (!is.SS(model))
TS.error.exit(clss =3D "SS")
data <<- TSdata(data)
if (!check.consistent.dimensions(model, data))
stop("dimension error\n")
if (is.null(sampleT))
sampleT <<- output.periods(data)
if (is.null(predictT))
predictT <<- sampleT
if (sampleT > predictT)
stop("sampleT cannot exceed predictT.\n")
if (sampleT > output.periods(data))
stop("sampleT cannot exceed length of data.\n")
if (0 !=3D input.dimension(data)) {
if (input.periods(data) << predictT)
stop("input data must be at least as long as requested
prediction.\n")
if (any(is.na(input.data(data))))
stop("input data cannot contain NAs.\n")
}
if (any(is.na(output.data(data))))
stop("output data cannot contain NAs.\n")
gain <<- is.innov.SS(model)
if (gain & return.track)
warning("Tracking error is zero for an innovations model. track
will not be calculated.")
FF <<- model$F
H <<- model$H
n <<- dim(FF)[2]
p <<- dim(H)[1]
if (is.null(model$G)) {
m <<- 0
# can't call compiled with 0 length arrays
G <<- matrix(0, n, 1)
u <<- matrix(0, predictT, 1)
}
else {
m <<- dim(model$G)[2]
G <<- model$G
u <<- input.data(data)
}
# K or Q,R can be NUll in model, which messes up compiled
if (gain) {
K <<- model$K
#not used
Q <<- matrix(0, 1, 1)
#not used
R <<- matrix(0, 1, 1)
#not used
track <<- array(0, c(1, 1, 1))
}
else {
Q <<- model$Q
# Q assumed square in compiled
if (ncol(Q) << n)
Q <<- cbind(Q, matrix(0, n, n - ncol(Q)))
R <<- model$R
# this is used
K <<- matrix(0, n, p)
#not used
if (return.track)
track <<- array(0, c(predictT, n, n))
else track <<- array(0, c(1, 1, 1))
storage.mode(track) <<- "double"
}
#not used
if (return.state | return.debug.info)
state <<- matrix(0, predictT, n)
else state <<- matrix(0, 1, 1)
storage.mode(state) <<- "double"
# initial state
if (is.null(model$z0))
z <<- rep(0, n)
else z <<- model$z0
# initial state tracking error
# this is not used in innov. models
if (is.null(model$P0))
P <<- diag(1, n)
else P <<- model$P0
# end of S version
if (compiled) {
r <<- .Fortran("kf", pred =3D matrix(0, predictT, p),
as.integer(length(error.weights)),
weighted.sqerror =3D matrix(0, sampleT, p), error.weights =3D
as.double(error.weights),
as.logical(return.state), state =3D state,
as.logical(return.track &
!gain), track =3D track, as.integer(m), as.integer(n),
as.integer(p), sampleT =3D as.integer(sampleT), predictT =3D
as.integer(predictT),
as.integer(output.periods(data)), as.double(u),
as.double(output.data(data)),
as.double(FF), as.double(G), as.double(H), as.double(K),
as.double(Q), as.double(R), as.logical(gain), as.double(z),
as.double(P))[c("pred", "state", "track", "weighted.sqerror")]=
if (all(0 =3D=3D error.weights))
r$weighted.sqerror <<- NULL
}
else {
y <<- output.data(data)
# initial prediction error
vt <<- rep(0, p)
pred <<- matrix(0, predictT, p)
wt.err <<- NULL
if (1 << length(error.weights))
wt.err <<- matrix(0, predictT, p)
if (!gain) {
RR <<- R %*% t(R)
QQ <<- Q %*% t(Q)
}
for (Time in 1:sampleT) {
if (!gain) {
PH <<- P %*% t(H)
ft <<- (H %*% PH) + RR
# force ft to be symmetric
ft <<- (ft + t(ft))/2
K <<- t(solve(ft, t(FF %*% PH)))
# P(t|t-1)
P <<- (FF %*% P %*% t(FF)) - (K %*% H %*% P %*%
t(FF)) + QQ
# force symmetry (eliminate rounding error problems)
P <<- (P + t(P))/2
# P(t|t-1)
# note P(t|t) =3DP -
P%*%t(H)%*%solve(H%*/home/mfa5/gilp/dse/my/src/SCCS/s.dse1b
.hs*%t(H)+RR)%*07/16/99*%P
if (return.track)
track[Time, , ] <<- P
}
# E[z(t)| t-1 ]
z <<- c(FF %*% z) + c(K %*% vt)
if (m !=3D 0)
z <<- z + c(G %*% u[Time, ])
if (return.state | return.debug.info)
state[Time, ] <<- z
# predicted output
pred[Time, ] <<- Ey <<- c(H %*% z)
# prediction error
vt <<- y[Time, ] - Ey
if (any(0 !=3D error.weights)) {
# weighted sq prediction error
wt.err[Time, ] <<- error.weights[1] * vt^2
if (length(error.weights) > 1) {
zh <<- z
for (h in 2:length(error.weights)) if ((Time +
h - 1) <<=3D sampleT) {
zh <<- c(FF %*% zh)
# vt is 0 for h>2
if (h =3D=3D 2)
zh <<- zh + c(K %*% vt)
if (m !=3D 0)
zh <<- zh + c(G %*% u[Time + h - 1, ])
wt.err[Time, ] <<- wt.err[Time, ] + error.weights[h] *=
(y[Time + h - 1, ] - c(H %*% zh))^2
}
}
}
}
# prederror <<- y[1:sampleT,,drop=3DF]-
pred[1:sampleT,,drop=3DF] #
now multi-step prediction to predictT # This requires u but not
y
(y is ignored if it is supplied) if (predictT > sampleT) {
for (Time in (sampleT + 1):predictT) {
z <<- c(FF %*% z)
if (m !=3D 0)
z <<- z + c(G %*% u[Time, ])
if (Time =3D=3D sampleT + 1)
z <<- z + c(K %*% vt)
if (return.state)
state[Time, ] <<- z
# predicted output
pred[Time, ] <<- c(H %*% z)
}
}
r <<- list(pred =3D pred, state =3D state, track =3D track,
weighted.sqerror =3D wt.err)
}
tf <<- truncate.tframe(tframe(output.data(data)), end =3D predictT)
tframe(r$pred) <<- tf
if (!is.null(r$weighted.sqerror))
tframe(r$weighted.sqerror) <<- tf
filter <<- NULL
if (return.state | return.track) {
if (gain | (!return.track))
filter$track <<- NULL
else {
filter$track <<- r$track
tframe(filter$track) <<- tf
}
if (return.state) {
filter$state <<- r$state
tframe(filter$state) <<- tf
}
}
if ((!is.null(result)) && (result =3D=3D "pred"))
return(r$pred)
r <<- append(residual.stats(r$pred, output.data(data), sampleT,
warn =3D warn), list(error.weights =3D error.weights,
weighted.sqerror
=3D
r$weighted.sqerror))
if (return.debug.info)
r$debug.info <<- list(m =3D m, p =3D p, a =3D a, b =3D b, c =3D c,=
G =3D G, FF =3D FF, K =3D K, P =3D P, H =3D H, u =3D u, y =3D =
y,
pred =3D pred, wt.err =3D wt.err, error.weights =3D error.weig=
hts,
sampleT =3D sampleT)
if (is.null(result)) {
r <<- list(estimates =3D r, data =3D data, model =3D model,
filter =3D filter)
return(classed(r, "TSestModel"))
}
else {
if (result =3D=3D "like")
return(r$like[1])
else {
# neg.log.like. from residual.stats
return(r[[result]])
}
}
"should never get to here in KF"
}
---------------------------------------------------------------------
Fernando TUSELL<< <underline><color><param>0000,8000,0000</param>etptupaf@=
bs.ehu.es</underline><color><param>0000,0000,0000</param>> wrote:
You may find useful the following code. I got it from somewhere, a
reference is at the end.
ft.
---------------- code cited in message -------------------
(1) This submission provides a pair of ASCII files to be "sourced"
into S. The resulting S functions, named filter and forecast,
implement Kalman filter recursions using the EM algorithm.
Reference: "An approach to time series smoothing
and forecasting using the EM algorithm."
R. H. Shumway and D. S. Stoffer
J. Time Series Anal. Vol. 3, No. 4 253-264
(2) The information I would like to share:
filter <<-
function(numobs,y,A,Sigma0,mu0,Phi0,Q0,R0,tol=3D0.01,max.iter=3D20,v
erbose=3DT){
# y[,t] rx1
# A[[t]] rxp
# Sigma0 pxp
# mu0 px1
# Phi0 pxp
# Q0 pxp
# R0 rxr
# tol, log likelihood convergence tolerance
# EM estimation of Kalman filter
# Reference: "An approach to time series smoothing
# and forecasting using the EM algorithm."
# R. H. Shumway and D. S. Stoffer
# J. Time Series Anal. Vol. 3, No. 4 253-264
# y(t) =3D A(t)%*%x(t) + v(t), for t=3D1,...,T
# x(t) =3D Phi%*%x(t-1) + w(t), for t=3D1,...,T
# y rx1 observation vector
# A rxp design matrix
# E[v(t)]=3D0, R =3D E[v(t)%*%t(v(t))] rxr observation noise covariance
# x px1 state vector
# Phi pxp transition matrix
# E[w(t)]=3D0, Q =3D E[w(t)%*%t(w(t))] pxp state noise covariance
# initial vector x0, E[x0] =3D mu, Sigma =3D E[(x0-mu)%*%t(x0-mu)]
# Notation:
# sxt =3D E[x(t)|y(1),...,y(s)]
# sPtu =3D E[(x(t)-sxt)%*%t(x(u)-sxu)|y(1),...,y(s)]
N <<- numobs
mu <<- mu0
Phi <<- Phi0
Q <<- Q0
R <<- R0
iter <<- 0
cvg <<- 1
while((iter <<=3D max.iter) && (cvg > tol)){
# gain K pxr and covariances sPtt, tPtt
sPtt <<- vector("list",N)
K <<- vector("list",N)
tPtt <<- vector("list",N+1)
tPtt[[1]] <<- Sigma0
sxt <<- vector("list",N)
txt <<- vector("list",N+1)
txt[[1]] <<- mu
eps <<- vector("list",N)
Sigma <<- vector("list",N)
qf <<- seq(N)*0
det <<- seq(N)*0
# forward recursions
for(n in seq(N)){
sPtt[[n]] <<- Phi%*%tPtt[[n]]%*%t(Phi) + Q
K[[n]] <<-
sPtt[[n]]%*%t(A[[n]])%*%solve(A[[n]]%*%sPtt[[n]]%*%t(A[[n]])+R)
tPtt[[n+1]] <<- sPtt[[n]] - K[[n]]%*%A[[n]]%*%sPtt[[n]]
# filter estimators sxt, txt
sxt[[n]] <<- Phi%*%txt[[n]]
txt[[n+1]] <<- sxt[[n]] + (K[[n]]%*%(y[,n]-(A[[n]]%*%sxt[[n]])))
# innovations eps
eps[[n]] <<- y[,n] - A[[n]]%*%sxt[[n]]
Sgm <<- A[[n]]%*%sPtt[[n]]%*%t(A[[n]]) + R
Sigma[[n]] <<- (t(Sgm)+Sgm)/2
# To ensure its symmetric!
qf[n] <<- t(eps[[n]])%*%solve(Sigma[[n]])%*%eps[[n]]
det[n] <<- prod(eigen( Sigma[[n]] )$values)
# Det for real-valued matrices!
# det[n] <<- prod(diag(chol( Sigma[[n]] )))^2
}
# backward recursions
J <<- vector("list",N)
Txs <<- vector("list",N+1)
Txs[[N+1]] <<- txt[[N+1]]
TPss <<- vector("list",N+1)
TPss[[N+1]] <<- tPtt[[N+1]]
st0 <<- vector("list",N)
ss0 <<- vector("list",N)
St0 <<-
matrix(0,nrow=3Ddim(TPss[[N+1]])[1],ncol=3Ddim(TPss[[N+1]])[2]) Ss0
<<- matrix(0,nrow=3Ddim(TPss[[N+1]])[1],ncol=3Ddim(TPss[[N+1]])[2])
# smoother estimators Txs
for(n in seq(from=3DN,to=3D1)){
J[[n]] <<- tPtt[[n]]%*%t(Phi)%*%solve(sPtt[[n]])
Txs[[n]] <<- txt[[n]] + J[[n]]%*%(Txs[[n+1]]-sxt[[n]])
# covariance TPss
TPss[[n]] <<- tPtt[[n]] +
J[[n]]%*%(TPss[[n+1]]-sPtt[[n]])%*%t(J[[n]])
# Q(,) calculations
st0[[n]] <<- TPss[[n+1]] + Txs[[n+1]]%*%t(Txs[[n+1]])
ss0[[n]] <<- TPss[[n]] + Txs[[n]]%*%t(Txs[[n]])
St0 <<- St0 + st0[[n]]
Ss0 <<- Ss0 + ss0[[n]]
}
loglik <<- -.5*sum(log(det)) - .5*sum(qf)
if(-2*loglik << 0){
out <<- list(mu, Phi, Q, R)
names(out) <<- c("mu", "Phi", "Q", "R")
warning("-2*loglik << 0")
return(out)
}
if(verbose=3D=3DT) print(-2*loglik)
# EM algorithm
# covariance TPsr
TPsr <<- vector("list",N)
p <<- dim(Phi0)[1]
TPsr[[N]] <<- (diag(p) - K[[N]]%*%A[[N]])%*%Phi%*%tPtt[[N]]
for(n in seq(from=3DN,to=3D2)){
TPsr[[n-1]] <<- tPtt[[n]]%*%t(J[[n-1]]) + J[[n]]%*%(TPsr[[n]] -
Phi%*%tPtt[[n]])%*%t(J[[n-1]]) }
# Q(,) calculations
st1 <<- vector("list",N)
St1 <<- matrix(0,nrow=3Ddim(TPsr[[N]])[1],ncol=3Ddim(TPsr[[N]])[2])
rcov <<- matrix(0,nrow=3Ddim(R)[1],ncol=3Ddim(R)[2])
for(n in seq(from=3DN,to=3D1)){
st1[[n]] <<- TPsr[[n]] + Txs[[n+1]]%*%t(Txs[[n]])
St1 <<- St1 + st1[[n]]
rcov <<- rcov +
(y[,n]-A[[n]]%*%Txs[[n+1]])%*%t(y[,n]-A[[n]]%*%Txs[[n+1]]) +
A[[n]]%*%TPss[[n+1]]%*%t(A[[n]]) }
# update mu, Phi, Q, R
# NB: structured parameter matrices can be used by fixing the
appropriate
# elements
mu <<- Txs[[1]]
Phi <<- St1%*%solve(Ss0)
Q <<- matrix(1/N,nrow=3Ddim(Q)[1],ncol=3Ddim(Q)[2])*(St0 -
St1%*%solve(Ss0)%*%t(St1)) R <<-
matrix(1/N,nrow=3Ddim(R)[1],ncol=3Ddim(R)[2])*rcov
iter <<- iter + 1
if(iter>1) cvg <<- (-2*old.loglik) - (-2*loglik)
old.loglik <<- loglik
}
# end while loop
r <<- dim(R0)[1]
BIC <<- loglik - 0.5*(p + p^2 + r*(r+1)/2 + r*(r+1)/2)*log(N) # mu,
Phi, Q, R parameters out <<- list(mu,Phi,Q,R,BIC) names(out) <<-
c("mu","Phi","Q","R","BIC") out
}
----------
forecast <<- function(ahead,numobs,y,A,Sigma0,mu0,Phi0,Q0,R0){
# ahead - the desired number of forecasts of y[,t], t>T
# y[,t] rx1
# A[[t]] rxp
# Sigma0 pxp
# mu0 px1
# Phi0 pxp
# Q0 pxp
# R0 rxr
# EM estimation of Kalman filter
# Reference: "An approach to time series smoothing
# and forecasting using the EM algorithm."
# R. H. Shumway and D. S. Stoffer
# J. Time Series Anal. Vol. 3, No. 4 253-264
# y(t) =3D A(t)%*%x(t) + v(t), for t=3D1,...,T
# x(t) =3D Phi%*%x(t-1) + w(t), for t=3D1,...,T
# y rx1 observation vector
# A rxp design matrix
# E[v(t)]=3D0, R =3D E[v(t)%*%t(v(t))] rxr observation noise covariance
# x px1 state vector
# Phi pxp transition matrix
# E[w(t)]=3D0, Q =3D E[w(t)%*%t(w(t))] pxp state noise covariance
# initial vector x0, E[x0] =3D mu, Sigma =3D E[(x0-mu)%*%t(x0-mu)]
# Notation:
# sxt =3D E[x(t)|y(1),...,y(s)]
# sPtu =3D E[(x(t)-sxt)%*%t(x(u)-sxu)|y(1),...,y(s)]
N <<- numobs + ahead
mu <<- mu0
Phi <<- Phi0
Q <<- Q0
R <<- R0
r <<- dim(A[[1]])[1]
p <<- dim(A[[1]])[2]
# gain K pxr and covariances sPtt, tPtt
sPtt <<- vector("list",N)
K <<- vector("list",N)
tPtt <<- vector("list",N+1)
tPtt[[1]] <<- Sigma0
sxt <<- vector("list",N)
txt <<- vector("list",N+1)
txt[[1]] <<- mu
# forward recursions
for(n in seq(N)){
sPtt[[n]] <<- Phi%*%tPtt[[n]]%*%t(Phi) + Q
# K(t)=3D0, for t>T
if(n<<=3Dnumobs) { K[[n]] <<-
sPtt[[n]]%*%t(A[[n]])%*%solve(A[[n]]%*%sPtt[[n]]%*%t(A[[n]])+R)
}
else { K[[n]] <<- matrix(0,nrow=3Dp,ncol=3Dr) } tPtt[[n+1]] <<-
sPtt[[n]] - K[[n]]%*%A[[n]]%*%sPtt[[n]]
# filter estimators sxt, txt
sxt[[n]] <<- Phi%*%txt[[n]]
if(n<<=3Dnumobs) { txt[[n+1]] <<- sxt[[n]] +
(K[[n]]%*%(y[,n]-(A[[n]]%*%sxt[[n]]))) } else { txt[[n+1]] <<-
sxt[[n]] } }
# backward recursions
J <<- vector("list",N)
Txs <<- vector("list",N+1)
Txs[[N+1]] <<- txt[[N+1]]
TPss <<- vector("list",N+1)
TPss[[N+1]] <<- tPtt[[N+1]]
# smoother estimators Txs
for(n in seq(from=3DN,to=3D1)){
J[[n]] <<- tPtt[[n]]%*%t(Phi)%*%solve(sPtt[[n]])
Txs[[n]] <<- txt[[n]] + J[[n]]%*%(Txs[[n+1]]-sxt[[n]])
# covariance TPss
TPss[[n]] <<- tPtt[[n]] +
J[[n]]%*%(TPss[[n+1]]-sPtt[[n]])%*%t(J[[n]]) }
# covariance TPsr
TPsr <<- vector("list",N)
TPsr[[N]] <<- (diag(p) - K[[N]]%*%A[[N]])%*%Phi%*%tPtt[[N]]
for(n in seq(from=3DN,to=3D2)){
TPsr[[n-1]] <<- tPtt[[n]]%*%t(J[[n-1]]) + J[[n]]%*%(TPsr[[n]] -
Phi%*%tPtt[[n]])%*%t(J[[n-1]]) }
Ty <<- matrix(0,nrow=3Dr,ncol=3DN)
Tx <<- matrix(0,nrow=3Dp,ncol=3DN)
for(i in seq(from=3DN+1,to=3D2)){
Ty[,i-1] <<- A[[i-1]]%*%Txs[[i]]
Tx[,i-1] <<- Txs[[i]]
}
out <<- list(Ty,Tx)
names(out) <<- c("obs.pred","state.pred")
out
}
----------
(3) GENERAL DISCLAIMER
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 1, or (at your option) any later version.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the
implied
warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License
for more details.
For a copy of the GNU General Public License write to the
Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA. In short: you may use this code any way you
like, as long as you don't charge money for it, remove this notice, or
hold anyone liable for its results.
Gary Nan Tie
(2i2) 902-7265
<underline><color><param>0000,8000,0000</param>nantig@fi.gs.com
</underline>----------------------------------------------<underline>
<nofill>
------------------------------------------------------------------------
DI Verena Ressel ph: +43 1 36006 5525
email: vressel@edv2.boku.ac.at
Institut f=FCr Wasserwirtschaft, Hydrologie
und konstruktiven Wasserbau (IWHW)
Universit=E4t f=FCr Bodenkultur Wien
Muthgasse 18
A-1190 Wien
AUSTRIA
------------------------------------------------------------------------
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news