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
Exemple #2
0
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
Exemple #3
0
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
Exemple #7
0
    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))
Exemple #8
0
 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