dim_m = 4 m = np.linspace(1, dim_m, dim_m).reshape((dim_m, 1)) D = np.random.randn(dim_m**2).reshape((dim_m, dim_m)) U,S,VT = np.linalg.svd(D) C = U.dot(np.diag(S**2)).dot(U.T) invC = U.dot(np.diag(1/S**2)).dot(U.T) C_cholesky = U.dot(np.diag(S)) checkvalue = np.linalg.norm(C - C_cholesky.dot(C_cholesky.T))/np.linalg.norm(C) assert checkvalue < 2e-16, checkvalue checkvalue2 = np.linalg.norm(C.dot(invC) - np.eye(dim_m)) assert checkvalue2 < 1e-12, checkvalue2 ####################### Multivariate Gaussian ################## sample_size = 100000 samples = SampleMultivariateNormal(m, C_cholesky, sample_size) m_emp = samples.sum(axis=1).reshape((dim_m,1))/sample_size m_one = m.dot(np.ones((1,sample_size))) C_emp = ((samples-m_one).dot((samples-m_one).T))/sample_size print "Test Multivariate Gaussian:" print "m, m_emp, m-m_emp: " print np.concatenate((m, m_emp, m-m_emp), axis=1) print np.sqrt(np.sum((m_emp-m)**2))/np.sqrt(np.sum(m**2)) print "C, C_emp, C-C_emp: " print C print C_emp print C-C_emp print np.linalg.norm(C-C_emp)/np.linalg.norm(C) ########################## Wishart ############################# sample_size = 10000
def BackwardSampling_SVD(Gt, svd_invW, m0, m_all, svd_C0, C_all, a_all, R_all): """ Sample from the joint distribution (theta_{0:T} | y_{1:T}) Inputs: Gt = list of matrices containing definition of DLM svd_invW = [U, S] such that U.S.U^T = W^{-1} (W = covariance matrix for evolution equation) m0, C0 = parameters of initial distribution m_all, C_all, a_all, R_all = output from KalmanFilter_SVD Outputs: thetas = joint draw from (theta_{0:T} | y_{1:T}) maxVarB = maximum variance in B at each time step (diagonal only) """ timesteps, parameters = m_all.shape thetas = np.zeros((timesteps+1, parameters)) invGam = svd_invW[0].dot(np.diag(np.sqrt(svd_invW[1]))) # Sample at time t=T h = m_all[timesteps-1,:].reshape((parameters,1)) C = C_all[-1] B_ch = C[0].dot(np.diag(C[1])) theta = SampleMultivariateNormal(h, B_ch) thetas[-1,:] = theta.reshape((1, parameters)) maxVarB = [] # To check, compute sT: # s_all, S_all = np.zeros(m_all.shape), [] # s = m_all[timesteps-1,:].reshape((parameters,1)) # s_all[timesteps-1,:] = s.T # Sfull = C[0].dot(np.diag(C[1]**2)).dot(C[0].T) # S_all.append(Sfull) # Iterate starting from t=T down to t=1: ii = timesteps - 2 for G, Rsvd in zip(reversed(Gt), reversed(R_all)): a = a_all[ii+1,:].reshape((parameters,1)) if ii < 0: m = m0.reshape((parameters,1)) C = svd_C0[0].dot(np.diag(svd_C0[1])).dot(svd_C0[0].T) invR = Rsvd[0].dot(np.diag(1/Rsvd[1]**2)).dot(Rsvd[0].T) CGinvR = C.dot(G.T).dot(invR) h = m + CGinvR.dot(theta - a) tmp = (invGam.T).dot(G).dot(svd_C0[0]) A, invD, ET = svd(np.concatenate((tmp, \ np.diag(1/np.sqrt(svd_C0[1]))), axis=0)) U = svd_C0[0].dot(ET.T) B_ch = U.dot(np.diag(1/invD)) theta = SampleMultivariateNormal(h, B_ch) thetas[ii+1,:] = theta.reshape((1, parameters)) maxVarB.append(np.abs(np.diag(B_ch.dot(B_ch.T))).max()) break m = m_all[ii,:].reshape((parameters,1)) Csvd = C_all[ii] C = Csvd[0].dot(np.diag(Csvd[1]**2)).dot(Csvd[0].T) invR = Rsvd[0].dot(np.diag(1/Rsvd[1]**2)).dot(Rsvd[0].T) CGinvR = C.dot(G.T).dot(invR) h = m + CGinvR.dot(theta - a) tmp = (invGam.T).dot(G).dot(Csvd[0]) A, invD, ET = svd(np.concatenate((tmp, np.diag(1/Csvd[1])), axis=0)) U = Csvd[0].dot(ET.T) B_ch = U.dot(np.diag(1/invD)) theta = SampleMultivariateNormal(h, B_ch) thetas[ii+1,:] = theta.reshape((1, parameters)) maxVarB.append(np.abs(np.diag(B_ch.dot(B_ch.T))).max()) # To check, compute st # s = m + CGinvR.dot(s - a) # s_all[ii,:] = s.T # Bfull = C - CGinvR.dot(G).dot(C) # Bfull = C - C.dot(G.T).dot(invR).dot(G).dot(C) # invBfullbis = np.linalg.inv(C) + \ # (G.T).dot(np.linalg.inv(W)).dot(G) # Bfullbis = np.linalg.inv(invBfullbis) # Rfull = Rsvd[0].dot(np.diag(Rsvd[1]**2)).dot(Rsvd[0].T) # Sfull = C - CGinvR.dot(Rfull-Sfull).dot(CGinvR.T) # S_all.append(Sfull) ii -= 1 return thetas, maxVarB
def BackwardSampling_SVD(Gt, svd_invW, m0, m_all, svd_C0, C_all, a_all, R_all): """ Sample from the joint distribution (theta_{0:T} | y_{1:T}) Inputs: Gt = list of matrices containing definition of DLM svd_invW = [U, S] such that U.S.U^T = W^{-1} (W = covariance matrix for evolution equation) m0, C0 = parameters of initial distribution m_all, C_all, a_all, R_all = output from KalmanFilter_SVD Outputs: thetas = joint draw from (theta_{0:T} | y_{1:T}) maxVarB = maximum variance in B at each time step (diagonal only) """ timesteps, parameters = m_all.shape thetas = np.zeros((timesteps + 1, parameters)) invGam = svd_invW[0].dot(np.diag(np.sqrt(svd_invW[1]))) # Sample at time t=T h = m_all[timesteps - 1, :].reshape((parameters, 1)) C = C_all[-1] B_ch = C[0].dot(np.diag(C[1])) theta = SampleMultivariateNormal(h, B_ch) thetas[-1, :] = theta.reshape((1, parameters)) maxVarB = [] # To check, compute sT: # s_all, S_all = np.zeros(m_all.shape), [] # s = m_all[timesteps-1,:].reshape((parameters,1)) # s_all[timesteps-1,:] = s.T # Sfull = C[0].dot(np.diag(C[1]**2)).dot(C[0].T) # S_all.append(Sfull) # Iterate starting from t=T down to t=1: ii = timesteps - 2 for G, Rsvd in zip(reversed(Gt), reversed(R_all)): a = a_all[ii + 1, :].reshape((parameters, 1)) if ii < 0: m = m0.reshape((parameters, 1)) C = svd_C0[0].dot(np.diag(svd_C0[1])).dot(svd_C0[0].T) invR = Rsvd[0].dot(np.diag(1 / Rsvd[1]**2)).dot(Rsvd[0].T) CGinvR = C.dot(G.T).dot(invR) h = m + CGinvR.dot(theta - a) tmp = (invGam.T).dot(G).dot(svd_C0[0]) A, invD, ET = svd(np.concatenate((tmp, \ np.diag(1/np.sqrt(svd_C0[1]))), axis=0)) U = svd_C0[0].dot(ET.T) B_ch = U.dot(np.diag(1 / invD)) theta = SampleMultivariateNormal(h, B_ch) thetas[ii + 1, :] = theta.reshape((1, parameters)) maxVarB.append(np.abs(np.diag(B_ch.dot(B_ch.T))).max()) break m = m_all[ii, :].reshape((parameters, 1)) Csvd = C_all[ii] C = Csvd[0].dot(np.diag(Csvd[1]**2)).dot(Csvd[0].T) invR = Rsvd[0].dot(np.diag(1 / Rsvd[1]**2)).dot(Rsvd[0].T) CGinvR = C.dot(G.T).dot(invR) h = m + CGinvR.dot(theta - a) tmp = (invGam.T).dot(G).dot(Csvd[0]) A, invD, ET = svd(np.concatenate((tmp, np.diag(1 / Csvd[1])), axis=0)) U = Csvd[0].dot(ET.T) B_ch = U.dot(np.diag(1 / invD)) theta = SampleMultivariateNormal(h, B_ch) thetas[ii + 1, :] = theta.reshape((1, parameters)) maxVarB.append(np.abs(np.diag(B_ch.dot(B_ch.T))).max()) # To check, compute st # s = m + CGinvR.dot(s - a) # s_all[ii,:] = s.T # Bfull = C - CGinvR.dot(G).dot(C) # Bfull = C - C.dot(G.T).dot(invR).dot(G).dot(C) # invBfullbis = np.linalg.inv(C) + \ # (G.T).dot(np.linalg.inv(W)).dot(G) # Bfullbis = np.linalg.inv(invBfullbis) # Rfull = Rsvd[0].dot(np.diag(Rsvd[1]**2)).dot(Rsvd[0].T) # Sfull = C - CGinvR.dot(Rfull-Sfull).dot(CGinvR.T) # S_all.append(Sfull) ii -= 1 return thetas, maxVarB