def star(SA, SB, device='cpu'): ''' STAR Redheffer Star Product % INPUT ARGUMENTS % ================ % SA First Scattering Matrix % .S11 S11 scattering parameter % .S12 S12 scattering parameter % .S21 S21 scattering parameter % .S22 S22 scattering parameter % % SB Second Scattering Matrix % .S11 S11 scattering parameter % .S12 S12 scattering parameter % .S21 S21 scattering parameter % .S22 S22 scattering parameter % % OUTPUT ARGUMENTS % ================ % S Combined Scattering Matrix % .S11 S11 scattering parameter % .S12 S12 scattering parameter % .S21 S21 scattering parameter % .S22 S22 scattering parameter ''' if device == 'gpu' or device == 'cuda': # use GPU, cupy N = SA['S11'].shape[0] I = cp.eye(N) S11 = SA['S11'] + (SA['S12'] @ CLA.inv(I - (SB['S11'] @ SA['S22'])) @ SB['S11'] @ SA['S21']) S12 = SA['S12'] @ CLA.inv(I - (SB['S11'] @ SA['S22'])) @ SB['S12'] S21 = SB['S21'] @ CLA.inv(I - (SA['S22'] @ SB['S11'])) @ SA['S21'] S22 = SB['S22'] + (SB['S21'] @ CLA.inv(I - (SA['S22'] @ SB['S11'])) @ SA['S22'] @ SB['S12']) S = {'S11': S11, 'S12': S12, 'S21': S21, 'S22': S22} else: # cpu, numpy N = SA['S11'].shape[0] I = np.eye(N) S11 = SA['S11'] + (SA['S12'] @ LA.inv(I - (SB['S11'] @ SA['S22'])) @ SB['S11'] @ SA['S21']) S12 = SA['S12'] @ LA.inv(I - (SB['S11'] @ SA['S22'])) @ SB['S12'] S21 = SB['S21'] @ LA.inv(I - (SA['S22'] @ SB['S11'])) @ SA['S21'] S22 = SB['S22'] + (SB['S21'] @ LA.inv(I - (SA['S22'] @ SB['S11'])) @ SA['S22'] @ SB['S12']) S = {'S11': S11, 'S12': S12, 'S21': S21, 'S22': S22} return S
def _eigh(A, B=None): """ Helper function for converting a generalized eigenvalue problem A(X) = lambda(B(X)) to standard eigen value problem using cholesky transformation """ if (B is None): # use cupy's eigh in standard case vals, vecs = linalg.eigh(A) return vals, vecs R = _cholesky(B) RTi = linalg.inv(R) Ri = linalg.inv(R.T) F = cupy.matmul(RTi, cupy.matmul(A, Ri)) vals, vecs = linalg.eigh(F) eigVec = cupy.matmul(Ri, vecs) return vals, eigVec
def _b_orthonormalize(B, blockVectorV, blockVectorBV=None, retInvR=False): """B-orthonormalize the given block vector using Cholesky.""" normalization = blockVectorV.max(axis=0) + cupy.finfo( blockVectorV.dtype).eps blockVectorV = blockVectorV / normalization if blockVectorBV is None: if B is not None: blockVectorBV = B(blockVectorV) else: blockVectorBV = blockVectorV else: blockVectorBV = blockVectorBV / normalization VBV = cupy.matmul(blockVectorV.T.conj(), blockVectorBV) try: # VBV is a Cholesky factor VBV = _cholesky(VBV) VBV = linalg.inv(VBV.T) blockVectorV = cupy.matmul(blockVectorV, VBV) if B is not None: blockVectorBV = cupy.matmul(blockVectorBV, VBV) else: blockVectorBV = None except numpy.linalg.LinAlgError: # LinAlg Error: cholesky transformation might fail in rare cases # raise ValueError("cholesky has failed") blockVectorV = None blockVectorBV = None VBV = None if retInvR: return blockVectorV, blockVectorBV, VBV, normalization else: return blockVectorV, blockVectorBV
def loggrad_z(thetas): """ theta = [z, sigma_z_sqr, w, gamma, eta] """ z = thetas['z'] w = thetas['w'] gamma = thetas['gamma'] eta = thetas['eta'] sigma_z_sqr = thetas['sigma_z_sqr'] K = z.shape[0] # Precision matrix with covariance [1, 1.98; 1.98, 4]. # A = np.linalg.inv( cov ) V_eta = np.exp(np.dot(w, gamma)) mu_eta = np.dot(w,z) V_z = inv(np.dot(w.T,np.dot(np.diag(1/V_eta), w)) + 1/sigma_z_sqr * np.diag(np.ones(K))) mu_z = np.dot(V_z, np.dot(w.T,np.dot(np.diag(1/V_eta), eta))) logp = -0.5 * np.dot((z - mu_z).T, np.dot(inv(V_z), z-mu_z))-np.log(norm.cdf(mu_eta/(V_eta**0.5))).sum() grad = - np.dot(inv(V_z), z) + np.dot(inv(V_z), mu_z) - np.dot(w.T,norm.pdf(mu_eta/(V_eta**0.5))/(norm.cdf(mu_eta/(V_eta**0.5)) * V_eta ** 0.5)) return -logp, -grad
def loggrad_delta(thetas): """ theta = [delta, sigma_delta_sqr, pi, u, xi] """ pi = thetas['pi'] xi = thetas['xi'] delta = thetas['delta'] u = thetas['u'] sigma_delta_sqr = thetas['sigma_delta_sqr'] K = delta.shape[0] # Precision matrix with covariance [1, 1.98; 1.98, 4]. # A = np.linalg.inv( cov ) V_u = np.exp(np.dot(pi, xi)) mu_u = np.dot(pi,delta) V_delta = inv(np.dot(pi.T,np.dot(np.diag(1/V_u), pi)) + 1/sigma_delta_sqr * np.diag(np.ones(K))) mu_delta = np.dot(V_delta, np.dot(pi.T,np.dot(np.diag(1/V_u), u))) logp = -0.5 * np.dot((delta - mu_delta).T, np.dot(inv(V_delta), delta-mu_delta))-np.log(norm.cdf(mu_u/(V_u**0.5))).sum() grad = - np.dot(inv(V_delta), delta) + np.dot(inv(V_delta), mu_delta) - np.dot(pi.T,norm.pdf(mu_u/(V_u**0.5))/(norm.cdf(mu_u/(V_u**0.5)) * V_u ** 0.5)) return -logp, -grad
def Correct(self, xHatMinus, PMinus, z, active_measurements=None): '''For use in Iterate''' if active_measurements is not None: H = self.H * active_measurements else: H = self.H K = dot(PMinus, dot(H.T, linalg.inv(dot(H, dot(PMinus, H.T)) + self.R))) xHat = xHatMinus + dot(K, (z - dot(H, xHatMinus))) P = dot((self.I - dot(K, H)), PMinus) return K, xHat, P
def update(self, z): # Transform sigmas into measurement space for i in range(self.num_sp): self.sp_h[i] = self.H(self.sp_f[i]) # Mean and covariance of the state in the measurement space Hx_bar, PHx = unscented_transform(self.sp_h, self.weights, self.R) # Cross variance of Fx and Hx -- used to calculate K cross_var = np.zeros((self.Nx, self.Nz)) for i in range(self.num_sp): cross_var += self.weights[i] * np.outer(self.sp_f[i] - self.x_hat, self.sp_h[i] - Hx_bar) # Calculate K and measurement residual K = np.dot(cross_var, inv(PHx)) residual = self.difference(np.array(z), Hx_bar) # Update predicted to new values for state and variance self.x_hat += np.dot(K, residual) self.P -= np.dot(K, np.dot(PHx, K.T))
def inv(self, a): return CuPyTensor(la.inv(a.unwrap()))
def basis_pursuit(A, b, tol=1e-4, niter=100, biter=32): """ solves min |x|_1 s.t. Ax=b using a Primal-Dual Interior Point Method Args: A: design matrix of size (d, n) b: measurement vector of length d tol: solver tolerance niter: maximum length of central path biter: maximum number of steps in backtracking line search Returns: vector of length n """ A = cp.asarray(A) b = cp.asarray(b) d, n = A.shape alpha = 0.01 beta = 0.5 mu = 10 e = cp.ones(n) gradf0 = cp.hstack([cp.zeros(n), e]) x = (A.T).dot(inv(A.dot(A.T))).dot(b) absx = cp.abs(x) u = 0.95 * absx + 0.1 * cp.max(absx) fu1 = x - u fu2 = -x - u lamu1 = -1.0 / fu1 lamu2 = -1.0 / fu2 v = A.dot(lamu2 - lamu1) ATv = (A.T).dot(v) sdg = -(cp.inner(fu1, lamu1) + cp.inner(fu2, lamu2)) tau = 2.0 * n * mu / sdg ootau = 1.0 / tau rcent = cp.hstack([-lamu1 * fu1, -lamu2 * fu2]) - ootau rdual = gradf0 + cp.hstack([lamu1 - lamu2 + ATv, -lamu1 - lamu2]) rpri = A.dot(x) - b resnorm = cp.sqrt(norm(rdual)**2 + norm(rcent)**2 + norm(rpri)**2) rdp = cp.empty(2 * n) rcp = cp.empty(2 * n) for i in range(niter): oofu1 = 1.0 / fu1 oofu2 = 1.0 / fu2 w1 = -ootau * (oofu2 - oofu1) - ATv w2 = -1.0 - ootau * (oofu1 + oofu2) w3 = -rpri lamu1xoofu1 = lamu1 * oofu1 lamu2xoofu2 = lamu2 * oofu2 sig1 = -lamu1xoofu1 - lamu2xoofu2 sig2 = lamu1xoofu1 - lamu2xoofu2 sigx = sig1 - sig2**2 / sig1 if cp.min(cp.abs(sigx)) == 0.0: break w1p = -(w3 - A.dot(w1 / sigx - w2 * sig2 / (sigx * sig1))) H11p = A.dot((A.T) * (e / sigx)[:, cp.newaxis]) if cp.min(sigx) > 0.0: dv = solve(H11p, w1p) else: dv = solve(H11p, w1p) dx = (w1 - w2 * sig2 / sig1 - (A.T).dot(dv)) / sigx Adx = A.dot(dx) ATdv = (A.T).dot(dv) du = (w2 - sig2 * dx) / sig1 dlamu1 = lamu1xoofu1 * (du - dx) - lamu1 - ootau * oofu1 dlamu2 = lamu2xoofu2 * (dx + du) - lamu2 - ootau * oofu2 s = 1.0 indp = cp.less(dlamu1, 0.0) indn = cp.less(dlamu2, 0.0) if cp.any(indp): s = min(s, cp.min(-lamu1[indp] / dlamu1[indp])) if cp.any(indn): s = min(s, cp.min(-lamu2[indn] / dlamu2[indn])) indp = cp.greater(dx - du, 0.0) indn = cp.greater(-dx - du, 0.0) if cp.any(indp): s = min(s, cp.min(-fu1[indp] / (dx[indp] - du[indp]))) if cp.any(indn): s = min(s, cp.min(-fu2[indn] / (-dx[indn] - du[indn]))) s = 0.99 * s for j in range(biter): xp = x + s * dx up = u + s * du vp = v + s * dv ATvp = ATv + s * ATdv lamu1p = lamu1 + s * dlamu1 lamu2p = lamu2 + s * dlamu2 fu1p = xp - up fu2p = -xp - up rdp[:n] = lamu1p - lamu2p + ATvp rdp[n:] = -lamu1p - lamu2p rdp += gradf0 rcp[:n] = -lamu1p * fu1p rcp[n:] = lamu2p * fu2p rcp -= ootau rpp = rpri + s * Adx s *= beta if (cp.sqrt(norm(rdp)**2 + norm(rcp)**2 + norm(rpp)**2) <= (1 - alpha * s) * resnorm): break else: break x = xp lamu1 = lamu1p lamu2 = lamu2p fu1 = fu1p fu2 = fu2p sdg = -(cp.inner(fu1, lamu1) + cp.inner(fu2, lamu2)) if sdg < tol: return cp.asnumpy(x) u = up v = vp ATv = ATvp tau = 2.0 * n * mu / sdg rpri = rpp rcent[:n] = lamu1 * fu1 rcent[n:] = lamu2 * fu2 ootau = 1.0 / tau rcent -= ootau rdual[:n] = lamu1 - lamu2 + ATv rdual[n:] = -lamu1 + lamu2 rdual += gradf0 resnorm = cp.sqrt(norm(rdual)**2 + norm(rcent)**2 + norm(rpri)**2) return cp.asnumpy(x)
accpt_num_xi = 0 accpt_num_z = 0 accpt_num_gamma = 0 S = 11000 all_beta = np.zeros([S, K]) all_xi = np.zeros([S,K]) all_delta = np.zeros([S,K]) all_z = np.zeros([S,K]) all_gamma = np.zeros([S,K]) all_sigma_v_sqr = np.zeros([S,]) all_sigma_alpha_sqr = np.zeros([S,]) for i in range(S): print(i) ### Posterior # beta V_beta = inv((np.dot(x.T,x) * sigma_beta_sqr + sigma_v_sqr)/(sigma_v_sqr * sigma_beta_sqr)) mu_beta = np.dot(V_beta, np.dot(x.T, y-u-np.kron(alpha, np.ones([T,])) - np.kron(eta, np.ones(T,)))/sigma_v_sqr) beta = multivariate_normal.rvs(mu_beta, V_beta) # sigma_v_sqr y_tilda = y-np.dot(x,beta)-u-np.kron(alpha,np.ones(T,))-np.kron(eta,np.ones(T,)) shape = (NT+1)/2 scale = 2 / (0.0001 + np.dot(y_tilda.T, y_tilda)) sigma_v_sqr = 1/np.random.gamma(shape,scale) # sigma_alpha_sqr shape = (N+1)/2 scale = 2/ (0.0001 + np.dot(alpha.T,alpha)) sigma_alpha_sqr = 1/np.random.gamma(shape,scale) # alpha # scale = sigma_alpha_sqr * sigma_v_sqr / (T * sigma_alpha_sqr + sigma_v_sqr) # y_bar = y-np.dot(x, beta)-np.kron(eta, np.ones(T,))-u