PageRenderTime 68ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/Src/filter.f

https://bitbucket.org/christophermarkstrickland/pyssm
FORTRAN Legacy | 3656 lines | 1381 code | 489 blank | 1786 comment | 105 complexity | b8a2dca2e237f97466547fdf677454f5 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. c Fortran 77 source code for the Python library PySSM
  2. c Copyright (C) 2010 Chris Strickland
  3. c This program is free software: you can redistribute it and/or modify
  4. c it under the terms of the GNU General Public License as published by
  5. c the Free Software Foundation, either version 2 or verion 3 of the
  6. c License.
  7. c This program is distributed in the hope that it will be useful,
  8. c but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. c GNU General Public License for more details.
  11. c You should have received a copy of the GNU General Public License
  12. c along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. c ------------------------------------------------------------------
  14. c Filtering and smoothing code + associated functions
  15. c ------------------------------------------------------------------
  16. c Note: Matrix Types [ std = 0, eye = 1, diag = 2, inv = 3, chol = 4 ]
  17. c If type = 3 then matrix is actually the inverse
  18. c If type = 4 then matrix is the cholesky decomposition
  19. c -----------------------------------------------------------------
  20. c fortran code to simulate disturbance vector for state space model
  21. c note fl = 1 if rvs on exit is qt & rvs, 0 otherwise
  22. c note if fl = 1 then gcqt should be gt, otherwise gcqt
  23. subroutine calc_st_er(gcqt,cqt,rvs,ser,fl,m,r,n,n_q,n_gq)
  24. implicit none
  25. integer m,r,n,t,n_q,n_gq,t_q,t_gq,timet,fl
  26. real*8 gcqt(m,r,n_gq),cqt(r,r,n_q),rvs(r,n),ser(m,n)
  27. real*8 alpha,beta
  28. c ----------------------
  29. cf2py intent(in) gcqt
  30. cf2py intent(in) cqt
  31. cf2py intent(inplace) rvs
  32. cf2py intent(inplace) ser
  33. cf2py intent(in) fl
  34. cf2py intent(in) m
  35. cf2py intent(in) r
  36. cf2py intent(in) b
  37. c ----------------------
  38. alpha = 1.0
  39. beta = 0.0
  40. c$omp parallel default(shared) private(t, t_q, t_gq)
  41. c$omp do schedule(static)
  42. do t = 1, n
  43. t_q = timet(n_q, t)
  44. t_gq = timet(n_gq, t)
  45. if (fl.eq.1) then
  46. call dtrmv('l','n','n',r,cqt(:,:,t_q),r,rvs(:,t),1)
  47. endif
  48. call dgemv('n',m,r,alpha,gcqt(:,:,t_gq),m,rvs(:,t),1,beta,
  49. + ser(:,t),1)
  50. enddo
  51. c$omp end do
  52. c$omp end parallel
  53. end
  54. c ------------------------------------------------------------------
  55. c fortran code to simulate disturbance vector for state space model
  56. c note fl = 1 if rvs on exit is qt & rvs, 0 otherwise
  57. c note if fl = 1 then gcqt should be gt, otherwise gcqt
  58. subroutine nt_calc_st_er(gcqt,cqt,rvs,ser,fl,m,r,n)
  59. implicit none
  60. integer m,r,n,fl
  61. real*8 gcqt(m,r),cqt(r,r),rvs(r,n),ser(m,n)
  62. real*8 alpha,beta
  63. c ----------------------
  64. cf2py intent(in) cqt
  65. cf2py intent(in) gcqt
  66. cf2py intent(inplace) rvs
  67. cf2py intent(inplace) ser
  68. cf2py intent(in) fl
  69. cf2py intent(in) m
  70. cf2py intent(in) r
  71. cf2py intent(in) b
  72. c ----------------------
  73. alpha = 1.0
  74. beta = 0.0
  75. if (fl.eq.1) then
  76. call dtrmm('l','l','n','n',r,n,alpha,cqt,r,rvs,r)
  77. endif
  78. call dgemm('n','n',m,n,r,alpha,gcqt,m,rvs,r,beta,ser,m)
  79. end
  80. c ------------------------------------------------------------------
  81. c **/** NEW OPENMP ADDED - UNTESTED **/**
  82. c fortran code for standard filtering and smoothing algorithms
  83. c simulates data for standard state space model
  84. subroutine simssm(y,zt,cht,tt,ser,rvm,av,n,p,m, n_z, n_t, n_h)
  85. implicit none
  86. integer n,p,m,t, t_t, t_z, n_z, n_t, t_h, n_h, timet
  87. real*8 y(p,n), zt(p,m,n_z), cht(p,p,n_h), tt(m,m,n_t)
  88. real*8 rvm(p,n), ser(m,n), av(m,n)
  89. real*8 alpha, beta
  90. c cht is the sqrt of the ht. recall that ht is a vector
  91. c ----------------------
  92. cf2py intent(inout) y
  93. cf2py intent(in) zt
  94. cf2py intent(in) ch
  95. cf2py intent(in) tt
  96. cf2py intent(in) rvm
  97. cf2py intent(in) ser
  98. cf2py intent(inout) av
  99. cf2py intent(in) n
  100. cf2py intent(in) p
  101. cf2py intent(in) m
  102. cf2py intent(in) n_z
  103. cf2py intent(in) n_t
  104. cf2py intent(in) n_h
  105. c ----------------------
  106. alpha = 1.0
  107. beta = 1.0
  108. do t = 1, n-1
  109. t_t = timet(n_t, t)
  110. c Initialise: av(t+1) = ser(t)
  111. call dcopy(m,ser(:,t),1,av(:,t+1),1)
  112. c Compute: av(t+1) = av(t+1) + tt * av(t)
  113. call dgemv('n',m,m,alpha,tt(:,:,t_t),m,av(:,t),1,beta,
  114. + av(:,t+1),1)
  115. enddo
  116. c$omp parallel default(shared) private(t, t_z, t_h, beta)
  117. c$omp do schedule(static)
  118. do t = 1, n
  119. t_z = timet(n_z, t)
  120. t_h = timet(n_h, t)
  121. c Compute: y(t) = cht(t) * rvm(t)
  122. beta = 0.0
  123. call dgemv('n',p,p,alpha,cht(:,:,t_h),p,rvm(:,t),1,beta,
  124. + y(:,t),1)
  125. c Compute: y(t) = y(t) + zt(t) * av(t)
  126. beta = 1.0
  127. call dgemv('n',p,m,alpha,zt(:,:,t_z),p,av(:,t),1, beta,
  128. + y(:,t),1)
  129. enddo
  130. c$omp end do
  131. c$omp end parallel
  132. end
  133. c ------------------------------------------------------------------
  134. c non time varying version that simulates data
  135. subroutine ntsimssm(y,zt,ch,tt,ser,rvm,av,n,p,m)
  136. integer n,p,m,t
  137. real*8 y(p,n), zt(p,m), ch(p,p), tt(m,m)
  138. real*8 rvm(p,n),av(m,n),ser(m,n)
  139. real*8 alpha, beta
  140. c cht is the sqrt of ht. recall that ht is a vector
  141. c ----------------------
  142. cf2py intent(inout) y
  143. cf2py intent(in) zt
  144. cf2py intent(in) ch
  145. cf2py intent(in) tt
  146. cf2py intent(in) ser
  147. cf2py intent(in) rvm
  148. cf2py intent(inout) av
  149. cf2py intent(in) n
  150. cf2py intent(in) p
  151. cf2py intent(in) m
  152. c ----------------------
  153. alpha = 1.0
  154. beta = 1.0
  155. do t = 1, n-1
  156. c Initialise: av(t+1) = ser(t)
  157. call dcopy(m,ser(:,t),1,av(:,t+1),1)
  158. c Compute: av(t+1) = av(t+1) + tt(t) * av(t)
  159. call dgemv('n',m,m,alpha,tt,m,av(:,t),1,beta, av(:,t+1),1)
  160. enddo
  161. beta = 0.0
  162. call dgemm('n','n',p,n,p,alpha,ch,p,rvm,p,beta,y,p)
  163. beta = 1.0
  164. call dgemm('n','n',p,n,m,alpha,zt,p,av,m,beta,y,p)
  165. end
  166. c ------------------------------------------------------------------
  167. c subroutine for filtering with the standard state SSM
  168. subroutine filter(y, z, h, tt, qt, nu, k, f, s, a, at, pt, ps,
  169. + mt, w, ls, lk, wl, ifo, ptt, ilike, pmiss, m, p, n, n_z, n_t,
  170. + n_q, n_h)
  171. integer m, p, n, t, i, ifo, ptt, info, ilike
  172. integer timet, n_z, n_t, n_q, t_z, t_t, t_q, t_h, pmiss(n)
  173. real*8 y(p,n), z(p,m,n_z), h(p,p,n_h), tt(m,m,n_t), qt(m,m,n_q)
  174. real*8 nu(p,n), k(m,p,n), s(p,m,n), ls(m,m,n), a(m,n)
  175. real*8 ps(m,m,n), mt(m,p), at(m), pt(m,m), f(p,p), w(m,m)
  176. real*8 alpha, beta, lk(*), wl(p), logdet, ddot, llike
  177. c ----------------------
  178. cf2py intent(in) y
  179. cf2py intent(in) z
  180. cf2py intent(in) h
  181. cf2py intent(in) tt
  182. cf2py intent(in) qt
  183. cf2py intent(inout) nu
  184. cf2py intent(inout) k
  185. cf2py intent(in) f
  186. cf2py intent(inout) s
  187. cf2py intent(inout) a
  188. cf2py intent(in) at
  189. cf2py intent(in) pt
  190. cf2py intent(inout) ps
  191. cf2py intent(in) mt
  192. cf2py intent(in) w
  193. cf2py intent(inplace) lk
  194. cf2py intent(inplace) ifo
  195. cf2py intent(in) pmiss
  196. cf2py intent(in) ptt
  197. cf2py intent(in) m
  198. cf2py intent(in) p
  199. cf2py intent(in) n
  200. cf2py intent(in) n_z
  201. cf2py intent(in) n_t
  202. cf2py intent(in) n_h
  203. cf2py intent(in) n_q
  204. c ----------------------
  205. c note if lk(1).lt.-1 then calculate likelihood and return in lk(1)
  206. ifo = 0
  207. llike = 0.0
  208. do t = 1, n
  209. t_z = timet(n_z, t)
  210. t_t = timet(n_t, t)
  211. t_q = timet(n_q, t)
  212. t_h = timet(n_h, t)
  213. c 1. Initialise: a(:,t) = at
  214. call dcopy(m,at,1,a(:,t),1)
  215. c -------------------------------------------------------------
  216. c 2. Initialise: ps(:,i,t) = pt(:,i)
  217. do i = 1, m
  218. call dcopy(m, pt(:,i), 1, ps(:,i,t), 1)
  219. enddo
  220. c -------------------------------------------------------------
  221. c 3. Compute: Nu(t) = Y(t) - Z(t) * a(t)
  222. c 3a. Initialise: nu(:,t) = y(:,t)
  223. if (pmiss(t).eq.0) then
  224. !data not missing
  225. call dcopy(p, y(:,t), 1, nu(:,t), 1)
  226. c 3b. Compute: nu = nu - z * at
  227. alpha = -1.0
  228. beta = 1.0
  229. call dgemv('n',p,m,alpha,z(:,:,t_z),p,at,1,beta,nu(:,t),1)
  230. c -------------------------------------------------------------
  231. c 4. Compute: m(t) = P(t)*Z(t)' [i.e. (m,p) = (m,m) *(m,p) ]
  232. alpha = 1.0
  233. beta = 0.0
  234. call dgemm('n','t',m,p,m,alpha,pt,m,z(:,:,t_z),p,beta,mt,
  235. + m)
  236. c -------------------------------------------------------------
  237. c 5. Compute: F(t) = Z(t)*m(t) + H(t) [i.e. (p,p) = (p,m)*(m,p) ]
  238. c 5a. Initialise: f(:,i) = h(:,i,t_h)
  239. !column of y not missing
  240. do i = 1, p
  241. call dcopy(p, h(:,i,t_h), 1, f(:,i), 1)
  242. enddo
  243. c 5b. Compute: f = f + z * mt
  244. beta = 1.0
  245. call dgemm('n','n',p,p,m,alpha,z(:,:,t_z),p,mt,m,beta,f,p)
  246. ! print *, "ft =", f
  247. c -------------------------------------------------------------
  248. c 6. Compute: S(t) = inv(F(t))*Z(t) [i.e. solve F.S = Z ]
  249. c 6a. Initialise: s = z
  250. do i = 1, m
  251. call dcopy(p, z(:,i,t_z), 1, s(:,i,t), 1)
  252. enddo
  253. c 6b. Solve: f * x = s [Note: store x in s] [i.e. (p,p) *(p,m) = (p,m) ]
  254. call dposv('u',p,m,f,p,s(:,:,t),p,info)
  255. if (info.ne.0) then
  256. ifo = 1
  257. endif
  258. !else
  259. !column of y missing so set S(t)=0
  260. ! do i=1,m
  261. ! do j=1,m
  262. ! S(i,j,t)=0.0
  263. ! enddo
  264. ! enddo
  265. c ------------------------------------------------------------
  266. if (ilike.eq.0) then
  267. c Compute: logdet = 2.0 * sum(i: log(f(i,i))
  268. logdet = 0.0
  269. do i = 1, p
  270. logdet = logdet + log(f(i,i))
  271. enddo
  272. logdet = 2.0 * logdet
  273. c Initialise: wl = nu(:,t)
  274. call dcopy(p, nu(:,t), 1, wl, 1)
  275. c Solve: f.x = wl (i.e. Compute: x = inv[f]*wl ) (Note: store x as wl)
  276. call dtrsv('u','t','n',p,f,p,wl,1)
  277. c Subtract: -(0.5 * nu^2) - (0.5 * logdet)
  278. llike = llike - 0.5 * (logdet + ddot(p,wl,1,wl,1))
  279. endif
  280. c -------------------------------------------------------------
  281. c 7. Compute: W(t) = T(t)*P(t)
  282. beta = 0.0
  283. if (ptt.eq.0) then
  284. c 7a. Compute: w = tt * pt
  285. call dgemm('n','n', m, m, m, alpha, tt(:,:,t_t),
  286. + m, pt, m, beta, w, m)
  287. else
  288. c 7b. Initialise: w = pt
  289. do i = 1, m
  290. call dcopy(m,pt(:,i),1,w(:,i),1)
  291. enddo
  292. endif
  293. c -------------------------------------------------------------
  294. c 8. Compute: K(t) = W(t) * S(t)'
  295. call dgemm('n','t',m,p,m,alpha,w,m,s(:,:,t),p,beta,
  296. + k(:,:,t),m)
  297. ! print *, "kt =", k(:,:,t)
  298. c -------------------------------------------------------------
  299. c 9. Compute: L(t) = T(t) - K(t)*Z(t) [i.e. (m,m) = (m,p) * (p,m) ]
  300. c 9a. Initialise: ls(:,i,t) = tt(:,t,t_t)
  301. do i = 1, m
  302. call dcopy(m,tt(:,i,t_t),1,ls(:,i,t),1)
  303. enddo
  304. c 9b. Compute: ls = ls - k(:,:,t) * z(:,:,t_z) [i.e. (m,m) = (m,p) * (p,m) ]
  305. alpha = -1.0
  306. beta = 1.0
  307. call dgemm('n','n',m,m,p,alpha,k(:,:,t),m,z(:,:,t_z),p,
  308. + beta,
  309. + ls(:,:,t),m)
  310. ! print *, "lt =", ls(:,:,t)
  311. c -------------------------------------------------------------
  312. c 10. Compute: a(t+1) = T(t)*a(t) + K(t)*nu(t)
  313. alpha = 1.0
  314. beta = 0.0
  315. if (ptt.eq.0) then
  316. c 10a. Compute: at = tt(:,:,t_t) * a(:,t)
  317. call dgemv('n',m,m,alpha,tt(:,:,t_t),m,a(:,t),1,beta,
  318. + at,1)
  319. else
  320. c 10a. Initialise: at = a(:,t)
  321. call dcopy(m, a(:,t), 1, at, 1)
  322. endif
  323. c 10b. Compute: at = at + k(:,:,t) * nu(:,t) [i.e. (m) = (m,p) *(p) ]
  324. beta = 1.0
  325. call dgemv('n',m,p,alpha,k(:,:,t),m,nu(:,t),1,beta,at,1)
  326. beta = 0.0
  327. ! print *, "at =", at
  328. else
  329. !Compute L(t)=T(t)
  330. do i = 1, m
  331. call dcopy(m,tt(:,i,t_t),1,ls(:,i,t),1)
  332. enddo
  333. c 10b. Compute a(t+1) = T(t)*a(t)
  334. alpha = 1.0
  335. beta = 0.0
  336. if (ptt.eq.0) then
  337. c 10a. Compute: at = tt(:,:,t_t) * a(:,t)
  338. call dgemv('n',m,m,alpha,tt(:,:,t_t),m,a(:,t),1,beta,
  339. + at,1)
  340. else
  341. c 10a. Initialise: at = a(:,t)
  342. call dcopy(m, a(:,t), 1, at, 1)
  343. endif
  344. c 10b. Compute: W(t) = T(t)*P(t)
  345. beta = 0.0
  346. if (ptt.eq.0) then
  347. c Compute: w = tt * pt
  348. call dgemm('n','n', m, m, m, alpha, tt(:,:,t_t),
  349. + m, pt, m, beta, w, m)
  350. else
  351. c Initialise: w = pt
  352. do i = 1, m
  353. call dcopy(m,pt(:,i),1,w(:,i),1)
  354. enddo
  355. endif
  356. endif
  357. c -------------------------------------------------------------
  358. c 11. Compute: P(t+1) = W(t)*L(t)' + Q(t)
  359. c call dgemm('n','n',m,m,m,alpha,tt(:,:,t),m,pt,m,beta,w,m)
  360. c 11a. Initialise: pt = qt(:,:,t_q)
  361. do i = 1, m
  362. call dcopy(m, qt(:,i,t_q), 1, pt(:,i), 1)
  363. enddo
  364. c 11b. Compute: pt = pt + w * ls' where w = tt * pt
  365. c [i.e. (m,m) = (m,m) * (m,m) * (m,m) ]
  366. beta = 1.0
  367. call dgemm('n','t',m,m,m,alpha,w,m,ls(:,:,t),m,beta,pt,m)
  368. enddo
  369. c -------------------------------------------------------------
  370. lk(1)=llike
  371. end
  372. c ------------------------------------------------------------------
  373. c subroutine for filtering with the standard non time varying state SSM
  374. subroutine ntfilter(y,z,h,tt,qt,nu,k,f,s,a,at,pt,ps,mt,w,ls,lt,
  375. + lk,wl,ifo,ilike,m,p,n)
  376. integer m,p,n,t,i,ifo,info,chk,indr,lt,ilike
  377. real*8 y(p,n),z(p,m),h(p,p),tt(m,m),qt(m,m),lk,wl(p)
  378. real*8 nu(p,n),k(m,p,n),s(p,m,n),ls(m,m,n),a(m,n)
  379. real*8 ps(m,m,n),mt(m,p),at(m),pt(m,m),f(p,p),w(m,m)
  380. real*8 alpha, beta,fnorm, tol,logdet,llike,ddot, temp
  381. c ----------------------
  382. cf2py intent(in) y
  383. cf2py intent(in) z
  384. cf2py intent(in) h
  385. cf2py intent(in) tt
  386. cf2py intent(in) qt
  387. cf2py intent(inplace) nu
  388. cf2py intent(inplace) k
  389. cf2py intent(in) f
  390. cf2py intent(inplace) s
  391. cf2py intent(inplace) a
  392. cf2py intent(in) at
  393. cf2py intent(in) pt
  394. cf2py intent(inplace) ps
  395. cf2py intent(in) mt
  396. cf2py intent(in) w
  397. cf2py intent(inout) lk
  398. cf2py intent(in) wl
  399. cf2py intent(inout) ifo
  400. cf2py intent(inout) lt
  401. cf2py intent(in) m
  402. cf2py intent(in) p
  403. cf2py intent(in) n
  404. c ----------------------
  405. ifo = 0
  406. tol = 1E-10
  407. chk = 10
  408. indr = 0 ! Indicator for steady state
  409. lt = n+1
  410. llike = 0.0
  411. do t = 1, n
  412. c Not yet reached steady state:
  413. if (indr.eq.0) then
  414. c 1. Initialise: a(:,t) = at
  415. call dcopy(m,at,1,a(:,t),1)
  416. c ------------------------------
  417. c 2. Initialise: ps(:,:,t) = pt
  418. do i = 1, m
  419. call dcopy(m,pt(:,i),1,ps(:,i,t),1)
  420. enddo
  421. c ------------------------------
  422. c 3. Compute: Nu(t) = Y(t) - Z(t)*a(t)
  423. c 3a. Initialise nu(:,t) = y(:, t)
  424. call dcopy(p, y(:,t), 1, nu(:,t), 1)
  425. c 3b. Compute: nu(:,t) = nu(:,t) - z * at
  426. alpha = -1.0
  427. beta = 1.0
  428. call dgemv('n',p,m,alpha,z,p,at,1,beta,nu(:,t),1)
  429. c ------------------------------
  430. c 4. Compute: m(t) = P(t)*Z(t)' , i.e. mt = pt * z
  431. alpha = 1.0
  432. beta = 0.0
  433. call dgemm('n','t',m,p,m,alpha,pt,m,z,p,beta,mt,m)
  434. c ------------------------------
  435. c 5. Compute: F(t) = Z(t)*m(t) + H(t)
  436. c 5a. Initialise f(:,i) = h(:,i)
  437. do i = 1, p
  438. call dcopy(p,h(:,i),1,f(:,i),1)
  439. enddo
  440. c 5b. Compute: f = f + z*mt
  441. beta = 1.0
  442. call dgemm('n','n',p,p,m,alpha,z,p,mt,m,beta,f,p)
  443. c ------------------------------
  444. c 6. Compute: F(t)*S(t) = Z(t); solve for S(t)=inv(F(t))*Z(t)
  445. c 6a.Initialise s(:,:,t) = z
  446. do i = 1, m
  447. call dcopy(p,z(:,i),1,s(:,i,t),1)
  448. enddo
  449. c 6b. Solve f . x = s and set s = x
  450. call dposv('u',p,m,f,p,s(:,:,t),p,info)
  451. if (info.ne.0) then
  452. ifo = 1
  453. endif
  454. ! if(t.eq.1) then
  455. ! print *, "S = ", s(:,:,t)
  456. ! endif
  457. c ------------------------------
  458. beta = 0.0
  459. if (ilike.eq.0) then
  460. logdet = 0.0
  461. do i = 1, p
  462. logdet = logdet + log(f(i,i))
  463. enddo
  464. logdet = 2.0 * logdet
  465. c Initialise wl = nu(:,t)
  466. call dcopy(p,nu(:,t),1,wl,1)
  467. call dtrsv('u','t','n',p,f,p,wl,1)
  468. llike = llike-0.5*(logdet+ddot(p,wl,1,wl,1))
  469. c call dcopy(p,nu(:,t),1,wl,1)
  470. c call dtrsm('l','u','t','n',p,1,alpha,f,p,wl,p)
  471. c call dtrsm('l','u','n','n',p,1,alpha,f,p,wl,p)
  472. c llike = llike-0.5*(logdet+ddot(p,wl,1,nu(:,t),1))
  473. endif
  474. c ------------------------------
  475. c 7. Compute: W(t) = T(t)*P(t), i.e. w = tt * pt
  476. call dgemm('n','n',m,m,m,alpha,tt,m,pt,m,beta,w,m)
  477. c ------------------------------
  478. c 8. Compute: K(t) = W(t)*S(t)', i.e. k = w * s
  479. call dgemm('n','t',m,p,m,alpha,w,m,s(:,:,t),p,beta,
  480. + k(:,:,t),m)
  481. ! if(t.eq.1) then
  482. ! print *, "K = ", k(:,:,t)
  483. ! endif
  484. c ------------------------------
  485. c 9. Compute: L(t)= T(t) - K(t)*Z(t)
  486. c 9a. Initialise ls(:,:,t) = tt
  487. do i = 1, m
  488. call dcopy(m,tt(:,i),1,ls(:,i,t),1)
  489. enddo
  490. c 9b. Compute: ls = ls - k * z
  491. alpha = -1.0
  492. beta = 1.0
  493. call dgemm('n','n',m,m,p,alpha,k(:,:,t),m,z,p,beta,
  494. + ls(:,:,t),m)
  495. ! if(t.eq.1) then
  496. ! print *, "L = ", ls(:,:,t)
  497. ! endif
  498. c ------------------------------
  499. c Monitor convergence to steady state
  500. if(t.gt.chk) then
  501. if(mod(t,chk).eq.0) then
  502. temp = fnorm(ps(:,:,t),ps(:,:,t-chk),m,m)
  503. if(temp.lt.tol) then
  504. indr = 1
  505. lt = t
  506. endif
  507. endif
  508. endif
  509. c ------------------------------
  510. c 10. Compute: a(t+1)= T(t)*a(t) + K(t)*nu(t)
  511. c 10a. Compute: at = tt * a
  512. alpha = 1.0
  513. beta = 0.0
  514. call dgemv('n',m,m,alpha,tt,m,a(:,t),1,beta,at,1)
  515. c 10b. Compute: at = at + k * nu
  516. beta = 1.0
  517. call dgemv('n',m,p,alpha,k(:,:,t),m,nu(:,t),1,beta,at,1)
  518. c ------------------------------
  519. c 11. Compute: P(t+1)= W(t)*L(t)' + Q(t)
  520. c 11a. Initialise: pt = qt
  521. do i = 1, m
  522. call dcopy(m,qt(:,i),1,pt(:,i),1)
  523. enddo
  524. c 11b. Compute: pt = pt + w*ls
  525. beta = 1.0
  526. call dgemm('n','t',m,m,m,alpha,w,m,ls(:,:,t),m,beta,pt,m)
  527. c Reached steady state:
  528. else
  529. call dcopy(m,at,1,a(:,t),1)
  530. c do i=1,m
  531. c call dcopy(m,pt(:,i),1,ps(:,i,t),1)
  532. c enddo
  533. c ------------------------------
  534. c 12. Compute: Nu(t)= Y(t) - Z(t)*a(t)
  535. c 12a. Initialise: nu = y
  536. call dcopy(p,y(:,t),1,nu(:,t),1)
  537. c 12b. Compute: nu = nu + z * at
  538. alpha = -1.0
  539. beta = 1.0
  540. call dgemv('n',p,m,alpha,z,p,at,1,beta,nu(:,t),1)
  541. ! if(t.eq.1) then
  542. ! print *, "nu = ", nu(:,t)
  543. ! endif
  544. c ----------------------------------------
  545. if (ilike.eq.0) then
  546. call dcopy(p,nu(:,t),1,wl,1)
  547. call dtrsv('u','t','n',p,f,p,wl,1)
  548. llike = llike - 0.5*(logdet+ddot(p,wl,1,wl,1))
  549. c call dtrsm('l','u','t','n',p,1,alpha,f,p,wl,p)
  550. c call dtrsm('l','u','n','n',p,1,alpha,f,p,wl,p)
  551. c llike=llike-0.5*(logdet+ddot(p,wl,1,nu(:,t),1))
  552. endif
  553. c ------------------------------
  554. c 13. Compute: a(t+1)= T(t)*a(t)+K(t)*nu(t)
  555. c 13a. Compute: at = tt * a
  556. alpha = 1.0
  557. beta = 0.0
  558. call dgemv('n',m,m,alpha,tt,m,a(:,t),1,beta,at,1)
  559. c ------------------------------
  560. c 14. Compute: at = at + k * nu
  561. c Note: lt replaces t in k, i.e. k(:,:,lt)
  562. beta = 1.0
  563. call dgemv('n',m,p,alpha,k(:,:,lt),m,nu(:,t),1,beta,at,1)
  564. beta = 0.0
  565. c ------------------------------
  566. c P(t+1) = W(t)*L(t)' + Q(t)
  567. do i=1,m
  568. call dcopy(m,qt(:,i),1,pt(:,i),1)
  569. enddo
  570. beta = 1.0
  571. call dgemm('n','t',m,m,m,alpha,w,m,ls(:,:,lt),m,beta,pt,m)
  572. endif
  573. enddo
  574. lk = llike
  575. end
  576. c ------------------------------------------------------------------
  577. c benchmark subroutine for filtering with the standard state SSM
  578. subroutine bfilter(y,z,h,tt,qt,nu,k,f,fi,wz,a,at,pt,ps,mt,w,ls,
  579. + ifo, m, p, n, n_h, n_t, n_q, n_z)
  580. integer m,p,n,t,i,ifo, info
  581. integer n_h, n_t, n_q, n_z, t_t, t_z, t_h, t_q, timet
  582. real*8 y(p,n),z(p,m,n_z),h(p,p,n_h),tt(m,m,n_t),qt(m,m,n_q)
  583. real*8 nu(p,n),k(m,p,n),fi(p,p,n),ls(m,m,n),a(m,n),wz(m,p)
  584. real*8 ps(m,m,n),mt(m,p),at(m),pt(m,m),f(p,p),w(m,m)
  585. real*8 alpha, beta
  586. c ----------------------
  587. cf2py intent(in) y
  588. cf2py intent(in) z
  589. cf2py intent(in) h
  590. cf2py intent(in) tt
  591. cf2py intent(in) qt
  592. cf2py intent(inout) nu
  593. cf2py intent(inout) k
  594. cf2py intent(in) f
  595. cf2py intent(inout) fi
  596. cf2py intent(in) wz
  597. cf2py intent(inout) s
  598. cf2py intent(inout) a
  599. cf2py intent(in) at
  600. cf2py intent(in) pt
  601. cf2py intent(inout) ps
  602. cf2py intent(in) mt
  603. cf2py intent(in) w
  604. cf2py intent(inout) ifo
  605. cf2py intent(in) m
  606. cf2py intent(in) p
  607. cf2py intent(in) n
  608. cf2py intent(in) n_z
  609. cf2py intent(in) n_t
  610. cf2py intent(in) n_h
  611. cf2py intent(in) n_q
  612. c ----------------------
  613. ifo = 0
  614. do t = 1, n
  615. t_q = timet(n_q, t)
  616. t_z = timet(n_z, t)
  617. t_h = timet(n_h, t)
  618. t_t = timet(n_t, t)
  619. call dcopy(m,at,1,a(:,t),1)
  620. do i = 1, m
  621. call dcopy(m,pt(:,i),1,ps(:,i,t),1)
  622. enddo
  623. c Nu(t)= Y(t) - Z(t)*a(t)
  624. call dcopy(p,y(:,t),1,nu(:,t),1)
  625. alpha=-1.0
  626. beta=1.0
  627. call dgemv('n',p,m,alpha,z(:,:,t_z),p,at,1,beta,nu(:,t),1)
  628. alpha=1.0
  629. beta=0.0
  630. c m(t) = P(t)*Z(t)'
  631. call dgemm('n','t',m,p,m,alpha,pt,m,z(:,:,t_z),p,beta,mt,m)
  632. c F(t) = Z(t)*m(t)+H(t)
  633. do i=1,p
  634. call dcopy(p,h(:,i,t_h),1,f(:,i),1)
  635. enddo
  636. beta=1.0
  637. call dgemm('n','n',p,p,m,alpha,z(:,:,t_z),p,mt,m,beta,f,p)
  638. c calculate fi = inverse(f)
  639. call eye(fi(:,:,t),p)
  640. call dposv('u',p,p,f,p,fi(:,:,t),p,info)
  641. if (info.ne.0) then
  642. ifo=1
  643. endif
  644. beta=0.0
  645. c W(t) = T(t)*P(t)
  646. call dgemm('n','n',m,m,m,alpha,tt(:,:,t_t),m,pt,m,beta,w,m)
  647. c K(t) = W(t)*Z(t)'*inv(F(t))
  648. call dgemm('n','t',m,p,m,alpha,w,m,z(:,:,t_z),p,beta,wz,m)
  649. call dgemm('n','n',m,p,p,alpha,wz,m,fi(:,:,t),p,beta,
  650. + k(:,:,t),m)
  651. c L(t)=T(t)-K(t)*Z(t)
  652. do i=1,m
  653. call dcopy(m,tt(:,i,t_t),1,ls(:,i,t),1)
  654. enddo
  655. alpha=-1.0
  656. beta=1.0
  657. call dgemm('n','n',m,m,p,alpha,k(:,:,t),m,z(:,:,t_z),p,beta,
  658. + ls(:,:,t),m)
  659. alpha=1.0
  660. beta=0.0
  661. c a(t+1)=T(t)*a(t)+K(t)*nu(t)
  662. call dgemv('n',m,m,alpha,tt(:,:,t_t),m,a(:,t),1,beta,at,1)
  663. beta=1.0
  664. call dgemv('n',m,p,alpha,k(:,:,t),m,nu(:,t),1,beta,at,1)
  665. beta=0.0
  666. c P(t+1)=W(t)*L(t)'+Q(t)
  667. c call dgemm('n','n',m,m,m,alpha,tt(:,:,t),m,pt,m,beta,w,m)
  668. do i=1,m
  669. call dcopy(m,qt(:,i,t_q),1,pt(:,i),1)
  670. enddo
  671. beta=1.0
  672. call dgemm('n','t',m,m,m,alpha,w,m,ls(:,:,t),m,beta,pt,m)
  673. enddo
  674. end
  675. c ------------------------------------------------------------------
  676. c contemporaneous version of the kalman filter
  677. c subroutine for filtering with the standard state SSM
  678. subroutine cfilter(y,z,h,tt,qt,nu,f,s,a,at,pt,ps,mt,w,lk,wl,ifo,
  679. + ilike, m, p, n, n_z, n_t, n_h, n_q)
  680. integer m,p,n,t,i,ifo, info,ilike
  681. integer n_z, n_t, n_h, n_q, t_z, t_t, t_h, t_q, timet
  682. real*8 y(p,n),z(p,m,n_z),h(p,p,n_h),tt(m,m,n_t),qt(m,m,n_q)
  683. real*8 nu(p,n),s(p,m,n),a(m,n+1)
  684. real*8 ps(m,m,n+1),mt(p,m),at(m,n),pt(m,m,n),f(p,p),w(m,m,n)
  685. real*8 alpha, beta,lk(*),logdet,ddot,llike,wl(p)
  686. c ----------------------
  687. cf2py intent(in) y
  688. cf2py intent(in) z
  689. cf2py intent(in) h
  690. cf2py intent(in) tt
  691. cf2py intent(in) qt
  692. cf2py intent(inout) nu
  693. cf2py intent(inout) k
  694. cf2py intent(in) f
  695. cf2py intent(inout) s
  696. cf2py intent(inout) a
  697. cf2py intent(in) at
  698. cf2py intent(in) pt
  699. cf2py intent(inout) ps
  700. cf2py intent(in) mt
  701. cf2py intent(in) w
  702. cf2py intent(inout) lk
  703. cf2py intent(in) wl
  704. cf2py intent(inout) ifo
  705. cf2py intent(in) m
  706. cf2py intent(in) p
  707. cf2py intent(in) n
  708. cf2py intent(in) n_t
  709. cf2py intent(in) n_q
  710. cf2py intent(in) n_z
  711. cf2py intent(in) n_h
  712. c ----------------------
  713. c note if lk(1).lt.-1 then calculate likelihood and return in lk(1)
  714. ifo=0
  715. llike=0.0
  716. do t=1,n
  717. t_t = timet(n_t, t)
  718. t_z = timet(n_z, t)
  719. t_q = timet(n_q, t)
  720. t_h = timet(n_h, t)
  721. c Nu(t)= Y(t) - Z(t)*a(t)
  722. call dcopy(p,y(:,t),1,nu(:,t),1)
  723. alpha=-1.0
  724. beta=1.0
  725. call dgemv('n',p,m,alpha,z(:,:,t_z),p,a(:,t),1,beta,nu(:,t),1)
  726. alpha=1.0
  727. beta=0.0
  728. c m(t) = Z(t)*P(t)
  729. call dgemm('n','n',p,m,m,alpha,z(:,:,t_z),p,ps(:,:,t),m,beta,
  730. + mt,p)
  731. c F(t) = m(t)*Z(t)'+H(t)
  732. do i=1,p
  733. call dcopy(p,h(:,i,t_h),1,f(:,i),1)
  734. enddo
  735. beta=1.0
  736. call dgemm('n','t',p,p,m,alpha,mt,p,z(:,:,t_h),p,beta,f,p)
  737. c F(t)*S(t) = m(t); solve for S(t)=inv(F(t))*m(t)
  738. do i=1,m
  739. call dcopy(p,mt(:,i),1,s(:,i,t),1)
  740. enddo
  741. call dposv('u',p,m,f,p,s(:,:,t),p,info)
  742. if (info.ne.0) then
  743. ifo=1
  744. endif
  745. beta=0.0
  746. if (ilike.eq.0) then
  747. logdet=0.0
  748. do i=1,p
  749. logdet=logdet+log(f(i,i))
  750. enddo
  751. logdet=2.0*logdet
  752. call dcopy(p,nu(:,t),1,wl,1)
  753. call dtrsv('u','t','n',p,f,p,wl,1)
  754. llike=llike-0.5*(logdet+ddot(p,wl,1,wl,1))
  755. c call dtrsm('l','u','t','n',p,1,alpha,f,p,wl,p)
  756. c call dtrsm('l','u','n','n',p,1,alpha,f,p,wl,p)
  757. c llike=llike-0.5*(logdet+ddot(p,wl,1,nu(:,t),1))
  758. endif
  759. c a(t|t)=a(t)+S(t)'nu(t)
  760. alpha=1.0
  761. beta=1.0
  762. call dcopy(m,a(:,t),1,at(:,t),1)
  763. call dgemv('t',p,m,alpha,s(:,:,t),p,nu(:,t),1,beta,at(:,t),1)
  764. c P(t|t)=P(t)-m(t)'S(t)
  765. do i=1,m
  766. call dcopy(m,ps(:,i,t),1,pt(:,i,t),1)
  767. enddo
  768. alpha=-1.0
  769. beta=1.0
  770. call dgemm('t','n',m,m,p,alpha,mt,p,s(:,:,t),p,beta,
  771. + pt(:,:,t),m)
  772. c W(t) = P(t)*T(t)'
  773. alpha=1.0
  774. beta=0.0
  775. call dgemm('n','t',m,m,m,alpha,pt(:,:,t),m,tt(:,:,t_t),m,beta,
  776. + w(:,:,t), m)
  777. c a(t+1)=T(t)*a(t|t)
  778. call dgemv('n',m,m,alpha,tt(:,:,t_t),m,at(:,t),1,beta,
  779. + a(:,t+1), 1)
  780. c P(t+1)=T(t)*W(t)+Q(t)
  781. beta=1.0
  782. do i=1,m
  783. call dcopy(m,qt(:,i,t),1,ps(:,i,t+1),1)
  784. enddo
  785. call dgemm('n','n',m,m,m,alpha,tt(:,:,t),m,w(:,:,t),m,beta,
  786. + ps(:,:,t+1),m)
  787. enddo
  788. lk(1)=llike
  789. end
  790. c ------------------------------------------------------------------
  791. c contemporaneous version of the kalman filter
  792. c subroutine for filtering with the standard state SSM
  793. c non-time varying system matricies
  794. subroutine ntcfilter(t_last,y,z,h,tt,qt,nu,f,s,a,at,pt,ps,mt,
  795. + w, lk, wl,ifo, ilike, m,p,n)
  796. integer m,p,n,t,it,t_last,i,ifo,info,ilike,chk,flag_steady
  797. real*8 y(p,n),z(p,m),h(p,p),tt(m,m),qt(m,m), tol
  798. real*8 nu(p,n),s(p,m,n),a(m,n+1),fnorm
  799. real*8 ps(m,m,n+1),mt(p,m),at(m,n),pt(m,m,n),f(p,p),w(m,m,n)
  800. real*8 alpha, beta,lk(*),logdet,ddot,llike,wl(p), temp
  801. c ----------------------
  802. cf2py intent(inout) t_last
  803. cf2py intent(in) y
  804. cf2py intent(in) z
  805. cf2py intent(in) h
  806. cf2py intent(in) tt
  807. cf2py intent(in) qt
  808. cf2py intent(inout) nu
  809. cf2py intent(inout) k
  810. cf2py intent(in) f
  811. cf2py intent(inout) s
  812. cf2py intent(inout) a
  813. cf2py intent(inout) at
  814. cf2py intent(in) pt
  815. cf2py intent(inout) ps
  816. cf2py intent(in) mt
  817. cf2py intent(in) w
  818. cf2py intent(inout) lk
  819. cf2py intent(in) wl
  820. cf2py intent(inout) ifo
  821. cf2py intent(in) m
  822. cf2py intent(in) p
  823. cf2py intent(in) n
  824. c ----------------------
  825. c Note: ps == P(t)
  826. c note if lk(1).lt.-1 then calculate likelihood and return in lk(1)
  827. chk = 10
  828. ifo = 0
  829. t_last = n + 1
  830. tol = 1E-10
  831. logdet = 0.0
  832. llike = 0.0
  833. flag_steady = 0 ! Indicator that steady state reached
  834. do t = 1, n
  835. c 1. Compute: Nu(t)= Y(t) - Z(t)*a(t)
  836. c 1a. Initialise: nu(:,t) = y(:,t)
  837. call dcopy(p,y(:,t),1,nu(:,t),1)
  838. c 1b. Compute: nu(:,t) = nu(:,t) + z * a(:,t)
  839. alpha = -1.0
  840. beta = 1.0
  841. call dgemv('n',p,m,alpha,z,p,a(:,t),1,beta,nu(:,t),1)
  842. c ---------------------------------------
  843. c NOTE: Step 2 - 7 do not need to be computed once steady state reached
  844. if(flag_steady.eq.0) then
  845. c 2. Compute: m(t) = Z(t)*P(t), i.e. mt = z * ps(:,:,t)
  846. alpha = 1.0
  847. beta = 0.0
  848. call dgemm('n','n',p,m,m,alpha,z,p,ps(:,:,t),m,beta,
  849. + mt,p)
  850. c ---------------------------------------
  851. c 3. Compute: F(t) = m(t)*Z(t)'+ H(t)
  852. c 3a. Initialise: f(:,:) = h(:,:)
  853. do i = 1, p
  854. call dcopy(p, h(:,i), 1, f(:,i), 1)
  855. enddo
  856. c 3b. Compute: f = f + mt * z'
  857. beta = 1.0
  858. call dgemm('n','t',p,p,m,alpha,mt,p,z,p,beta,f,p)
  859. c ---------------------------------------
  860. c Calculate log-likelihood component
  861. if (ilike.eq.0) then
  862. logdet = 0.0
  863. do i = 1, p
  864. logdet = logdet + 2.0 * log(f(i,i))
  865. enddo
  866. endif
  867. c ---------------------------------------
  868. c 4. Compute: S(t) = inv(F(t)) * m(t)
  869. c by solving system F(t)*S(t) = m(t)
  870. c 4a. Initialise s(:,:,t) = mt
  871. do i = 1, m
  872. call dcopy(p,mt(:,i),1,s(:,i,t),1)
  873. enddo
  874. c 4b. Solve f x = s and set s = x
  875. call dposv('u',p,m,f,p,s(:,:,t),p,info)
  876. if (info.ne.0) then
  877. ifo = 1
  878. print *, 'Error: Failed to solve [ntcfilter:4b]'
  879. endif
  880. c ---------------------------------------
  881. c 5. Compute: P(t|t) = P(t) - S(t)'m(t)
  882. c 5a. Initialise: pt(:,:,t) = ps(:,:,t)
  883. do i = 1, m
  884. call dcopy(m,ps(:,i,t),1,pt(:,i,t),1)
  885. enddo
  886. c 5b. Compute: pt = pt - s' * mt
  887. alpha = -1.0
  888. beta = 1.0
  889. call dgemm('t','n',m,m,p,alpha,s(:,:,t),p,mt,p,beta,
  890. + pt(:,:,t),m)
  891. c ---------------------------------------
  892. c 6. Compute: W(t) = T(t) * P(t|t), i.e. w = tt * pt
  893. alpha = 1.0
  894. beta = 0.0
  895. call dgemm('n','t',m,m,m,alpha,tt,m,pt(:,:,t),m,beta,
  896. + w(:,:,t), m)
  897. c ---------------------------------------
  898. c 7. Compute: P(t+1) = W(t)*T(t)' + Q(t)
  899. c 7a. Initialise: ps(:,:, t+1) = qt
  900. beta = 1.0
  901. do i = 1, m
  902. call dcopy(m,qt(:,i),1,ps(:,i,t+1),1)
  903. enddo
  904. c 7b. Compute: ps = ps + w * tt'
  905. call dgemm('n','t',m,m,m,alpha,w(:,:,t),m,tt,m,beta,
  906. + ps(:,:,t+1),m)
  907. c ---------------------------------------
  908. endif ! FINISH CALCS FOR NO STEADY STATE SITUATION
  909. c ----------------------------------------------------
  910. c NOTE: This must always be computed at time t
  911. if (ilike.eq.0) then
  912. c Initialise: wl = nu(:,t)
  913. call dcopy(p,nu(:,t),1,wl,1)
  914. c Solve: f x = wl and set wl = x
  915. call dtrsv('u','t','n',p,f,p,wl,1)
  916. llike = llike -0.5*(logdet + ddot(p,wl,1,wl,1))
  917. endif
  918. if (flag_steady.eq.0) then
  919. it = t
  920. else
  921. it = t_last
  922. endif
  923. c ---------------------------------------
  924. c NOTE: Step 8 and 9 must always be computed at time t
  925. c 8. Compute: a(t|t) = a(t) + S(t)'nu(t)
  926. alpha = 1.0
  927. beta = 1.0
  928. c 8a. Initialise: at(:,t) = a(:,t)
  929. call dcopy(m,a(:,t),1,at(:,t),1)
  930. c 8b. Compute: at = at + s' * nu
  931. c NOTE: s(:,:,t or lt) depending on whether steady state reached
  932. call dgemv('t',p,m,alpha,s(:,:,it),p,nu(:,t),1,beta,at(:,t),1)
  933. c ---------------------------------------
  934. c 9. Compute: a(t+1) = T(t) * a(t|t), i.e. a = tt * at
  935. call dgemv('n',m,m,alpha,tt,m,at(:,t),1,beta,a(:,t+1),
  936. + 1)
  937. c ---------------------------------------
  938. c Monitor convergence to steady state if not already occurred
  939. if (flag_steady.eq.0) then ! i.e Not yet reached
  940. if(t.gt.chk) then
  941. if (mod(t,chk).eq.0) then ! i.e. check regularly
  942. temp = fnorm(ps(:,:,t),ps(:,:,t-chk),m,m)
  943. if(temp.lt.tol) then
  944. flag_steady = 1 ! Update flag
  945. t_last = t ! Record when steady state occurs
  946. endif
  947. endif
  948. endif
  949. endif
  950. enddo
  951. lk(1) = llike
  952. end
  953. c ------------------------------------------------------------------
  954. c subroutine for smoothing. Standard state space model. Time varying
  955. c system matricies.
  956. subroutine smoother(ah,s,nu,ls,r,ltr,as,ps,pmiss,p,m,n)
  957. integer p,m,n,t,i,pmiss(n)
  958. real*8 ah(m,n),s(p,m,n),nu(p,n),ls(m,m,n),r(m),ltr(m)
  959. real*8 as(m,n), ps(m,m,n)
  960. real*8 alpha, beta
  961. c ----------------------
  962. cf2py intent(inout) ah
  963. cf2py intent(in) s
  964. cf2py intent(in) nu
  965. cf2py intent(in) ls
  966. cf2py intent(in) r
  967. cf2py intent(in) ltr
  968. cf2py intent(in) as
  969. cf2py intent(in) ps
  970. cf2py intent(in) p
  971. cf2py intent(in) m
  972. cf2py intent(in) n
  973. c ----------------------
  974. c Initialise vector
  975. do i = 1, m
  976. r(i) = 0.0
  977. enddo
  978. alpha = 1.0
  979. do t = n, 1, -1
  980. c Step 1: Compute r(t-1) = S(t)' * nu(t) + L(t)' * r(t)
  981. beta = 0.0
  982. c 1a. Compute: ltr = ls(:,:,t) * r
  983. call dgemv('t',m,m,alpha,ls(:,:,t),m,r,1,beta,ltr,1)
  984. c 1b. Initialise r: i.e. r = ltr
  985. call dcopy(m, ltr, 1, r, 1)
  986. if (pmiss(t).eq.0) then
  987. !data not missing
  988. beta = 1.0
  989. c 1c. Compute: r = (s * nu) + r
  990. call dgemv('t',p,m,alpha,s(:,:,t),p,nu(:,t),1,beta,r,1)
  991. endif
  992. c Step 2: Compute ahat(t) = a(t) + P(t) * r(t-1)
  993. c 2a. Initialise as: i.e. ah(:,t) = as(:, t)
  994. call dcopy(m, as(:,t), 1, ah(:,t), 1)
  995. c 2b. Compute: ah = ah + ps*r
  996. beta = 1.0
  997. call dgemv('n',m,m,alpha, ps(:,:,t), m, r,1, beta, ah(:,t),1)
  998. enddo
  999. end
  1000. c ------------------------------------------------------------------
  1001. c subroutine for smoothing. Standard state space model. Non time varying system matricies.
  1002. subroutine ntsmoother(ah,s,nu,ls,r,ltr,as,ps,lt,p,m,n)
  1003. integer p,m,n,t,i,lt,it
  1004. real*8 ah(m,n),s(p,m,n),nu(p,n),ls(m,m,n),r(m),ltr(m)
  1005. real*8 as(m,n), ps(m,m,n)
  1006. real*8 alpha, beta
  1007. c ----------------------
  1008. cf2py intent(inout) ah
  1009. cf2py intent(in) s
  1010. cf2py intent(in) nu
  1011. cf2py intent(in) ls
  1012. cf2py intent(in) r
  1013. cf2py intent(in) ltr
  1014. cf2py intent(in) as
  1015. cf2py intent(in) ps
  1016. cf2py intent(in) lt
  1017. cf2py intent(in) p
  1018. cf2py intent(in) m
  1019. cf2py intent(in) n
  1020. c ----------------------
  1021. c Initialise vector
  1022. do i = 1, m
  1023. r(i) = 0.0
  1024. enddo
  1025. alpha = 1.0
  1026. do t = n, 1, -1
  1027. if (t.gt.lt) then
  1028. it = lt
  1029. else
  1030. it = t
  1031. endif
  1032. c Step 1: Compute r(t-1) = S(t)'*nu(t) + L(t)'r(t)
  1033. beta = 0.0
  1034. c 1a. Compute: ltr = ls * r
  1035. call dgemv('t',m,m,alpha,ls(:,:,it),m,r,1,beta,ltr,1)
  1036. c 1b. Initialise: r = ltr
  1037. call dcopy(m,ltr,1,r,1)
  1038. c 1c. Compute: r = r + s * nu
  1039. beta = 1.0
  1040. call dgemv('t',p,m,alpha,s(:,:,it),p,nu(:,t),1,beta,r,1)
  1041. c -----------------------------------------------
  1042. c Step 2: Compute ahat(t) = a(t) + P(t)*r(t-1)
  1043. c 2. Initialise ah = as
  1044. call dcopy(m,as(:,t),1,ah(:,t),1)
  1045. c 2b. Compute: ah = ah + ps * r
  1046. call dgemv('n',m,m,alpha,ps(:,:,it),m,r,1,beta,ah(:,t),1)
  1047. enddo
  1048. end
  1049. c ------------------------------------------------------------------
  1050. c subroutine for state disturbance smoother
  1051. subroutine dsmoother(ehat,nu,st,jt,rt,ls,ltr,pmiss,p,m,n,r)
  1052. implicit none
  1053. integer p, m, n, r, t, i, pmiss(n)
  1054. real*8 nu(p,n), st(p,m,n), jt(r,m,n), rt(m), ls(m,m,n)
  1055. real*8 alpha, beta, ehat(r,n), ltr(m)
  1056. c ----------------------
  1057. cf2py intent(in) nu
  1058. cf2py intent(in) st
  1059. cf2py intent(in) jt
  1060. cf2py intent(in) rt
  1061. cf2py intent(in) ls
  1062. cf2py intent(inout) ehat
  1063. cf2py intent(in) ltr
  1064. cf2py intent(in) pmiss
  1065. cf2py intent(in) p
  1066. cf2py intent(in) m
  1067. cf2py intent(in) n
  1068. cf2py intent(in) r
  1069. c ----------------------
  1070. c Initialise rt array
  1071. do i = 1, m
  1072. rt(i) = 0.0
  1073. enddo
  1074. alpha = 1.0
  1075. do t = n, 1, -1
  1076. c 1. Compute: ehat(t) = J(t) * rt
  1077. beta = 0.0
  1078. call dgemv('n',r,m,alpha,jt(:,:,t),r,rt,1,beta,ehat(:,t),1)
  1079. c ---------------------------------------------
  1080. c 2. Compute: r(t-1) = S(t)'.nu(t) + L(t)'.r(t)
  1081. beta = 0.0
  1082. c 2a. Compute: ltr = ls(t)' * rt
  1083. call dgemv('t',m,m,alpha,ls(:,:,t),m,rt,1,beta,ltr,1)
  1084. c 2b. Initialise: rt = ltr
  1085. call dcopy(m,ltr,1,rt,1)
  1086. beta = 1.0
  1087. if (pmiss(t).eq.0) then
  1088. c 2c. Compute: rt = rt + st'.nu
  1089. call dgemv('t',p,m,alpha,st(:,:,t),p,nu(:,t),1,beta,rt,1)
  1090. endif
  1091. enddo
  1092. end
  1093. c ------------------------------------------------------------------
  1094. c subroutine for state disturbance smoother
  1095. subroutine ntdsmoother(ehat,nu,st,jt,rt,ls,ltr,lt,p,m,n,r)
  1096. implicit none
  1097. integer p,m,n,r,lt,it,t,i
  1098. real*8 nu(p,n),st(p,m,n),jt(r,m),rt(m),ls(m,m,n)
  1099. real*8 alpha,beta,ehat(r,n),ltr(m)
  1100. c NOTE: r(t) is input, used in calcs, then over written with r(t-1)
  1101. c ----------------------
  1102. cf2py intent(in) nu
  1103. cf2py intent(in) st
  1104. cf2py intent(in) jt
  1105. cf2py intent(in) rt
  1106. cf2py intent(in) ls
  1107. cf2py intent(inout) ehat
  1108. cf2py intent(in) ltr
  1109. cf2py intent(in) lt
  1110. cf2py intent(in) p
  1111. cf2py intent(in) m
  1112. cf2py intent(in) n
  1113. cf2py intent(in) r
  1114. c ----------------------
  1115. c Initialise rt array
  1116. do i = 1, m
  1117. rt(i) = 0.0
  1118. enddo
  1119. alpha = 1.0
  1120. do t = n, 1, -1
  1121. if (t.gt.lt) then
  1122. it = lt
  1123. else
  1124. it = t
  1125. endif
  1126. c --------------------------------
  1127. c 1. Compute: etahat = J(t)*r(t)
  1128. beta = 0.0
  1129. call dgemv('n',r,m,alpha,jt,r,rt,1,beta,ehat(:,t),1)
  1130. c -----------------------------------------------
  1131. c 2. Compute: r(t-1) = S(t)'.nu(t) + L(t)'.r(t)
  1132. c 2a. Compute: ltr = ls'.rt
  1133. beta = 0.0
  1134. call dgemv('t',m,m,alpha,ls(:,:,it),m,rt,1,beta,ltr,1)
  1135. c 2b. Initialise: rt = ltr
  1136. call dcopy(m,ltr,1,rt,1)
  1137. beta = 1.0
  1138. c 2c. Compute: rt = rt + st'.nu
  1139. call dgemv('t',p,m,alpha,st(:,:,it),p,nu(:,t),1,beta,rt,1)
  1140. enddo
  1141. end
  1142. c ------------------------------------------------------------------
  1143. c subroutine calculates the Frobenius norm for the difference of two matrices
  1144. real*8 function fnorm(a,b,m,n)
  1145. implicit none
  1146. integer m,n,i,j
  1147. real*8 a(m,n), b(m,n), sumd
  1148. sumd = 0.0
  1149. do j = 1, n
  1150. do i = 1, m
  1151. sumd = sumd + (a(i,j)-b(i,j))**2
  1152. enddo
  1153. enddo
  1154. fnorm = sqrt(sumd)
  1155. return
  1156. end
  1157. c ------------------------------------------------------------------
  1158. c benchmark simulation smoothing routine
  1159. subroutine bsmoother(ah,z,fi,fn,nu,ls,r,ltr,as,ps,p,m,n, n_z)
  1160. integer p,m,n,t,i, n_z, t_z, timet
  1161. real*8 ah(m,n),z(p,m,n_z),fi(p,p,n),fn(p),nu(p,n),ls(m,m,n),r(m)
  1162. real*8 as(m,n), ps(m,m,n),ltr(m)
  1163. real*8 alpha, beta
  1164. c ----------------------
  1165. cf2py intent(inout) ah
  1166. cf2py intent(in) fi
  1167. cf2py intent(in) fn
  1168. cf2py intent(in) nu
  1169. cf2py intent(in) ls
  1170. cf2py intent(in) r
  1171. cf2py intent(in) ltr
  1172. cf2py intent(in) as
  1173. cf2py intent(in) ps
  1174. cf2py intent(in) p
  1175. cf2py intent(in) m
  1176. cf2py intent(in) n
  1177. cf2py intent(in) n_z
  1178. c ----------------------
  1179. do i = 1,m
  1180. r(i) = 0.0
  1181. enddo
  1182. alpha = 1.0
  1183. do t = n, 1, -1
  1184. t_z = timet(n_z, t)
  1185. c r(t-1)=Z(t)'inv(F(t))*nu(t)+L(t)'r(t)
  1186. beta = 0.0
  1187. call dgemv('t',m,m,alpha,ls(:,:,t),m,r,1,beta,ltr,1)
  1188. call dcopy(m,ltr,1,r,1)
  1189. call dgemv('n',p,p,alpha,fi(:,:,t),p,nu(:,t),1,beta,fn,1)
  1190. beta = 1.0
  1191. call dgemv('t',p,m,alpha,z(:,:,t_z),p,fn,1,beta,ltr,1)
  1192. call dcopy(m,ltr,1,r,1)
  1193. c ahat(t)=a(t)+P(t)*r(t-1)
  1194. call dcopy(m,as(:,t),1,ah(:,t),1)
  1195. call dgemv('n',m,m,alpha,ps(:,:,t),m,r,1,beta,ah(:,t),1)
  1196. enddo
  1197. end
  1198. c ------------------------------------------------------------------
  1199. c Procedure to initialise an identity matrix of specified dimension
  1200. subroutine eye(a,m)
  1201. integer m, i, j
  1202. real*8 a(m,m)
  1203. do i = 1, m
  1204. do j = 1, m
  1205. a(i,j) = 0.0
  1206. enddo
  1207. a(i,i) = 1.0
  1208. enddo
  1209. end
  1210. c ------------------------------------------------------------------
  1211. c de Jong and Shephard simulation smoother
  1212. subroutine dssimsm(eta,s,nu,z,w,u,ls,rt,nt,v,nl,jt,
  1213. + ct,nj,lr,qt,ifo,pmiss,p,m,r,n, n_z, n_q)
  1214. implicit none
  1215. integer ifo,info,p,m,r,n,t,i,j, t_z, n_z, t_q, n_q, timet
  1216. integer pmiss(n)
  1217. real*8 eta(r,n),s(p,m,n),nu(p,n), z(p,m,n_z), w(r,m), u(r)
  1218. real*8 ls(m,m,n),rt(m),nt(m,m),v(r,m),nl(m,m),jt(r,m,n)
  1219. real*8 ct(r,r),nj(m,r),lr(m), qt(r,r,n_q)
  1220. real*8 alpha,beta
  1221. c on entry eta is a matrix of random normals on exit it is a
  1222. c sample of eta
  1223. c ----------------------
  1224. cf2py intent(inout) eta
  1225. cf2py intent(in) s
  1226. cf2py intent(in) nu
  1227. cf2py intent(in) z
  1228. cf2py intent(in) w
  1229. cf2py intent(in) u
  1230. cf2py intent(in) ls
  1231. cf2py intent(inout) rt
  1232. cf2py intent(in) nt
  1233. cf2py intent(in) v
  1234. cf2py intent(in) nl
  1235. cf2py intent(in) jt
  1236. cf2py intent(in) ct
  1237. cf2py intent(in) nj
  1238. cf2py intent(in) lr
  1239. cf2py intent(in) qt
  1240. cf2py intent(in) pmiss
  1241. cf2py intent(inout) ifo
  1242. cf2py intent(in) p
  1243. cf2py intent(in) m
  1244. cf2py intent(in) r
  1245. cf2py intent(in) n
  1246. cf2py intent(in) n_z
  1247. cf2py intent(in) n_q
  1248. c ----------------------
  1249. do j = 1, m
  1250. rt(j) = 0.0
  1251. do i = 1, m
  1252. nt(i,j) = 0.0
  1253. enddo
  1254. enddo
  1255. do t = n, 1, -1
  1256. t_z = timet(n_z, t)
  1257. t_q = timet(n_q, t)
  1258. alpha = 1.0
  1259. beta = 0.0
  1260. c NL(t) = N(t) * L(t)
  1261. call dgemm('n','n',m,m,m,alpha,nt,m,ls(:,:,t),m,beta,nl,m)
  1262. c W(t) = J(t) * NL(t)
  1263. call dgemm('n','n',r,m,m,alpha,jt(:,:,t),r,nl,m,beta,w,r)
  1264. c NJ(t) = N(t) * J(t)'
  1265. call dgemm('n','t',m,r,m,alpha,nt,m,jt(:,:,t),r,beta,nj,m)
  1266. c C(t) = Q(t)-J(t) * NJ(t)
  1267. do i=1,r
  1268. call dcopy(r,qt(:,i,t_q),1,ct(:,i),1)
  1269. enddo
  1270. alpha = -1.0
  1271. beta = 1.0
  1272. call dgemm('n','n',r,r,m,alpha,jt(:,:,t),r,nj,m,beta,ct,r)
  1273. c C(t) * V(t) = W(t); solve for V(t)
  1274. do i = 1, m
  1275. call dcopy(r,w(:,i),1,v(:,i),1)
  1276. enddo
  1277. call dposv('u',r,m,ct,r,v,r,info)
  1278. if (info.ne.0) then
  1279. ifo = 1
  1280. endif
  1281. c d(t)~N(0,C(t)); on exit eta(:,t) = d(t)
  1282. call dtrmv('u','t','n',r,ct,r,eta(:,t),1)
  1283. c C(t) * U(t) = d(t); solve for U(t)
  1284. call dcopy(r,eta(:,t),1,u,1)
  1285. call dtrsv('u','t','n',r,ct,r,u,1)
  1286. call dtrsv('u','n','n',r,ct,r,u,1)
  1287. c eta = d(t) + J(t) * r(t)
  1288. alpha = 1.0
  1289. beta = 1.0
  1290. call dgemv('n',r,m,alpha,jt(:,:,t),r,rt,1,beta,eta(:,t),1)
  1291. c r(t) = S(t)' * nu(t) - W(t)' * U(t) + l(t)'r(t)
  1292. beta = 0.0
  1293. call dgemv('t',m,m,alpha,ls(:,:,t),m,rt,1,beta,lr,1)
  1294. call dcopy(m,lr,1,rt,1)
  1295. alpha = -1.0
  1296. beta = 1.0
  1297. call dgemv('t',r,m,alpha,w,r,u,1,beta,rt,1)
  1298. alpha = 1.0
  1299. if (pmiss(t).eq.0) then
  1300. call dgemv('t',p,m,alpha,s(:,:,t),p,nu(:,t),1,beta,rt,1)
  1301. endif
  1302. c N(t) = S(t)'Z(t) + W(t)'V(t) +L(t)'NL(t)
  1303. beta = 0.0
  1304. call dgemm('t','n',m,m,m,alpha,ls(:,:,t),m,nl,m,beta,nt,m)
  1305. beta = 1.0
  1306. call dgemm('t','n',m,m,r,alpha,w,r,v,r,beta,nt,m)
  1307. if (pmiss(t).eq.0) then
  1308. call dgemm('t','n',m,m,p,alpha,s(:,:,t),p,z(:,:,t_z),p,
  1309. + beta,nt,m)
  1310. endif
  1311. enddo
  1312. end
  1313. c ------------------------------------------------------------------
  1314. c de Jong and Shephard simulation smoother non time varying system
  1315. c matricies
  1316. subroutine ntdssimsm(eta,s,nu,z,w,u,ls,rt,nt,v,nl,jt,
  1317. + ct,nj,lr,qt,lt,ifo,p,m,r,n)
  1318. implicit none
  1319. integer ifo,info,lt,it,p,m,r,n,t,i,j
  1320. real*8 eta(r,n),s(p,m,n),nu(p,n),z(p,m),w(r,m),u(r)
  1321. real*8 ls(m,m,n),rt(m),nt(m,m),v(r,m),nl(m,m),jt(r,m)
  1322. real*8 ct(r,r),nj(m,r),lr(m),qt(r,r)
  1323. real*8 alpha,beta
  1324. c on entry eta is a matrix of random normals on exit it is a
  1325. c sample of eta
  1326. c ----------------------
  1327. cf2py intent(inout) eta
  1328. cf2py intent(in) s
  1329. cf2py intent(in) nu
  1330. cf2py intent(in) z
  1331. cf2py intent(in) w
  1332. cf2py intent(in) u
  1333. cf2py intent(in) ls
  1334. cf2py intent(inout) rt
  1335. cf2py intent(in) nt
  1336. cf2py intent(in) lt
  1337. cf2py intent(in) v
  1338. cf2py intent(in) nl
  1339. cf2py intent(in) jt
  1340. cf2py intent(in) ct
  1341. cf2py intent(in) nj
  1342. cf2py intent(in) lr
  1343. cf2py intent

Large files files are truncated, but you can click here to view the full file