Beispiel #1
0
        def classifier2(Y, soft=False):

            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(theta, (width, M))
            blas.gemm(X,
                      Y,
                      K,
                      transB='T',
                      alpha=1.0 / sigma,
                      beta=-1.0,
                      m=width)

            K = exp(K)
            K = div(K - K**-1, K + K**-1)

            # complete K
            lapack.potrs(L11, K)
            K = matrix([K, matrix(0., (N - width, M))], (N, M))
            chompack.trsm(Lc, K, trans='N')
            chompack.trsm(Lc, K, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(K, z, x, trans='T', beta=1.0)

            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])
Beispiel #2
0
    def g(x, y, z):

        x[:iC] = 0.5 * (
            x[:iC] - mul(d3, x[iC:]) + mul(d1, z[:iC] + mul(d3, z[:iC])) - mul(d2, z[iC:] - mul(d3, z[iC:]))
        )
        x[:iC] = div(x[:iC], ds)

        # Solve
        #
        #     S * v = 0.5 * A * D^-1 * ( bx[:n]
        #             - (D2-D1)*(D1+D2)^-1 * bx[n:]
        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n]
        #             - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] )

        blas.gemv(mmAsc, x, vvV)
        lapack.potrs(mmS, vvV)

        # x[:n] = D^-1 * ( rhs - A'*v ).
        blas.gemv(mmAsc, vvV, x, alpha=-1.0, beta=1.0, trans="T")
        x[:iC] = div(x[:iC], ds)

        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n]  - D2*bz[n:] )
        #         - (D2-D1)*(D1+D2)^-1 * x[:n]
        x[iC:] = div(x[iC:] - mul(d1, z[:iC]) - mul(d2, z[iC:]), d1 + d2) - mul(d3, x[:iC])

        # z[:n] = D1^1/2 * (  x[:n] - x[n:] - bz[:n] )
        # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ).
        z[:iC] = mul(W["di"][:iC], x[:iC] - x[iC:] - z[:iC])
        z[iC:] = mul(W["di"][iC:], -x[:iC] - x[iC:] - z[iC:])
Beispiel #3
0
        def g(x, y, z):

            x[:n] = 0.5 * (x[:n] - mul(d3, x[n:]) + mul(
                d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - mul(d3, z[n:])))
            x[:n] = div(x[:n], ds)

            # Solve
            #
            #     S * v = 0.5 * A * D^-1 * ( bx[:n] -
            #         (D2-D1)*(D1+D2)^-1 * bx[n:] +
            #         D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] -
            #         D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] )

            blas.gemv(Asc, x, v)
            lapack.potrs(S, v)

            # x[:n] = D^-1 * ( rhs - A'*v ).
            blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
            x[:n] = div(x[:n], ds)

            # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] )
            #         - (D2-D1)*(D1+D2)^-1 * x[:n]
            x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\
                - mul( d3, x[:n] )

            # zl[:n] = D1^1/2 * (  x[:n] - x[n:] - bzl[:n] )
            # zl[n:] = D2^1/2 * ( -x[:n] - x[n:] - bzl[n:] ).
            z[:n] = mul(W['di'][:n], x[:n] - x[n:] - z[:n])
            z[n:] = mul(W['di'][n:], -x[:n] - x[n:] - z[n:])
Beispiel #4
0
    def _gen_bandsdp(self,n,m,bw,seed):
        """Random data generator for SDP with band structure"""
        setseed(seed)

        I = matrix([ i for j in range(n) for i in range(j,min(j+bw+1,n))])
        J = matrix([ j for j in range(n) for i in range(j,min(j+bw+1,n))])
        V = spmatrix(0.,I,J,(n,n))
        Il = misc.sub2ind((n,n),I,J)
        Id = matrix([i for i in range(len(Il)) if I[i]==J[i]])

        # generate random y with norm 1
        y0 = normal(m,1)
        y0 /= blas.nrm2(y0)

        # generate random S0
        S0 = mk_rand(V,cone='posdef',seed=seed)
        X0 = mk_rand(V,cone='completable',seed=seed)

        # generate random A1,...,Am and set A0 = sum Ai*yi + S0
        A_ = normal(len(I),m+1,std=1./len(I))
        u = +S0.V
        blas.gemv(A_[:,1:],y0,u,beta=1.0)
        A_[:,0] = u
        # compute b
        x = +X0.V
        x[Id] *= 0.5
        self._b = matrix(0.,(m,1))
        blas.gemv(A_[:,1:],x,self._b,trans='T',alpha=2.0)
        # form A
        self._A = spmatrix(A_[:],
                     [i for j in range(m+1) for i in Il],
                     [j for j in range(m+1) for i in Il],(n**2,m+1))

        self._X0 = X0; self._y0 = y0; self._S0 = S0
Beispiel #5
0
        def g(x, y, z):

            x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + 
                mul(d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - 
                mul(d3, z[n:])) )
            x[:n] = div( x[:n], ds) 

            # Solve
            #
            #     S * v = 0.5 * A * D^-1 * ( bx[:n] - 
            #         (D2-D1)*(D1+D2)^-1 * bx[n:] + 
            #         D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - 
            #         D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] )
                
            blas.gemv(Asc, x, v)
            lapack.potrs(S, v)
            
            # x[:n] = D^-1 * ( rhs - A'*v ).
            blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
            x[:n] = div(x[:n], ds)

            # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] ) 
            #         - (D2-D1)*(D1+D2)^-1 * x[:n]         
            x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\
                - mul( d3, x[:n] )
                
            # zl[:n] = D1^1/2 * (  x[:n] - x[n:] - bzl[:n] )
            # zl[n:] = D2^1/2 * ( -x[:n] - x[n:] - bzl[n:] ).
            z[:n] = mul( W['di'][:n],  x[:n] - x[n:] - z[:n] ) 
            z[n:] = mul( W['di'][n:], -x[:n] - x[n:] - z[n:] ) 
Beispiel #6
0
    def G(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
        """
        If trans is 'N':

            v[:msq] := alpha * (A*u[0] - u[1][:]) + beta * v[:msq]
            v[msq:] := -alpha * u[1][:] + beta * v[msq:].


        If trans is 'T':

            v[0] := alpha *  A' * u[:msq] + beta * v[0]
            v[1][:] := alpha * (-u[:msq] - u[msq:]) + beta * v[1][:].

        """
 
        if trans == 'N': 

            blas.gemv(A, u[0], v, alpha = alpha, beta = beta) 
            blas.axpy(u[1], v, alpha = -alpha)
            blas.scal(beta, v, offset = msq)
            blas.axpy(u[1], v, alpha = -alpha, offsety = msq)
            
        else:

            misc.sgemv(A, u, v[0], dims = {'l': 0, 'q': [], 's': [m]},
                alpha = alpha, beta = beta, trans = 'T')   
            blas.scal(beta, v[1])
            blas.axpy(u, v[1], alpha = -alpha, n = msq)
            blas.axpy(u, v[1], alpha = -alpha, n = msq, offsetx = msq)
Beispiel #7
0
    def g(x, y, z):

        x[:iC] = 0.5 * ( x[:iC] - mul(d3, x[iC:]) + \
                mul(d1, z[:iC] + mul(d3, z[:iC])) - \
                mul(d2, z[iC:] - mul(d3, z[iC:])) )
        x[:iC] = div(x[:iC], ds)

        # Solve
        #
        #     S * v = 0.5 * A * D^-1 * ( bx[:n]
        #             - (D2-D1)*(D1+D2)^-1 * bx[n:]
        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n]
        #             - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] )

        blas.gemv(mmAsc, x, vvV)
        lapack.potrs(mmS, vvV)

        # x[:n] = D^-1 * ( rhs - A'*v ).
        blas.gemv(mmAsc, vvV, x, alpha=-1.0, beta=1.0, trans='T')
        x[:iC] = div(x[:iC], ds)

        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n]  - D2*bz[n:] )
        #         - (D2-D1)*(D1+D2)^-1 * x[:n]
        x[iC:] = div( x[iC:] - mul(d1, z[:iC]) - mul(d2, z[iC:]), d1+d2 )\
                - mul( d3, x[:iC] )

        # z[:n] = D1^1/2 * (  x[:n] - x[n:] - bz[:n] )
        # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ).
        z[:iC] = mul(W['di'][:iC], x[:iC] - x[iC:] - z[:iC])
        z[iC:] = mul(W['di'][iC:], -x[:iC] - x[iC:] - z[iC:])
Beispiel #8
0
        def f(x, y, z):

            # Solve for x[:n]:
            #
            #    A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:]
            #        + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ).

            blas.copy((mul(div(d1 - d2, d1 + d2), x[n:]) +
                       mul(2 * D, z[:m] - z[m:])), u)
            blas.gemv(P, u, x, beta=1.0, trans='T')
            lapack.potrs(A, x)

            # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:]
            #     + (D1-D2)*P*x[:n])

            base.gemv(P, x, u)
            x[n:] = div(
                x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + mul(d1 - d2, u),
                d1 + d2)

            # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m])
            # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:])

            z[:m] = mul(di[:m], u - x[n:] - z[:m])
            z[m:] = mul(di[m:], -u - x[n:] - z[m:])
    def F(x=None, z=None):
        if x is None:
            return 0, matrix(0.0, (n, 1))
        if max(abs(x)) >= 1.0:
            return None
        r = -b
        blas.gemv(A, x, r, beta=-1.0)
        w = x**2
        f = 0.5 * blas.nrm2(r)**2 - sum(log(1 - w))
        gradf = div(x, 1.0 - w)
        blas.gemv(A, r, gradf, trans='T', beta=2.0)
        if z is None:
            return f, gradf.T
        else:

            def Hf(u, v, alpha=1.0, beta=0.0):
                """
                   v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v
               """
                v *= beta
                v += 2.0 * alpha * mul(div(1.0 + w, (1.0 - w)**2), u)
                blas.gemv(A, u, r)
                blas.gemv(A, r, v, alpha=alpha, beta=1.0, trans='T')

            return f, gradf.T, Hf
Beispiel #10
0
        def classifier2(Y, soft=False):

            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(0.0, (width, M))
            blas.gemm(X, Y, K, transB='T', alpha=1.0 / sigma, m=width)

            # c[i] = ||Yi||^2 / sigma
            ones = matrix(1.0, (max(width, n, M), 1))
            c = Y**2 * ones[:n]
            blas.scal(1.0 / sigma, c)

            # Kij := Kij - 0.5 * (ci + aj)
            #      = || yi - xj ||^2 / (2*sigma)
            blas.ger(ones[:width], c, K, alpha=-0.5)
            blas.ger(a[:width], ones[:M], K, alpha=-0.5)
            # Kij = exp(Kij)
            K = exp(K)

            # complete K
            lapack.potrs(L11, K)
            K = matrix([K, matrix(0., (N - width, M))], (N, M))
            chompack.trsm(Lc, K, trans='N')
            chompack.trsm(Lc, K, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(K, z, x, trans='T', beta=1.0)

            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])
Beispiel #11
0
    def G(x, y, alpha=1.0, beta=0.0, trans='N'):
        """
        Implements the linear operator

               [ -DX    E   -d   -I ]  
               [  0     0    0   -I ]  
               [  0   -e_1'  0    0 ]
          G =  [ -P_1'  0    0    0 ]     
               [  .     .    .    . ]    
               [  0   -e_k'  0    0 ]        
               [ -P_k'  0    0    0 ]       

        and its adjoint G'.

        """
        if trans == 'N':
            tmp = +y[:m]
            # y[:m] = alpha*(-DXw + Et - d*b - v) + beta*y[:m]
            base.gemv(E, x[n:n + k], tmp, alpha=alpha, beta=beta)
            blas.axpy(x[n + k + 1:], tmp, alpha=-alpha)
            blas.axpy(d, tmp, alpha=-alpha * x[n + k])
            y[:m] = tmp

            base.gemv(X, x[:n], tmp, alpha=alpha, beta=0.0)
            tmp = mul(d, tmp)
            y[:m] -= tmp

            # y[m:2*m] = -v
            y[m:2 * m] = -alpha * x[n + k + 1:] + beta * y[m:2 * m]

            # SOC 1,...,k
            for i in range(k):
                l = 2 * m + i * (n + 1)
                y[l] = -alpha * x[n + i] + beta * y[l]
                y[l + 1:l + 1 +
                  n] = -alpha * P[i] * x[:n] + beta * y[l + 1:l + 1 + n]

        else:
            tmp1 = mul(d, x[:m])
            tmp2 = y[:n]
            blas.gemv(X, tmp1, tmp2, trans='T', alpha=-alpha, beta=beta)
            for i in range(k):
                l = 2 * m + 1 + i * (n + 1)
                blas.gemv(P[i],
                          x[l:l + n],
                          tmp2,
                          trans='T',
                          alpha=-alpha,
                          beta=1.0)
            y[:n] = tmp2

            tmp2 = y[n:n + k]
            base.gemv(E, x[:m], tmp2, trans='T', alpha=alpha, beta=beta)
            blas.axpy(x[2 * m:2 * m + k * (1 + n):n + 1], tmp2, alpha=-alpha)
            y[n:n + k] = tmp2

            y[n + k] = -alpha * blas.dot(d, x[:m]) + beta * y[n + k]
            y[n + k +
              1:] = -alpha * (x[:m] + x[m:2 * m]) + beta * y[n + k + 1:]
Beispiel #12
0
 def Hf(u, v, alpha = 1.0, beta = 0.0):
    """
        v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v
    """
    v *= beta
    v += 2.0 * alpha * mul(div(1.0+w, (1.0-w)**2), u)
    blas.gemv(A, u, r)
    blas.gemv(A, r, v, alpha = alpha, beta = 1.0, trans = 'T')
Beispiel #13
0
 def Hf(u, v, alpha = 1.0, beta = 0.0):
    """
        v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v
    """
    v *= beta
    v += 2.0 * alpha * mul(div(1.0+w, (1.0-w)**2), u)
    blas.gemv(A, u, r)
    blas.gemv(A, r, v, alpha = alpha, beta = 1.0, trans = 'T')
Beispiel #14
0
def P(u, v, alpha = 1.0, beta = 0.0):
    """
    Function and gradient evaluation of

	v := alpha * 2*A'*A * u + beta * v
    """

    blas.gemv(A, u, r)      
    blas.gemv(A, r, v, alpha = 2.0*alpha, beta = beta, trans = 'T') 
Beispiel #15
0
 def classifier(Y, soft = False):
     M = Y.size[0]
     x = matrix(b, (M,1))
     #print('b ( = w_0)')
     #print(b)
     #print('about to print long vector?')
     blas.gemv(Y, w, x, beta = 1.0)
     if soft: return x
     else:    return matrix([ 2*(xk > 0.0) - 1 for xk in x ])
def P(u, v, alpha=1.0, beta=0.0):
    """
    Function and gradient evaluation of

        v := alpha * 2*A'*A * u + beta * v
    """

    blas.gemv(A, u, r)
    blas.gemv(A, r, v, alpha=2.0 * alpha, beta=beta, trans='T')
Beispiel #17
0
def test_Gfunc(ntrials=10, tol=1e-10):
    K = 5
    sij = matrix(np.random.rand(K * K), (K, K))
    sij = 0.5 * (sij.T + sij)
    si2 = cvxopt.div(1., sij**2)
    alpha = 1.5
    beta = 0.25
    G, h, A = Aopt_GhA(si2)

    success = True

    for i in xrange(ntrials):
        trans = 'N'
        nx = K * (K + 1) / 2 + K
        ny = K * (K + 1) / 2 + K * (K + 1) * (K + 1)
        x = matrix(np.random.rand(nx), (nx, 1))
        y = matrix(1.e6 * np.random.rand(ny), (ny, 1))

        yp = y[:]
        Aopt_Gfunc(si2, x, y, alpha, beta, trans)
        blas.gemv(matrix(G), x, yp, 'N', alpha, beta)

        dy = np.max(np.abs(y - yp))
        if (dy > tol):
            success = False
            print 'G function FAILS for trans=N: dy=%g' % dy
        else:
            print 'G function succeeds for trans=N: dy=%g' % dy

        trans = 'T'
        nx = K * (K + 1) / 2 + K * (K + 1) * (K + 1)
        ny = K * (K + 1) / 2 + K
        x = matrix(np.random.rand(nx), (nx, 1))
        y = matrix(1.e6 * np.random.rand(ny), (ny, 1))

        for i in xrange(K):
            start = K * (K + 1) / 2 + i * (K + 1) * (K + 1)
            for a in xrange(K + 1):
                for b in xrange(a + 1, K + 1):
                    x[start + a * (K + 1) + b] = x[start + b * (K + 1) + a]

        yp = y[:]
        Aopt_Gfunc(si2, x, y, alpha, beta, trans)
        blas.gemv(matrix(G), x, yp, 'T', alpha, beta)

        dy = np.max(np.abs(y - yp))
        if (dy > tol):
            success = False
            print 'G function FAILS for trans=T: dy=%g' % dy
        else:
            print 'G function succeeds for trans=T: dy=%g' % dy

    return success
Beispiel #18
0
    def Fi(x, y, alpha=1.0, beta=0.0, trans='N'):
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            blas.gemv(P, x, u)
            y[:m] = alpha * (u - x[n:]) + beta * y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta * y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            blas.copy(x[:m] - x[m:], u)
            blas.gemv(P, u, y, alpha=alpha, beta=beta, trans='T')
            y[n:] = -alpha * (x[:m] + x[m:]) + beta * y[n:]
Beispiel #19
0
    def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):    
        if trans == 'N':
            # y := alpha * [P, -I; -P, -I] * x + beta*y
            blas.gemv(P, x, u) 
            y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
            y[m:] = alpha * (-u - x[n:]) + beta*y[m:]

        else:
            # y := alpha * [P', -P'; -I, -I] * x + beta*y
            blas.copy(x[:m] - x[m:], u)
            blas.gemv(P, u, y, alpha = alpha, beta = beta, trans = 'T')
            y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]
Beispiel #20
0
    def G(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):
        """
        Implements the linear operator

               [ -DX    E   -d   -I ]  
               [  0     0    0   -I ]  
               [  0   -e_1'  0    0 ]
          G =  [ -P_1'  0    0    0 ]     
               [  .     .    .    . ]    
               [  0   -e_k'  0    0 ]        
               [ -P_k'  0    0    0 ]       

        and its adjoint G'.

        """
        if trans == 'N':
            tmp = +y[:m]
            # y[:m] = alpha*(-DXw + Et - d*b - v) + beta*y[:m]
            base.gemv(E, x[n:n+k], tmp, alpha = alpha, beta = beta)
            blas.axpy(x[n+k+1:], tmp, alpha = -alpha)
            blas.axpy(d, tmp, alpha = -alpha*x[n+k])
            y[:m] = tmp

            base.gemv(X, x[:n], tmp, alpha = alpha, beta = 0.0)
            tmp = mul(d,tmp)
            y[:m] -= tmp
            
            # y[m:2*m] = -v
            y[m:2*m] = -alpha * x[n+k+1:] + beta * y[m:2*m]

            # SOC 1,...,k
            for i in range(k):
                l = 2*m+i*(n+1)
                y[l] = -alpha * x[n+i] + beta * y[l]
                y[l+1:l+1+n] = -alpha * P[i] * x[:n] + beta * y[l+1:l+1+n];

        else:
            tmp1 = mul(d,x[:m])
            tmp2 = y[:n]
            blas.gemv(X, tmp1, tmp2, trans = 'T', alpha = -alpha, beta = beta)
            for i in range(k):
                l = 2*m+1+i*(n+1)
                blas.gemv(P[i], x[l:l+n], tmp2, trans = 'T', alpha = -alpha, beta = 1.0)
            y[:n] = tmp2

            tmp2 = y[n:n+k]
            base.gemv(E, x[:m], tmp2, trans = 'T', alpha = alpha, beta = beta)
            blas.axpy(x[2*m:2*m+k*(1+n):n+1], tmp2, alpha = -alpha)
            y[n:n+k] = tmp2

            y[n+k] = -alpha * blas.dot(d,x[:m]) + beta * y[n+k]
            y[n+k+1:] = -alpha * (x[:m] + x[m:2*m]) + beta * y[n+k+1:]
Beispiel #21
0
        def classifier2(Y, soft=False):
            M = Y.size[0]
            W = matrix(0., (width, M))
            blas.gemm(X, Y, W, transB='T', alpha=1.0 / sigma, m=width)
            lapack.potrs(L11, W)
            W = matrix([W, matrix(0., (N - width, M))])
            chompack.trsm(Lc, W, trans='N')
            chompack.trsm(Lc, W, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(W, z, x, trans='T', beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])
Beispiel #22
0
def P(u, vvV, alpha=1.0, beta=0.0):
    """
    Function and gradient evaluation of

          v := alpha * 2*A'*A * u + beta * v
    """
    # Allocate R
    vvR = matrix(0.0, (iR, 1))

    # R = A * u
    blas.gemv(mmTh, u, vvR)

    # v = 2 * A' * R
    blas.gemv(mmTh, vvR, vvV, alpha=2.0 * alpha, beta=beta, trans='T')
Beispiel #23
0
def P(u, vvV, alpha=1.0, beta=0.0):
    """
    Function and gradient evaluation of

          v := alpha * 2*A'*A * u + beta * v
    """
    # Allocate R
    vvR = matrix(0.0, (iR, 1))

    # R = A * u
    blas.gemv(mmTh, u, vvR)

    # v = 2 * A' * R
    blas.gemv(mmTh, vvR, vvV, alpha=2.0 * alpha, beta=beta, trans="T")
        def classifier2(Y, soft=False):
            if Y is None: return zs

            M = Y.size[0]
            W = matrix(0., (width, M))
            blas.gemm(X, Y, W, transB='T', alpha=1.0 / sigma, m=width)
            W = W**degree
            lapack.potrs(L11, W)
            W = matrix([W, matrix(0., (N - width, M))])
            chompack.solve(Lc, W, mode=0)
            chompack.solve(Lc, W, mode=1)

            x = matrix(b, (M, 1))
            blas.gemv(W, z, x, trans='T', beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])
Beispiel #25
0
    def A(x, y, alpha=1.0, beta=0.0, trans='N'):
        """
        If trans is 'N', x is an N x m matrix and y an N-vector.

            y := alpha * x * 1_m + beta y.

        If trans is 'T', x is an N vector and y an N x m matrix.

            y := alpha * x * 1_m' + beta y.
        """

        if trans == 'N':
            blas.gemv(x, ones, y, alpha=alpha, beta=beta)

        else:
            blas.scal(beta, y)
            blas.ger(x, ones, y, alpha=alpha)
Beispiel #26
0
    def _gen_bandsdp(self, n, m, bw, seed):
        """Random data generator for SDP with band structure"""
        setseed(seed)

        I = matrix(
            [i for j in xrange(n) for i in xrange(j, min(j + bw + 1, n))])
        J = matrix(
            [j for j in xrange(n) for i in xrange(j, min(j + bw + 1, n))])
        V = spmatrix(0., I, J, (n, n))
        Il = misc.sub2ind((n, n), I, J)
        Id = matrix([i for i in xrange(len(Il)) if I[i] == J[i]])

        # generate random y with norm 1
        y0 = normal(m, 1)
        y0 /= blas.nrm2(y0)

        # generate random S0
        S0 = mk_rand(V, cone='posdef', seed=seed)
        X0 = mk_rand(V, cone='completable', seed=seed)

        # generate random A1,...,Am and set A0 = sum Ai*yi + S0
        A_ = normal(len(I), m + 1, std=1. / len(I))
        u = +S0.V
        blas.gemv(A_[:, 1:], y0, u, beta=1.0)
        A_[:, 0] = u
        # compute b
        x = +X0.V
        x[Id] *= 0.5
        self._b = matrix(0., (m, 1))
        blas.gemv(A_[:, 1:], x, self._b, trans='T', alpha=2.0)
        # form A
        self._A = spmatrix(A_[:], [i for j in xrange(m + 1) for i in Il],
                           [j for j in xrange(m + 1) for i in Il],
                           (n**2, m + 1))

        self._X0 = X0
        self._y0 = y0
        self._S0 = S0
Beispiel #27
0
    def G(u, v, alpha=1.0, beta=0.0, trans='N'):
        """
        If trans is 'N':

            v[:msq] := alpha * (A*u[0] - u[1][:]) + beta * v[:msq]
            v[msq:] := -alpha * u[1][:] + beta * v[msq:].


        If trans is 'T':

            v[0] := alpha *  A' * u[:msq] + beta * v[0]
            v[1][:] := alpha * (-u[:msq] - u[msq:]) + beta * v[1][:].

        """

        if trans == 'N':

            blas.gemv(A, u[0], v, alpha=alpha, beta=beta)
            blas.axpy(u[1], v, alpha=-alpha)
            blas.scal(beta, v, offset=msq)
            blas.axpy(u[1], v, alpha=-alpha, offsety=msq)

        else:

            misc.sgemv(A,
                       u,
                       v[0],
                       dims={
                           'l': 0,
                           'q': [],
                           's': [m]
                       },
                       alpha=alpha,
                       beta=beta,
                       trans='T')
            blas.scal(beta, v[1])
            blas.axpy(u, v[1], alpha=-alpha, n=msq)
            blas.axpy(u, v[1], alpha=-alpha, n=msq, offsetx=msq)
Beispiel #28
0
 def F(x = None, z = None):
     if x is None: 
         return 0, matrix(0.0, (n,1))
     if max(abs(x)) >= 1.0: 
         return None 
     r = - b
     blas.gemv(A, x, r, beta = -1.0)
     w = x**2
     f = 0.5 * blas.nrm2(r)**2  - sum(log(1-w))
     gradf = div(x, 1.0 - w)
     blas.gemv(A, r, gradf, trans = 'T', beta = 2.0)
     if z is None:
         return f, gradf.T
     else:
         def Hf(u, v, alpha = 1.0, beta = 0.0):
            """
                v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v
            """
            v *= beta
            v += 2.0 * alpha * mul(div(1.0+w, (1.0-w)**2), u)
            blas.gemv(A, u, r)
            blas.gemv(A, r, v, alpha = alpha, beta = 1.0, trans = 'T')
         return f, gradf.T, Hf
Beispiel #29
0
        def f(x, y, z):

            # Solve for x[:n]:
            #
            #    A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:]
            #        + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ).

            blas.copy(( mul( div(d1-d2, d1+d2), x[n:]) + 
                mul( 2*D, z[:m]-z[m:] ) ), u)
            blas.gemv(P, u, x, beta = 1.0, trans = 'T')
            lapack.potrs(A, x)

            # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:]
            #     + (D1-D2)*P*x[:n])

            base.gemv(P, x, u)
            x[n:] =  div( x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + 
                mul(d1-d2, u), d1+d2 )

            # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m])
            # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:]) 

            z[:m] = mul(di[:m],  u-x[n:]-z[:m])
            z[m:] = mul(di[m:], -u-x[n:]-z[m:])
Beispiel #30
0
 def classifier(Y, soft=False):
     M = Y.size[0]
     x = matrix(b, (M, 1))
     blas.gemv(Y, w, x, beta=1.0)
     if soft: return x
     else: return matrix([2 * (xk > 0.0) - 1 for xk in x])
Beispiel #31
0
 def g(x, y, z):
     x[:] = mul(x, ds) / a
     blas.gemv(Asc, x, v)
     lapack.potrs(S, v)
     blas.gemv(Asc, v, x, alpha = -1.0, beta = 1.0, trans = 'T')
     x[:] = mul(x, ds)  
Beispiel #32
0
def kernel_matrix(X,
                  kernel,
                  sigma=1.0,
                  theta=1.0,
                  degree=1,
                  V=None,
                  width=None):
    """
    Computes the kernel matrix or a partial kernel matrix.

    Input arguments.

        X is an N x n matrix.

        kernel is a string with values 'linear', 'rfb', 'poly', or 'tanh'.
        'linear': k(u,v) = u'*v/sigma.
        'rbf':    k(u,v) = exp(-||u - v||^2 / (2*sigma)).
        'poly':   k(u,v) = (u'*v/sigma)**degree.
        'tanh':   k(u,v) = tanh(u'*v/sigma - theta).        kernel is a

        sigma and theta are positive numbers.

        degree is a positive integer.

        V is an N x N sparse matrix (default is None).

        width is a positive integer (default is None).

    Output.

        Q, an N x N matrix or sparse matrix.
        If V is a sparse matrix, a partial kernel matrix with the sparsity
        pattern V is returned.
        If width is specified and V = 'band', a partial kernel matrix
        with band sparsity is returned (width is the half-bandwidth).

        a, an N x 1 matrix with the products <xi,xi>/sigma.

    """
    N, n = X.size

    #### dense (full) kernel matrix
    if V is None:
        if verbose: print("building kernel matrix ..")

        # Qij = xi'*xj / sigma
        Q = matrix(0.0, (N, N))
        blas.syrk(X, Q, alpha=1.0 / sigma)
        a = Q[::N + 1]  # ai = ||xi||**2 / sigma

        if kernel == 'linear':
            pass

        elif kernel == 'rbf':
            # Qij := Qij - 0.5 * ( ai + aj )
            #      = -||xi - xj||^2 / (2*sigma)
            ones = matrix(1.0, (N, 1))
            blas.syr2(a, ones, Q, alpha=-0.5)

            Q = exp(Q)

        elif kernel == 'tanh':
            Q = exp(Q - theta)
            Q = div(Q - Q**-1, Q + Q**-1)

        elif kernel == 'poly':
            Q = Q**degree

        else:
            raise ValueError('invalid kernel type')

    #### general sparse partial kernel matrix
    elif type(V) is cvxopt.base.spmatrix:

        if verbose: print("building projected kernel matrix ...")
        Q = +V
        base.syrk(X, Q, partial=True, alpha=1.0 / sigma)

        # ai = ||xi||**2 / sigma
        a = matrix(Q[::N + 1], (N, 1))

        if kernel == 'linear':
            pass

        elif kernel == 'rbf':

            ones = matrix(1.0, (N, 1))

            # Qij := Qij - 0.5 * ( ai + aj )
            #      = -||xi - xj||^2 / (2*sigma)
            p = chompack.maxcardsearch(V)
            symb = chompack.symbolic(Q, p)
            Qc = chompack.cspmatrix(symb) + Q
            chompack.syr2(Qc, a, ones, alpha=-0.5)
            Q = Qc.spmatrix(reordered=False)
            Q.V = exp(Q.V)

        elif kernel == 'tanh':

            v = +Q.V
            v = exp(v - theta)
            v = div(v - v**-1, v + v**-1)
            Q.V = v

        elif kernel == 'poly':

            Q.V = Q.V**degree

        else:
            raise ValueError('invalid kernel type')

    #### banded partial kernel matrix
    elif V == 'band' and width is not None:

        # Lower triangular part of band matrix with bandwidth 2*w+1.
        if verbose: print("building projected kernel matrix ...")
        I = [i for k in range(N) for i in range(k, min(width + k + 1, N))]
        J = [k for k in range(N) for i in range(min(width + 1, N - k))]
        V = matrix(0.0, (len(I), 1))
        oy = 0
        for k in range(N):  # V[:,k] = Xtrain[k:k+w, :] * Xtrain[k,:].T
            m = min(width + 1, N - k)
            blas.gemv(X,
                      X,
                      V,
                      m=m,
                      ldA=N,
                      incx=N,
                      offsetA=k,
                      offsetx=k,
                      offsety=oy)
            oy += m
        blas.scal(1.0 / sigma, V)

        # ai = ||xi||**2 / sigma
        a = matrix(V[[i for i in range(len(I)) if I[i] == J[i]]], (N, 1))

        if kernel == 'linear':

            Q = spmatrix(V, I, J, (N, N))

        elif kernel == 'rbf':

            Q = spmatrix(V, I, J, (N, N))

            ones = matrix(1.0, (N, 1))

            # Qij := Qij - 0.5 * ( ai + aj )
            #      = -||xi - xj||^2 / (2*sigma)
            symb = chompack.symbolic(Q)
            Qc = chompack.cspmatrix(symb) + Q
            chompack.syr2(Qc, a, ones, alpha=-0.5)
            Q = Qc.spmatrix(reordered=False)
            Q.V = exp(Q.V)

        elif kernel == 'tanh':

            V = exp(V - theta)
            V = div(V - V**-1, V + V**-1)
            Q = spmatrix(V, I, J, (N, N))

        elif kernel == 'poly':

            Q = spmatrix(V**degree, I, J, (N, N))

        else:
            raise ValueError('invalid kernel type')
    else:
        raise TypeError('invalid type V')

    return Q, a
Beispiel #33
0
def softmargin_appr(X,
                    d,
                    gamma,
                    width,
                    kernel='linear',
                    sigma=1.0,
                    degree=1,
                    theta=1.0,
                    Q=None):
    """
    Solves the approximate 'soft-margin' SVM problem

        maximize    -(1/2)*z'*Qc*z + d'*z
        subject to  0 <= diag(d)*z <= gamma*ones
                    sum(z) = 0

    (with variables z), and its dual problem

        minimize    (1/2)*y'*Qc^{-1}*y + gamma*sum(v)
        subject to  diag(d)*(y + b*ones) + v >= 1
                    v >= 0

    (with variables y, v, b).

    Qc is the maximum determinant completion of the projection of Q
    on a band with bandwidth 2*w+1.  Q_ij = K(xi, xj) where K is a kernel
    function and xi is the ith row of X (xi' = X[i,:]).

    Input arguments.

        X is an N x n matrix.

        d is an N-vector with elements -1 or 1; d[i] is the label of
        row X[i,:].

        gamma is a positive parameter.

        kernel is a string with values 'linear', 'rfb', 'poly', or 'tanh'.
        'linear': k(u,v) = u'*v/sigma.
        'rbf':    k(u,v) = exp(-||u - v||^2 / (2*sigma)).
        'poly':   k(u,v) = (u'*v/sigma)**degree.
        'tanh':   k(u,v) = tanh(u'*v/sigma - theta).

        sigma and theta are positive numbers.

        degree is a positive integer.

        width is a positive integer.

    Output.

        Returns a dictionary with the keys:

        'classifier'
           a Python function object that takes an M x n matrix with
           test vectors as rows and returns a vector with labels

        'completion classifier'
          a Python function object that takes an M x n matrix with
          test vectors as rows and returns a vector with labels

        'z'
           a sparse m-vector

        'cputime'
           a tuple (Ttot, Tqp, Tker) where Ttot is the total
           CPU time, Tqp is the CPU time spent solving the QP, and
           Tker is the CPU time spent computing the kernel matrix

        'iterations'
           the number of interior-point iteations

        'misclassified'
           a tuple (L1, L2) where L1 is a list of indices of
           misclassified training vectors from class 1, and L2 is a
           list of indices of misclassified training vectors from
           class 2
    """

    Tstart = cputime()

    if verbose: solvers.options['show_progress'] = True
    else: solvers.options['show_progress'] = False
    N, n = X.size

    if Q is None:
        Q, a = kernel_matrix(X,
                             kernel,
                             sigma=sigma,
                             degree=degree,
                             theta=theta,
                             V='band',
                             width=width)
    else:
        if not (Q.size[0] == N and Q.size[1] == N):
            raise ValueError("invalid kernel matrix dimensions")
        elif not type(Q) is cvxopt.base.spmatrix:
            raise ValueError("invalid kernel matrix type")
        elif verbose:
            print("using precomputed kernel matrix ..")
        if kernel == 'rbf':
            Ad = spmatrix(0.0, range(N), range(N))
            base.syrk(X, V, partial=True)
            a = Ad.V
            del Ad

    Tkernel = cputime(Tstart)

    # solve qp
    Tqp = cputime()
    y, b, v, z, optval, Lc, iters = softmargin_completion(
        Q, matrix(d, tc='d'), gamma)
    Tqp = cputime(Tqp)
    if verbose: print("utime = %f, stime = %f." % Tqp)

    # extract nonzero support vectors
    nrmz = max(abs(z))
    sv = [k for k in range(N) if abs(z[k]) > Tsv * nrmz]
    zs = spmatrix(z[sv], sv, [0 for i in range(len(sv))], (len(d), 1))
    if verbose: print("%d support vectors." % len(sv))
    Xr, zr, Nr = X[sv, :], z[sv], len(sv)

    # find misclassified training vectors
    err1 = [i for i in range(Q.size[0]) if (v[i] > 1 and d[i] == 1)]
    err2 = [i for i in range(Q.size[0]) if (v[i] > 1 and d[i] == -1)]
    if verbose:
        e1, n1 = len(err1), list(d).count(1)
        e2, n2 = len(err2), list(d).count(-1)
        print("class 1: %i/%i = %.1f%% misclassified." %
              (e1, n1, 100. * e1 / n1))
        print("class 2: %i/%i = %.1f%% misclassified." %
              (e2, n2, 100. * e2 / n2))
        del e1, e2, n1, n2

    # create classifier function object

    # CLASSIFIER 1 (standard kernel classifier)
    if kernel == 'linear':
        # w = X'*z / sigma
        w = matrix(0.0, (n, 1))
        blas.gemv(Xr, zr, w, trans='T', alpha=1.0 / sigma)

        def classifier(Y, soft=False):
            M = Y.size[0]
            x = matrix(b, (M, 1))
            blas.gemv(Y, w, x, beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'rbf':

        def classifier(Y, soft=False):
            M = Y.size[0]
            # K = Y*X' / sigma
            K = matrix(0.0, (M, Nr))
            blas.gemm(Y, Xr, K, transB='T', alpha=1.0 / sigma)

            # c[i] = ||Yi||^2 / sigma
            ones = matrix(1.0, (max([M, Nr, n]), 1))
            c = Y**2 * ones[:n]
            blas.scal(1.0 / sigma, c)

            # Kij := Kij - 0.5 * (ci + aj)
            #      = || yi - xj ||^2 / (2*sigma)
            blas.ger(c, ones, K, alpha=-0.5)
            blas.ger(ones, a[sv], K, alpha=-0.5)
            x = exp(K) * zr + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'tanh':

        def classifier(Y, soft=False):
            M = Y.size[0]
            # K = Y*X' / sigma - theta
            K = matrix(theta, (M, Nr))
            blas.gemm(Y, Xr, K, transB='T', alpha=1.0 / sigma, beta=-1.0)

            K = exp(K)
            x = div(K - K**-1, K + K**-1) * zr + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'poly':

        def classifier(Y, soft=False):
            M = Y.size[0]
            # K = Y*X' / sigma
            K = matrix(0.0, (M, Nr))
            blas.gemm(Y, Xr, K, transB='T', alpha=1.0 / sigma)

            x = K**degree * zr + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    else:
        pass

    # CLASSIFIER 2 (completion kernel classifier)
    # TODO: generalize to arbitrary sparsity pattern
    L11 = matrix(Q[:width, :width])
    lapack.potrf(L11)

    if kernel == 'linear':

        def classifier2(Y, soft=False):
            M = Y.size[0]
            W = matrix(0., (width, M))
            blas.gemm(X, Y, W, transB='T', alpha=1.0 / sigma, m=width)
            lapack.potrs(L11, W)
            W = matrix([W, matrix(0., (N - width, M))])
            chompack.trsm(Lc, W, trans='N')
            chompack.trsm(Lc, W, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(W, z, x, trans='T', beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'poly':

        def classifier2(Y, soft=False):
            if Y is None: return zs

            M = Y.size[0]
            W = matrix(0., (width, M))
            blas.gemm(X, Y, W, transB='T', alpha=1.0 / sigma, m=width)
            W = W**degree
            lapack.potrs(L11, W)
            W = matrix([W, matrix(0., (N - width, M))])
            chompack.trsm(Lc, W, trans='N')
            chompack.trsm(Lc, W, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(W, z, x, trans='T', beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'rbf':

        def classifier2(Y, soft=False):

            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(0.0, (width, M))
            blas.gemm(X, Y, K, transB='T', alpha=1.0 / sigma, m=width)

            # c[i] = ||Yi||^2 / sigma
            ones = matrix(1.0, (max(width, n, M), 1))
            c = Y**2 * ones[:n]
            blas.scal(1.0 / sigma, c)

            # Kij := Kij - 0.5 * (ci + aj)
            #      = || yi - xj ||^2 / (2*sigma)
            blas.ger(ones[:width], c, K, alpha=-0.5)
            blas.ger(a[:width], ones[:M], K, alpha=-0.5)
            # Kij = exp(Kij)
            K = exp(K)

            # complete K
            lapack.potrs(L11, K)
            K = matrix([K, matrix(0., (N - width, M))], (N, M))
            chompack.trsm(Lc, K, trans='N')
            chompack.trsm(Lc, K, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(K, z, x, trans='T', beta=1.0)

            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'tanh':

        def classifier2(Y, soft=False):

            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(theta, (width, M))
            blas.gemm(X,
                      Y,
                      K,
                      transB='T',
                      alpha=1.0 / sigma,
                      beta=-1.0,
                      m=width)

            K = exp(K)
            K = div(K - K**-1, K + K**-1)

            # complete K
            lapack.potrs(L11, K)
            K = matrix([K, matrix(0., (N - width, M))], (N, M))
            chompack.trsm(Lc, K, trans='N')
            chompack.trsm(Lc, K, trans='T')

            x = matrix(b, (M, 1))
            blas.gemv(K, z, x, trans='T', beta=1.0)

            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    Ttotal = cputime(Tstart)

    return {
        'classifier': classifier,
        'completion classifier': classifier2,
        'cputime': (sum(Ttotal), sum(Tqp), sum(Tkernel)),
        'iterations': iters,
        'z': zs,
        'misclassified': (err1, err2)
    }
Beispiel #34
0
y = mul( 1.0 + 0.5 * sin(11*ts), sin(30 * sin(5*ts)))

# Basis pursuit problem
#
#     minimize    ||A*x - y||_2^2 + ||x||_1
#
#     minimize    x'*A'*A*x - 2.0*y'*A*x + 1'*u
#     subject to  -u <= x <= u
#
# Variables x (n),  u (n).

m, n = A.size
r = matrix(0.0, (m,1))

q = matrix(1.0, (2*n,1))
blas.gemv(A, y, q, alpha = -2.0, trans = 'T')


def P(u, v, alpha = 1.0, beta = 0.0):
    """
    Function and gradient evaluation of

	v := alpha * 2*A'*A * u + beta * v
    """

    blas.gemv(A, u, r)      
    blas.gemv(A, r, v, alpha = 2.0*alpha, beta = beta, trans = 'T') 
        

def G(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
    """
Beispiel #35
0
# with n variables, and matrices A(x), B of size p x q.

setseed(0)

p, q, n = 100, 100, 100
A = normal(p*q, n)
B = normal(p, q)


# options['feastol'] = 1e-6
# options['refinement'] = 3

sol = nucnrm.nrmapp(A, B)

x = sol['x']
Z = sol['Z']

s = matrix(0.0, (p,1))
X = matrix(A *x, (p, q)) + B
lapack.gesvd(+X, s)
nrmX = sum(s)
lapack.gesvd(+Z, s)
nrmZ = max(s)
res = matrix(0.0, (n, 1))
blas.gemv(A, Z, res, beta = 1.0, trans = 'T')

print "\nNuclear norm of A(x) + B: %e" %nrmX
print "Inner product of B and Z: %e" %blas.dot(B, Z)
print "Maximum singular value of Z: %e" %nrmZ
print "Euclidean norm of A'(Z): %e" %blas.nrm2(res)
Beispiel #36
0
def sysid(y, u, vsig, svth = None):

    """
    System identification using the subspace method and nuclear norm 
    optimization.  Estimate a linear time-invariant state-space model 
    given inputs and outputs.  The algorithm is described in [1].
    

    INPUT
    y       'd' matrix of size (p, N).  y are the measured outputs, p is 
            the number of outputs, and N is the number of data points 
            measured. 
    
    u       'd' matrix of size (m, N).  u are the inputs, m is the number 
            of inputs, and N is the number of data points.
    
    vsig    a weighting parameter in the nuclear norm optimization, its 
            value is approximately the 1-sigma output noise level
    
    svth    an optional parameter, if specified, the model order is 
            determined as the number of singular values greater than svth 
            times the maximum singular value.  The default value is 1E-3 
    
    OUTPUT
    sol     a dictionary with the following words
            -- 'A', 'B', 'C', 'D' are the state-space matrices
            -- 'svN', the original singular values of the Hankel matrix
            -- 'sv', the optimized singular values of the Hankel matrix
            -- 'x0', the initial state x(0)
            -- 'n', the model order

    [1] Zhang Liu and Lieven Vandenberghe. "Interior-point method for 
        nuclear norm approximation with application to system 
        identification."  

    """

    m, N, p = u.size[0], u.size[1], y.size[0]
    if y.size[1] != N:
        raise ValueError, "y and u must have the same length"
           
    # Y = G*X + H*U + V, Y has size a x b, U has size c x b, Un has b x d
    r = min(int(30/p),int((N+1.0)/(p+m+1)+1.0))
    a = r*p
    c = r*m
    b = N-r+1
    d = b-c
    
    # construct Hankel matrix Y
    Y = Hankel(y,r,b,p=p,q=1)
    
    # construct Hankel matrix U
    U = Hankel(u,r,b,p=m,q=1)
    
    # compute Un = null(U) and YUn = Y*Un
    Vt = matrix(0.0,(b,b))
    Stemp = matrix(0.0,(c,1))
    Un = matrix(0.0,(b,d))
    YUn = matrix(0.0,(a,d))
    lapack.gesvd(U,Stemp,jobvt='A',Vt=Vt)
    Un[:,:] = Vt.T[:,c:]
    blas.gemm(Y,Un,YUn)
    
    # compute original singular values
    svN = matrix(0.0,(min(a,d),1))
    lapack.gesvd(YUn,svN)
    
    # variable, [y(1);...;y(N)]
    # form the coefficient matrices for the nuclear norm optimization
    # minimize | Yh * Un |_* + alpha * | y - yh |_F
    AA = Hankel_basis(r,b,p=p,q=1)
    A = matrix(0.0,(a*d,p*N))
    temp = spmatrix([],[],[],(a,b),'d')
    temp2 = matrix(0.0,(a,d))
    for ii in xrange(p*N):
        temp[:] = AA[:,ii]
        base.gemm(temp,Un,temp2)
        A[:,ii] = temp2[:]
    B = matrix(0.0,(a,d))

    # flip the matrix if columns is more than rows
    if a < d:
        Itrans = [i+j*a for i in xrange(a) for j in xrange(d)]
        B[:] = B[Itrans]
        B.size = (d,a)
        for ii in xrange(p*N):
            A[:,ii] = A[Itrans,ii]
      
    # regularized term
    x0 = y[:]
    Qd = matrix(2.0*svN[0]/p/N/(vsig**2),(p*N,1))

    # solve the nuclear norm optimization
    sol = nrmapp(A, B, C = base.spdiag(Qd), d = -base.mul(x0, Qd))
    status = sol['status']
    x = sol['x']
    
    # construct YhUn and take the svd
    YhUn = matrix(B)
    blas.gemv(A,x,YhUn,beta=1.0)
    if a < d:
        YhUn = YhUn.T
    Uh = matrix(0.0,(a,d))
    sv = matrix(0.0,(d,1))
    lapack.gesvd(YhUn,sv,jobu='S',U=Uh)

    # determine model order
    if svth is None:
        svth = 1E-3
    svthn = sv[0]*svth
    n=1
    while sv[n] >= svthn and n < 10:
        n=n+1
    
    # estimate A, C
    Uhn = Uh[:,:n]
    for ii in xrange(n):
        blas.scal(sv[ii],Uhn,n=a,offset=ii*a)
    syseC = Uhn[:p,:]
    Als = Uhn[:-p,:]
    Bls = Uhn[p:,:]
    lapack.gels(Als,Bls)
    syseA = Bls[:n,:]
    Als[:,:] = Uhn[:-p,:]
    Bls[:,:] = Uhn[p:,:]
    blas.gemm(Als,syseA,Bls,beta=-1.0)
    Aerr = blas.nrm2(Bls)
    
    # stabilize A
    Sc = matrix(0.0,(n,n),'z')
    w = matrix(0.0, (n,1), 'z')
    Vs = matrix(0.0, (n,n), 'z')
    def F(w):
        return (abs(w) < 1.0)
    
    Sc[:,:] = syseA
    ns = lapack.gees(Sc, w, Vs, select = F)
    while ns < n:
        #print "stabilize matrix A"
        w[ns:] = w[ns:]**-1
        Sc[::n+1] = w
        Sc = Vs*Sc*Vs.H
        syseA[:,:] = Sc.real()
        Sc[:,:] = syseA
        ns = lapack.gees(Sc, w, Vs, select = F)

    # estimate B,D,x0 stored in vector [x0; vec(D); vec(B)]
    F1 = matrix(0.0,(p*N,n))
    F1[:p,:] = syseC
    for ii in xrange(1,N):
        F1[ii*p:(ii+1)*p,:] = F1[(ii-1)*p:ii*p,:]*syseA
    F2 = matrix(0.0,(p*N,p*m))
    ut = u.T
    for ii in xrange(p):
        F2[ii::p,ii::p] = ut
    F3 = matrix(0.0,(p*N,n*m))
    F3t = matrix(0.0,(p*(N-1),n*m))
    for ii in xrange(1,N):
        for jj in xrange(p):
            for kk in xrange(n):
                F3t[jj:jj+(N-ii)*p:p,kk::n] = ut[:N-ii,:]*F1[(ii-1)*p+jj,kk]
        F3[ii*p:,:] = F3[ii*p:,:] + F3t[:(N-ii)*p,:]
    
    F = matrix([[F1],[F2],[F3]])
    yls = y[:]
    Sls = matrix(0.0,(F.size[1],1))
    Uls = matrix(0.0,(F.size[0],F.size[1]))
    Vtls = matrix(0.0,(F.size[1],F.size[1]))
    lapack.gesvd(F, Sls, jobu='S', jobvt='S', U=Uls, Vt=Vtls)
    Frank=len([ii for ii in xrange(Sls.size[0]) if Sls[ii] >= 1E-6])
    #print 'Rank deficiency = ', F.size[1] - Frank
    xx = matrix(0.0,(F.size[1],1))
    xx[:Frank] = Uls.T[:Frank,:] * yls
    xx[:Frank] = base.mul(xx[:Frank],Sls[:Frank]**-1)
    xx[:] = Vtls.T[:,:Frank]*xx[:Frank] 
    blas.gemv(F,xx,yls,beta=-1.0)
    xxerr = blas.nrm2(yls)
    
    x0 = xx[:n]
    syseD = xx[n:n+p*m]
    syseD.size = (p,m)
    syseB = xx[n+p*m:]
    syseB.size = (n,m)
    
    return {'A': syseA, 'B': syseB, 'C': syseC, 'D': syseD, 'svN': svN, 'sv': \
        sv, 'x0': x0, 'n': n, 'Aerr': Aerr, 'xxerr': xxerr}
Beispiel #37
0
        def solve(x, y, z):
            """

            1. Solve for usx[0]:

               Asc'(Asc(usx[0]))
                   = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
                   = bx0 + Asc'( ( bsz0 + S * ( bsx[1] - bssz1) S ) 
                     ./ sqrtG)

               where bsx[1] = U^-1 * bx[1] * U^-T, bsz0 = U' * bz0 * U, 
               bsz1 = U' * bz1 * U, bssz1 = S^-1 * bsz1 * S^-1 

            2. Solve for usx[1]:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1 

               usx[1] 
                   = ( S * (As(usx[0]) + bsx[1] - bsz0) * S - bsz1) ./ Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 - bsz1 + S * bsx[1] * S ) . / Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 + S * ( bsx[1] - bssz1 ) * S ) . / Gamma

               Unscale ux[1] = Uti * usx[1] * Uti'

            3. Compute usz0, usz1

               r0' * uz0 * r0 = r0^-1 * ( A(ux[0]) - ux[1] - bz0 ) * r0^-T
               r1' * uz1 * r1 = r1^-1 * ( -ux[1] - bz1 ) * r1^-T

            """

            # z0 := U' * z0 * U
            #     = bsz0
            __cngrnc(U, z, trans='T')

            # z1 := Us' * bz1 * Us
            #     = S^-1 * U' * bz1 * U * S^-1
            #     = S^-1 * bsz1 * S^-1
            __cngrnc(Us, z, trans='T', offsetx=msq)

            # x[1] := Uti' * x[1] * Uti
            #       = bsx[1]
            __cngrnc(Uti, x[1], trans='T')

            # x[1] := x[1] - z[msq:]
            #       = bsx[1] - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], alpha=-1.0, offsetx=msq)

            # x1 = (S * x[1] * S + z[:msq] ) ./ sqrtG
            #    = (S * ( bsx[1] - S^-1 * bsz1 * S^-1) * S + bsz0 ) ./ sqrtG
            #    = (S * bsx[1] * S - bsz1 + bsz0 ) ./ sqrtG
            # in packed storage
            blas.copy(x[1], x1)
            blas.tbmv(S, x1, n=msq, k=0, ldA=1)
            blas.axpy(z, x1, n=msq)
            blas.tbsv(sqrtG, x1, n=msq, k=0, ldA=1)
            misc.pack2(x1, {'l': 0, 'q': [], 's': [m]})

            # x[0] := x[0] + Asc'*x1
            #       = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
            #       = bx0 + As'( ( bz0 - bz1 + S * bx[1] * S ) ./ Gamma )
            blas.gemv(Asc, x1, x[0], m=mpckd, trans='T', beta=1.0)

            # x[0] := H^-1 * x[0]
            #       = ux[0]
            lapack.potrs(H, x[0])

            # x1 = Asc(x[0]) .* sqrtG  (unpacked)
            #    = As(x[0])
            blas.gemv(Asc, x[0], tmp, m=mpckd)
            misc.unpack(tmp, x1, {'l': 0, 'q': [], 's': [m]})
            blas.tbmv(sqrtG, x1, n=msq, k=0, ldA=1)

            # usx[1] = (x1 + (x[1] - z[:msq])) ./ sqrtG**2
            #        = (As(ux[0]) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1)
            #           ./ Gamma

            # x[1] := x[1] - z[:msq]
            #       = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], -1.0, n=msq)

            # x[1] := x[1] + x1
            #       = As(ux) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(x1, x[1])

            # x[1] := x[1] / Gammma
            #       = (As(ux) + bsx[1] - bsz0 + S^-1 * bsz1 * S^-1 ) / Gamma
            #       = S^-1 * usx[1] * S^-1
            blas.tbsv(Gamma, x[1], n=msq, k=0, ldA=1)

            # z[msq:] := r1' * U * (-z[msq:] - x[1]) * U * r1
            #         := -r1' * U * S^-1 * (bsz1 + ux[1]) * S^-1 *  U * r1
            #         := -r1' * uz1 * r1
            blas.axpy(x[1], z, n=msq, offsety=msq)
            blas.scal(-1.0, z, offset=msq)
            __cngrnc(U, z, offsetx=msq)
            __cngrnc(W['r'][1], z, trans='T', offsetx=msq)

            # x[1] :=  S * x[1] * S
            #       =  usx1
            blas.tbmv(S, x[1], n=msq, k=0, ldA=1)

            # z[:msq] = r0' * U' * ( x1 - x[1] - z[:msq] ) * U * r0
            #         = r0' * U' * ( As(ux) - usx1 - bsz0 ) * U * r0
            #         = r0' * U' *  usz0 * U * r0
            #         = r0' * uz0 * r0
            blas.axpy(x1, z, -1.0, n=msq)
            blas.scal(-1.0, z, n=msq)
            blas.axpy(x[1], z, -1.0, n=msq)
            __cngrnc(U, z)
            __cngrnc(W['r'][0], z, trans='T')

            # x[1] := Uti * x[1] * Uti'
            #       = ux[1]
            __cngrnc(Uti, x[1])
Beispiel #38
0
        def f(x, y, z):
            """

            Solve 

                              C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                       -uzs11 = bX1
                                                       -uzs22 = bX2
                                           G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]       [ uzs11 uzs21' ]     
                [                ] - T * [              ] * T = bzs.
                [ -A(ux) -uX2    ]       [ uzs21 uzs22  ]

            On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
            On exit, x = (ux, uX1, uX2) and z = [ D*uzl; (r'*uzs*r)[:] ].

            Define X = uzs21, Z = T * uzs * T:   
 
                      C * ux + G' * uzl - 2*A'(X) = bx
                                [ 0  X' ]               [ bX1 0   ]
                            T * [       ] * T - Z = T * [         ] * T
                                [ X  0  ]               [ 0   bX2 ]
                               G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                [                ] - [          ] = bzs
                [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            Return x = (ux, uX1, uX2), z = [ D*uzl; (rti'*Z*rti)[:] ].

            We use the congruence transformation 

                [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
                [          ] [           ] [         ] = [       ]
                [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]

            and the factorization 

                X + S * X' * S = L( L'(X) ) 

            to write this as

                                  C * ux + G' * uzl - 2*A'(X) = bx
                L'(V2^-1 * X * V1^-1) - L^-1(V2' * Z21 * V1') = bX
                                           G * ux - D^2 * uzl = bzl
                            [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                            [                ] - [          ] = bzs,
                            [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            or

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                      XX - ZZ21 = bX
                                 Gs * ux - uuzl = D^-1 * bzl
                                 -As(ux) - ZZ21 = bbzs_21
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22

            if we introduce scaled variables

                uuzl = D * uzl
                  XX = L'(V2^-1 * X * V1^-1) 
                     = L'(V2^-1 * uzs21 * V1^-1)
                ZZ21 = L^-1(V2' * Z21 * V1') 

            and define

                bbzs_21 = L^-1(V2' * bzs_21 * V1')
                                           [ bX1  0   ]
                     bX = L^-1( V2' * (T * [          ] * T)_21 * V1').
                                           [ 0    bX2 ]           
 
            Eliminating Z21 gives 

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                 Gs * ux - uuzl = D^-1 * bzl
                                   -As(ux) - XX = bbzs_21 - bX
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22 

            and eliminating uuzl and XX gives

                        H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bX - bbzs_21)
                Gs * ux - uuzl = D^-1 * bzl
                  -As(ux) - XX = bbzs_21 - bX
                    -uX1 - Z11 = bzs_11
                    -uX2 - Z22 = bzs_22.


            In summary, we can use the following algorithm: 

            1. bXX := bX - bbzs21
                                        [ bX1 0   ]
                    = L^-1( V2' * ((T * [         ] * T)_21 - bzs_21) * V1')
                                        [ 0   bX2 ]

            2. Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            3. From ux, compute 

                   uuzl = Gs*ux - D^-1 * bzl and 
                      X = V2 * L^-T(-As(ux) + bXX) * V1.

            4. Return ux, uuzl, 

                   rti' * Z * rti = r' * [ -bX1, X'; X, -bX2 ] * r
 
               and uX1 = -Z11 - bzs_11,  uX2 = -Z22 - bzs_22.

            """

            # Save bzs_11, bzs_22, bzs_21.
            lapack.lacpy(z, bz11, uplo = 'L', m = q, n = q, ldA = p+q,
                offsetA = m)
            lapack.lacpy(z, bz21, m = p, n = q, ldA = p+q, offsetA = m+q)
            lapack.lacpy(z, bz22, uplo = 'L', m = p, n = p, ldA = p+q,
                offsetA = m + (p+q+1)*q)


            # zl := D^-1 * zl
            #     = D^-1 * bzl
            blas.tbmv(W['di'], z, n = m, k = 0, ldA = 1)


            # zs := r' * [ bX1, 0; 0, bX2 ] * r.

            # zs := [ bX1, 0; 0, bX2 ]
            blas.scal(0.0, z, offset = m)
            lapack.lacpy(x[1], z, uplo = 'L', m = q, n = q, ldB = p+q,
                offsetB = m)
            lapack.lacpy(x[2], z, uplo = 'L', m = p, n = p, ldB = p+q,
                offsetB = m + (p+q+1)*q)

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc = p+q+1, offset = m)

            # a := tril(zs)*r  
            blas.copy(r, a)
            blas.trmm(z, a, side = 'L', m = p+q, n = p+q, ldA = p+q, ldB = 
                p+q, offsetA = m)

            # zs := a'*r + r'*a 
            blas.syr2k(r, a, z, trans = 'T', n = p+q, k = p+q, ldB = p+q,
                ldC = p+q, offsetC = m)



            # bz21 := L^-1( V2' * ((r * zs * r')_21 - bz21) * V1')
            #
            #                           [ bX1 0   ]
            #       = L^-1( V2' * ((T * [         ] * T)_21 - bz21) * V1').
            #                           [ 0   bX2 ]

            # a = [ r21 r22 ] * z
            #   = [ r21 r22 ] * r' * [ bX1, 0; 0, bX2 ] * r
            #   = [ T21  T22 ] * [ bX1, 0; 0, bX2 ] * r
            blas.symm(z, r, a, side = 'R', m = p, n = p+q, ldA = p+q, 
                ldC = p+q, offsetB = q)
    
            # bz21 := -bz21 + a * [ r11, r12 ]'
            #       = -bz21 + (T * [ bX1, 0; 0, bX2 ] * T)_21
            blas.gemm(a, r, bz21, transB = 'T', m = p, n = q, k = p+q, 
                beta = -1.0, ldA = p+q, ldC = p)

            # bz21 := V2' * bz21 * V1'
            #       = V2' * (-bz21 + (T*[bX1, 0; 0, bX2]*T)_21) * V1'
            blas.gemm(V2, bz21, tmp, transA = 'T', m = p, n = q, k = p, 
                ldB = p)
            blas.gemm(tmp, V1, bz21, transB = 'T', m = p, n = q, k = q, 
                ldC = p)

            # bz21[:] := D * (I-P) * bz21[:] 
            #       = L^-1 * bz21[:]
            #       = bXX[:]
            blas.copy(bz21, tmp)
            base.gemv(P, bz21, tmp, alpha = -1.0, beta = 1.0)
            base.gemv(D, tmp, bz21)


            # Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            # x[0] := x[0] + Gs'*zl + 2*As'(bz21) 
            #       = bx + G' * D^-1 * bzl + 2 * As'(bXX)
            blas.gemv(Gs, z, x[0], trans = 'T', alpha = 1.0, beta = 1.0)
            blas.gemv(As, bz21, x[0], trans = 'T', alpha = 2.0, beta = 1.0) 

            # x[0] := H \ x[0] 
            #      = ux
            lapack.potrs(H, x[0])


            # uuzl = Gs*ux - D^-1 * bzl
            blas.gemv(Gs, x[0], z, alpha = 1.0, beta = -1.0)

            
            # bz21 := V2 * L^-T(-As(ux) + bz21) * V1
            #       = X
            blas.gemv(As, x[0], bz21, alpha = -1.0, beta = 1.0)
            blas.tbsv(DV, bz21, n = p*q, k = 0, ldA = 1)
            blas.copy(bz21, tmp)
            base.gemv(P, tmp, bz21, alpha = -1.0, beta = 1.0, trans = 'T')
            blas.gemm(V2, bz21, tmp)
            blas.gemm(tmp, V1, bz21)


            # zs := -zs + r' * [ 0, X'; X, 0 ] * r
            #     = r' * [ -bX1, X'; X, -bX2 ] * r.

            # a := bz21 * [ r11, r12 ]
            #   =  X * [ r11, r12 ]
            blas.gemm(bz21, r, a, m = p, n = p+q, k = q, ldA = p, ldC = p+q)
            
            # z := -z + [ r21, r22 ]' * a + a' * [ r21, r22 ]
            #    = rti' * uzs * rti
            blas.syr2k(r, a, z, trans = 'T', beta = -1.0, n = p+q, k = p,
                offsetA = q, offsetC = m, ldB = p+q, ldC = p+q)  



            # uX1 = -Z11 - bzs_11 
            #     = -(r*zs*r')_11 - bzs_11
            # uX2 = -Z22 - bzs_22 
            #     = -(r*zs*r')_22 - bzs_22


            blas.copy(bz11, x[1])
            blas.copy(bz22, x[2])

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc = p+q+1, offset = m)

            # a := r*tril(zs)  
            blas.copy(r, a)
            blas.trmm(z, a, side = 'R', m = p+q, n = p+q, ldA = p+q, ldB = 
                p+q, offsetA = m)

            # x[1] := -x[1] - a[:q,:] * r[:q, :]' - r[:q,:] * a[:q,:]'
            #       = -bzs_11 - (r*zs*r')_11
            blas.syr2k(a, r, x[1], n = q, alpha = -1.0, beta = -1.0) 

            # x[2] := -x[2] - a[q:,:] * r[q:, :]' - r[q:,:] * a[q:,:]'
            #       = -bzs_22 - (r*zs*r')_22
            blas.syr2k(a, r, x[2], n = p, alpha = -1.0, beta = -1.0, 
                offsetA = q, offsetB = q)

            # scale diagonal of zs by 1/2
            blas.scal(2.0, z, inc = p+q+1, offset = m)
Beispiel #39
0
def scale(x, W, trans='N', inverse='N'):
    """
    Applies Nesterov-Todd scaling or its inverse.

    Computes

         x := W*x        (trans is 'N', inverse = 'N')
         x := W^T*x      (trans is 'T', inverse = 'N')
         x := W^{-1}*x   (trans is 'N', inverse = 'I')
         x := W^{-T}*x   (trans is 'T', inverse = 'I').

    x is a dense 'd' matrix.

    W is a dictionary with entries:

    - W['dnl']: positive vector
    - W['dnli']: componentwise inverse of W['dnl']
    - W['d']: positive vector
    - W['di']: componentwise inverse of W['d']
    - W['v']: lists of 2nd order cone vectors with unit hyperbolic norms
    - W['beta']: list of positive numbers
    - W['r']: list of square matrices
    - W['rti']: list of square matrices.  rti[k] is the inverse transpose
      of r[k].

    The 'dnl' and 'dnli' entries are optional, and only present when the
    function is called from the nonlinear solver.
    """
    from cvxopt import blas

    ind = 0

    # Scaling for nonlinear component xk is xk := dnl .* xk; inverse
    # scaling is xk ./ dnl = dnli .* xk, where dnl = W['dnl'],
    # dnli = W['dnli'].

    if 'dnl' in W:
        if inverse == 'N':
            w = W['dnl']
        else:
            w = W['dnli']
        for k in range(x.size[1]):
            blas.tbmv(w, x, n=w.size[0], k=0, ldA=1, offsetx=k * x.size[0])
        ind += w.size[0]

    # Scaling for linear 'l' component xk is xk := d .* xk; inverse
    # scaling is xk ./ d = di .* xk, where d = W['d'], di = W['di'].

    if inverse == 'N':
        w = W['d']
    else:
        w = W['di']
    for k in range(x.size[1]):
        blas.tbmv(w, x, n=w.size[0], k=0, ldA=1, offsetx=k * x.size[0] + ind)
    ind += w.size[0]

    # Scaling for 'q' component is
    #
    #     xk := beta * (2*v*v' - J) * xk
    #         = beta * (2*v*(xk'*v)' - J*xk)
    #
    # where beta = W['beta'][k], v = W['v'][k], J = [1, 0; 0, -I].
    #
    # Inverse scaling is
    #
    #     xk := 1/beta * (2*J*v*v'*J - J) * xk
    #         = 1/beta * (-J) * (2*v*((-J*xk)'*v)' + xk).

    w = matrix(0.0, (x.size[1], 1))
    for k in range(len(W['v'])):
        v = W['v'][k]
        m = v.size[0]
        if inverse == 'I':
            blas.scal(-1.0, x, offset=ind, inc=x.size[0])
        blas.gemv(x, v, w, trans='T', m=m, n=x.size[1], offsetA=ind, ldA=x.size[0])
        blas.scal(-1.0, x, offset=ind, inc=x.size[0])
        blas.ger(v, w, x, alpha=2.0, m=m, n=x.size[1], ldA=x.size[0], offsetA=ind)
        if inverse == 'I':
            blas.scal(-1.0, x, offset=ind, inc=x.size[0])
            a = 1.0 / W['beta'][k]
        else:
            a = W['beta'][k]
        for i in range(x.size[1]):
            blas.scal(a, x, n=m, offset=ind + i * x.size[0])
        ind += m

    # Scaling for 's' component xk is
    #
    #     xk := vec( r' * mat(xk) * r )  if trans = 'N'
    #     xk := vec( r * mat(xk) * r' )  if trans = 'T'.
    #
    # r is kth element of W['r'].
    #
    # Inverse scaling is
    #
    #     xk := vec( rti * mat(xk) * rti' )  if trans = 'N'
    #     xk := vec( rti' * mat(xk) * rti )  if trans = 'T'.
    #
    # rti is kth element of W['rti'].

    maxn = max([0] + [r.size[0] for r in W['r']])
    a = matrix(0.0, (maxn, maxn))
    for k in range(len(W['r'])):

        if inverse == 'N':
            r = W['r'][k]
            if trans == 'N':
                t = 'T'
            else:
                t = 'N'
        else:
            r = W['rti'][k]
            t = trans

        n = r.size[0]
        for i in range(x.size[1]):

            # scale diagonal of xk by 0.5
            blas.scal(0.5, x, offset=ind + i * x.size[0], inc=n + 1, n=n)

            # a = r*tril(x) (t is 'N') or a = tril(x)*r  (t is 'T')
            blas.copy(r, a)
            if t == 'N':
                blas.trmm(x, a, side='R', m=n, n=n, ldA=n, ldB=n,
                          offsetA=ind + i * x.size[0])
            else:
                blas.trmm(x, a, side='L', m=n, n=n, ldA=n, ldB=n,
                          offsetA=ind + i * x.size[0])

            # x := (r*a' + a*r')  if t is 'N'
            # x := (r'*a + a'*r)  if t is 'T'
            blas.syr2k(r, a, x, trans=t, n=n, k=n, ldB=n, ldC=n,
                       offsetC=ind + i * x.size[0])

        ind += n ** 2
Beispiel #40
0
        def f(x, y, z):
            """

            Solve 

                              C * ux + G' * uzl - 2*A'(uzs21) = bx
                                                       -uzs11 = bX1
                                                       -uzs22 = bX2
                                           G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]       [ uzs11 uzs21' ]     
                [                ] - T * [              ] * T = bzs.
                [ -A(ux) -uX2    ]       [ uzs21 uzs22  ]

            On entry, x = (bx, bX1, bX2) and z = [ bzl; bzs[:] ].
            On exit, x = (ux, uX1, uX2) and z = [ D*uzl; (r'*uzs*r)[:] ].

            Define X = uzs21, Z = T * uzs * T:   
 
                      C * ux + G' * uzl - 2*A'(X) = bx
                                [ 0  X' ]               [ bX1 0   ]
                            T * [       ] * T - Z = T * [         ] * T
                                [ X  0  ]               [ 0   bX2 ]
                               G * ux - D^2 * uzl = bzl
                [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                [                ] - [          ] = bzs
                [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            Return x = (ux, uX1, uX2), z = [ D*uzl; (rti'*Z*rti)[:] ].

            We use the congruence transformation 

                [ V1   0   ] [ T11  T21' ] [ V1'  0  ]   [ I  S' ]
                [          ] [           ] [         ] = [       ]
                [ 0    V2' ] [ T21  T22  ] [ 0    V2 ]   [ S  I  ]

            and the factorization 

                X + S * X' * S = L( L'(X) ) 

            to write this as

                                  C * ux + G' * uzl - 2*A'(X) = bx
                L'(V2^-1 * X * V1^-1) - L^-1(V2' * Z21 * V1') = bX
                                           G * ux - D^2 * uzl = bzl
                            [ -uX1   -A(ux)' ]   [ Z11 Z21' ]     
                            [                ] - [          ] = bzs,
                            [ -A(ux) -uX2    ]   [ Z21 Z22  ]

            or

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                      XX - ZZ21 = bX
                                 Gs * ux - uuzl = D^-1 * bzl
                                 -As(ux) - ZZ21 = bbzs_21
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22

            if we introduce scaled variables

                uuzl = D * uzl
                  XX = L'(V2^-1 * X * V1^-1) 
                     = L'(V2^-1 * uzs21 * V1^-1)
                ZZ21 = L^-1(V2' * Z21 * V1') 

            and define

                bbzs_21 = L^-1(V2' * bzs_21 * V1')
                                           [ bX1  0   ]
                     bX = L^-1( V2' * (T * [          ] * T)_21 * V1').
                                           [ 0    bX2 ]           
 
            Eliminating Z21 gives 

                C * ux + Gs' * uuzl - 2*As'(XX) = bx
                                 Gs * ux - uuzl = D^-1 * bzl
                                   -As(ux) - XX = bbzs_21 - bX
                                     -uX1 - Z11 = bzs_11
                                     -uX2 - Z22 = bzs_22 

            and eliminating uuzl and XX gives

                        H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bX - bbzs_21)
                Gs * ux - uuzl = D^-1 * bzl
                  -As(ux) - XX = bbzs_21 - bX
                    -uX1 - Z11 = bzs_11
                    -uX2 - Z22 = bzs_22.


            In summary, we can use the following algorithm: 

            1. bXX := bX - bbzs21
                                        [ bX1 0   ]
                    = L^-1( V2' * ((T * [         ] * T)_21 - bzs_21) * V1')
                                        [ 0   bX2 ]

            2. Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            3. From ux, compute 

                   uuzl = Gs*ux - D^-1 * bzl and 
                      X = V2 * L^-T(-As(ux) + bXX) * V1.

            4. Return ux, uuzl, 

                   rti' * Z * rti = r' * [ -bX1, X'; X, -bX2 ] * r
 
               and uX1 = -Z11 - bzs_11,  uX2 = -Z22 - bzs_22.

            """

            # Save bzs_11, bzs_22, bzs_21.
            lapack.lacpy(z, bz11, uplo='L', m=q, n=q, ldA=p + q, offsetA=m)
            lapack.lacpy(z, bz21, m=p, n=q, ldA=p + q, offsetA=m + q)
            lapack.lacpy(z,
                         bz22,
                         uplo='L',
                         m=p,
                         n=p,
                         ldA=p + q,
                         offsetA=m + (p + q + 1) * q)

            # zl := D^-1 * zl
            #     = D^-1 * bzl
            blas.tbmv(W['di'], z, n=m, k=0, ldA=1)

            # zs := r' * [ bX1, 0; 0, bX2 ] * r.

            # zs := [ bX1, 0; 0, bX2 ]
            blas.scal(0.0, z, offset=m)
            lapack.lacpy(x[1], z, uplo='L', m=q, n=q, ldB=p + q, offsetB=m)
            lapack.lacpy(x[2],
                         z,
                         uplo='L',
                         m=p,
                         n=p,
                         ldB=p + q,
                         offsetB=m + (p + q + 1) * q)

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc=p + q + 1, offset=m)

            # a := tril(zs)*r
            blas.copy(r, a)
            blas.trmm(z,
                      a,
                      side='L',
                      m=p + q,
                      n=p + q,
                      ldA=p + q,
                      ldB=p + q,
                      offsetA=m)

            # zs := a'*r + r'*a
            blas.syr2k(r,
                       a,
                       z,
                       trans='T',
                       n=p + q,
                       k=p + q,
                       ldB=p + q,
                       ldC=p + q,
                       offsetC=m)

            # bz21 := L^-1( V2' * ((r * zs * r')_21 - bz21) * V1')
            #
            #                           [ bX1 0   ]
            #       = L^-1( V2' * ((T * [         ] * T)_21 - bz21) * V1').
            #                           [ 0   bX2 ]

            # a = [ r21 r22 ] * z
            #   = [ r21 r22 ] * r' * [ bX1, 0; 0, bX2 ] * r
            #   = [ T21  T22 ] * [ bX1, 0; 0, bX2 ] * r
            blas.symm(z,
                      r,
                      a,
                      side='R',
                      m=p,
                      n=p + q,
                      ldA=p + q,
                      ldC=p + q,
                      offsetB=q)

            # bz21 := -bz21 + a * [ r11, r12 ]'
            #       = -bz21 + (T * [ bX1, 0; 0, bX2 ] * T)_21
            blas.gemm(a,
                      r,
                      bz21,
                      transB='T',
                      m=p,
                      n=q,
                      k=p + q,
                      beta=-1.0,
                      ldA=p + q,
                      ldC=p)

            # bz21 := V2' * bz21 * V1'
            #       = V2' * (-bz21 + (T*[bX1, 0; 0, bX2]*T)_21) * V1'
            blas.gemm(V2, bz21, tmp, transA='T', m=p, n=q, k=p, ldB=p)
            blas.gemm(tmp, V1, bz21, transB='T', m=p, n=q, k=q, ldC=p)

            # bz21[:] := D * (I-P) * bz21[:]
            #       = L^-1 * bz21[:]
            #       = bXX[:]
            blas.copy(bz21, tmp)
            base.gemv(P, bz21, tmp, alpha=-1.0, beta=1.0)
            base.gemv(D, tmp, bz21)

            # Solve H * ux = bx + Gs' * D^-1 * bzl + 2*As'(bXX).

            # x[0] := x[0] + Gs'*zl + 2*As'(bz21)
            #       = bx + G' * D^-1 * bzl + 2 * As'(bXX)
            blas.gemv(Gs, z, x[0], trans='T', alpha=1.0, beta=1.0)
            blas.gemv(As, bz21, x[0], trans='T', alpha=2.0, beta=1.0)

            # x[0] := H \ x[0]
            #      = ux
            lapack.potrs(H, x[0])

            # uuzl = Gs*ux - D^-1 * bzl
            blas.gemv(Gs, x[0], z, alpha=1.0, beta=-1.0)

            # bz21 := V2 * L^-T(-As(ux) + bz21) * V1
            #       = X
            blas.gemv(As, x[0], bz21, alpha=-1.0, beta=1.0)
            blas.tbsv(DV, bz21, n=p * q, k=0, ldA=1)
            blas.copy(bz21, tmp)
            base.gemv(P, tmp, bz21, alpha=-1.0, beta=1.0, trans='T')
            blas.gemm(V2, bz21, tmp)
            blas.gemm(tmp, V1, bz21)

            # zs := -zs + r' * [ 0, X'; X, 0 ] * r
            #     = r' * [ -bX1, X'; X, -bX2 ] * r.

            # a := bz21 * [ r11, r12 ]
            #   =  X * [ r11, r12 ]
            blas.gemm(bz21, r, a, m=p, n=p + q, k=q, ldA=p, ldC=p + q)

            # z := -z + [ r21, r22 ]' * a + a' * [ r21, r22 ]
            #    = rti' * uzs * rti
            blas.syr2k(r,
                       a,
                       z,
                       trans='T',
                       beta=-1.0,
                       n=p + q,
                       k=p,
                       offsetA=q,
                       offsetC=m,
                       ldB=p + q,
                       ldC=p + q)

            # uX1 = -Z11 - bzs_11
            #     = -(r*zs*r')_11 - bzs_11
            # uX2 = -Z22 - bzs_22
            #     = -(r*zs*r')_22 - bzs_22

            blas.copy(bz11, x[1])
            blas.copy(bz22, x[2])

            # scale diagonal of zs by 1/2
            blas.scal(0.5, z, inc=p + q + 1, offset=m)

            # a := r*tril(zs)
            blas.copy(r, a)
            blas.trmm(z,
                      a,
                      side='R',
                      m=p + q,
                      n=p + q,
                      ldA=p + q,
                      ldB=p + q,
                      offsetA=m)

            # x[1] := -x[1] - a[:q,:] * r[:q, :]' - r[:q,:] * a[:q,:]'
            #       = -bzs_11 - (r*zs*r')_11
            blas.syr2k(a, r, x[1], n=q, alpha=-1.0, beta=-1.0)

            # x[2] := -x[2] - a[q:,:] * r[q:, :]' - r[q:,:] * a[q:,:]'
            #       = -bzs_22 - (r*zs*r')_22
            blas.syr2k(a,
                       r,
                       x[2],
                       n=p,
                       alpha=-1.0,
                       beta=-1.0,
                       offsetA=q,
                       offsetB=q)

            # scale diagonal of zs by 1/2
            blas.scal(2.0, z, inc=p + q + 1, offset=m)
Beispiel #41
0
def sysid(y, u, vsig, svth=None):
    """
    System identification using the subspace method and nuclear norm 
    optimization.  Estimate a linear time-invariant state-space model 
    given inputs and outputs.  The algorithm is described in [1].
    

    INPUT
    y       'd' matrix of size (p, N).  y are the measured outputs, p is 
            the number of outputs, and N is the number of data points 
            measured. 
    
    u       'd' matrix of size (m, N).  u are the inputs, m is the number 
            of inputs, and N is the number of data points.
    
    vsig    a weighting parameter in the nuclear norm optimization, its 
            value is approximately the 1-sigma output noise level
    
    svth    an optional parameter, if specified, the model order is 
            determined as the number of singular values greater than svth 
            times the maximum singular value.  The default value is 1E-3 
    
    OUTPUT
    sol     a dictionary with the following words
            -- 'A', 'B', 'C', 'D' are the state-space matrices
            -- 'svN', the original singular values of the Hankel matrix
            -- 'sv', the optimized singular values of the Hankel matrix
            -- 'x0', the initial state x(0)
            -- 'n', the model order

    [1] Zhang Liu and Lieven Vandenberghe. "Interior-point method for 
        nuclear norm approximation with application to system 
        identification."  

    """

    m, N, p = u.size[0], u.size[1], y.size[0]
    if y.size[1] != N:
        raise ValueError, "y and u must have the same length"

    # Y = G*X + H*U + V, Y has size a x b, U has size c x b, Un has b x d
    r = min(int(30 / p), int((N + 1.0) / (p + m + 1) + 1.0))
    a = r * p
    c = r * m
    b = N - r + 1
    d = b - c

    # construct Hankel matrix Y
    Y = Hankel(y, r, b, p=p, q=1)

    # construct Hankel matrix U
    U = Hankel(u, r, b, p=m, q=1)

    # compute Un = null(U) and YUn = Y*Un
    Vt = matrix(0.0, (b, b))
    Stemp = matrix(0.0, (c, 1))
    Un = matrix(0.0, (b, d))
    YUn = matrix(0.0, (a, d))
    lapack.gesvd(U, Stemp, jobvt='A', Vt=Vt)
    Un[:, :] = Vt.T[:, c:]
    blas.gemm(Y, Un, YUn)

    # compute original singular values
    svN = matrix(0.0, (min(a, d), 1))
    lapack.gesvd(YUn, svN)

    # variable, [y(1);...;y(N)]
    # form the coefficient matrices for the nuclear norm optimization
    # minimize | Yh * Un |_* + alpha * | y - yh |_F
    AA = Hankel_basis(r, b, p=p, q=1)
    A = matrix(0.0, (a * d, p * N))
    temp = spmatrix([], [], [], (a, b), 'd')
    temp2 = matrix(0.0, (a, d))
    for ii in xrange(p * N):
        temp[:] = AA[:, ii]
        base.gemm(temp, Un, temp2)
        A[:, ii] = temp2[:]
    B = matrix(0.0, (a, d))

    # flip the matrix if columns is more than rows
    if a < d:
        Itrans = [i + j * a for i in xrange(a) for j in xrange(d)]
        B[:] = B[Itrans]
        B.size = (d, a)
        for ii in xrange(p * N):
            A[:, ii] = A[Itrans, ii]

    # regularized term
    x0 = y[:]
    Qd = matrix(2.0 * svN[0] / p / N / (vsig**2), (p * N, 1))

    # solve the nuclear norm optimization
    sol = nrmapp(A, B, C=base.spdiag(Qd), d=-base.mul(x0, Qd))
    status = sol['status']
    x = sol['x']

    # construct YhUn and take the svd
    YhUn = matrix(B)
    blas.gemv(A, x, YhUn, beta=1.0)
    if a < d:
        YhUn = YhUn.T
    Uh = matrix(0.0, (a, d))
    sv = matrix(0.0, (d, 1))
    lapack.gesvd(YhUn, sv, jobu='S', U=Uh)

    # determine model order
    if svth is None:
        svth = 1E-3
    svthn = sv[0] * svth
    n = 1
    while sv[n] >= svthn and n < 10:
        n = n + 1

    # estimate A, C
    Uhn = Uh[:, :n]
    for ii in xrange(n):
        blas.scal(sv[ii], Uhn, n=a, offset=ii * a)
    syseC = Uhn[:p, :]
    Als = Uhn[:-p, :]
    Bls = Uhn[p:, :]
    lapack.gels(Als, Bls)
    syseA = Bls[:n, :]
    Als[:, :] = Uhn[:-p, :]
    Bls[:, :] = Uhn[p:, :]
    blas.gemm(Als, syseA, Bls, beta=-1.0)
    Aerr = blas.nrm2(Bls)

    # stabilize A
    Sc = matrix(0.0, (n, n), 'z')
    w = matrix(0.0, (n, 1), 'z')
    Vs = matrix(0.0, (n, n), 'z')

    def F(w):
        return (abs(w) < 1.0)

    Sc[:, :] = syseA
    ns = lapack.gees(Sc, w, Vs, select=F)
    while ns < n:
        #print "stabilize matrix A"
        w[ns:] = w[ns:]**-1
        Sc[::n + 1] = w
        Sc = Vs * Sc * Vs.H
        syseA[:, :] = Sc.real()
        Sc[:, :] = syseA
        ns = lapack.gees(Sc, w, Vs, select=F)

    # estimate B,D,x0 stored in vector [x0; vec(D); vec(B)]
    F1 = matrix(0.0, (p * N, n))
    F1[:p, :] = syseC
    for ii in xrange(1, N):
        F1[ii * p:(ii + 1) * p, :] = F1[(ii - 1) * p:ii * p, :] * syseA
    F2 = matrix(0.0, (p * N, p * m))
    ut = u.T
    for ii in xrange(p):
        F2[ii::p, ii::p] = ut
    F3 = matrix(0.0, (p * N, n * m))
    F3t = matrix(0.0, (p * (N - 1), n * m))
    for ii in xrange(1, N):
        for jj in xrange(p):
            for kk in xrange(n):
                F3t[jj:jj + (N - ii) * p:p,
                    kk::n] = ut[:N - ii, :] * F1[(ii - 1) * p + jj, kk]
        F3[ii * p:, :] = F3[ii * p:, :] + F3t[:(N - ii) * p, :]

    F = matrix([[F1], [F2], [F3]])
    yls = y[:]
    Sls = matrix(0.0, (F.size[1], 1))
    Uls = matrix(0.0, (F.size[0], F.size[1]))
    Vtls = matrix(0.0, (F.size[1], F.size[1]))
    lapack.gesvd(F, Sls, jobu='S', jobvt='S', U=Uls, Vt=Vtls)
    Frank = len([ii for ii in xrange(Sls.size[0]) if Sls[ii] >= 1E-6])
    #print 'Rank deficiency = ', F.size[1] - Frank
    xx = matrix(0.0, (F.size[1], 1))
    xx[:Frank] = Uls.T[:Frank, :] * yls
    xx[:Frank] = base.mul(xx[:Frank], Sls[:Frank]**-1)
    xx[:] = Vtls.T[:, :Frank] * xx[:Frank]
    blas.gemv(F, xx, yls, beta=-1.0)
    xxerr = blas.nrm2(yls)

    x0 = xx[:n]
    syseD = xx[n:n + p * m]
    syseD.size = (p, m)
    syseB = xx[n + p * m:]
    syseB.size = (n, m)

    return {'A': syseA, 'B': syseB, 'C': syseC, 'D': syseD, 'svN': svN, 'sv': \
        sv, 'x0': x0, 'n': n, 'Aerr': Aerr, 'xxerr': xxerr}
Beispiel #42
0
    def F(W):
        """
        Custom solver for the system

        [  It  0   0    Xt'     0     At1' ...  Atk' ][ dwt  ]   [ rwt ]
        [  0   0   0    -d'     0      0   ...   0   ][ db   ]   [ rb  ]
        [  0   0   0    -I     -I      0   ...   0   ][ dv   ]   [ rv  ]
        [  Xt -d  -I  -Wl1^-2                        ][ dzl1 ]   [ rl1 ]
        [  0   0  -I         -Wl2^-2                 ][ dzl2 ] = [ rl2 ]
        [ At1  0   0                -W1^-2           ][ dz1  ]   [ r1  ] 
        [  |   |   |                       .         ][  |   ]   [  |  ]
        [ Atk  0   0                          -Wk^-2 ][ dzk  ]   [ rk  ]

        where

        It = [ I 0 ]  Xt = [ -D*X E ]  Ati = [ 0   -e_i' ]  
             [ 0 0 ]                         [ -Pi   0   ] 

        dwt = [ dw ]  rwt = [ rw ]
              [ dt ]        [ rt ].

        """

        # scalings and 'intermediate' vectors
        # db = inv(Wl1)^2 + inv(Wl2)^2
        db = W['di'][:m]**2 + W['di'][m:2 * m]**2
        dbi = div(1.0, db)

        # dt = I - inv(Wl1)*Dbi*inv(Wl1)
        dt = 1.0 - mul(W['di'][:m]**2, dbi)
        dtsqrt = sqrt(dt)

        # lam = Dt*inv(Wl1)*d
        lam = mul(dt, mul(W['di'][:m], d))

        # lt = E'*inv(Wl1)*lam
        lt = matrix(0.0, (k, 1))
        base.gemv(E, mul(W['di'][:m], lam), lt, trans='T')

        # Xs = sqrt(Dt)*inv(Wl1)*X
        tmp = mul(dtsqrt, W['di'][:m])
        Xs = spmatrix(tmp, range(m), range(m)) * X

        # Es = D*sqrt(Dt)*inv(Wl1)*E
        Es = spmatrix(mul(d, tmp), range(m), range(m)) * E

        # form Ab = I + sum((1/bi)^2*(Pi'*Pi + 4*(v'*v + 1)*Pi'*y*y'*Pi)) + Xs'*Xs
        #  and Bb = -sum((1/bi)^2*(4*ui*v'*v*Pi'*y*ei')) - Xs'*Es
        #  and D2 = Es'*Es + sum((1/bi)^2*(1+4*ui^2*(v'*v - 1))
        Ab = matrix(0.0, (n, n))
        Ab[::n + 1] = 1.0
        base.syrk(Xs, Ab, trans='T', beta=1.0)
        Bb = matrix(0.0, (n, k))
        Bb = -Xs.T * Es  # inefficient!?
        D2 = spmatrix(0.0, range(k), range(k))
        base.syrk(Es, D2, trans='T', partial=True)
        d2 = +D2.V
        del D2
        py = matrix(0.0, (n, 1))
        for i in range(k):
            binvsq = (1.0 / W['beta'][i])**2
            Ab += binvsq * Pt[i]
            dvv = blas.dot(W['v'][i], W['v'][i])
            blas.gemv(P[i], W['v'][i][1:], py, trans='T', alpha=1.0, beta=0.0)
            blas.syrk(py, Ab, alpha=4 * binvsq * (dvv + 1), beta=1.0)
            Bb[:, i] -= 4 * binvsq * W['v'][i][0] * dvv * py
            d2[i] += binvsq * (1 + 4 * (W['v'][i][0]**2) * (dvv - 1))

        d2i = div(1.0, d2)
        d2isqrt = sqrt(d2i)

        # compute a = alpha - lam'*inv(Wl1)*E*inv(D2)*E'*inv(Wl1)*lam
        alpha = blas.dot(lam, mul(W['di'][:m], d))
        tmp = matrix(0.0, (k, 1))
        base.gemv(E, mul(W['di'][:m], lam), tmp, trans='T')
        tmp = mul(tmp, d2isqrt)  #tmp = inv(D2)^(1/2)*E'*inv(Wl1)*lam
        a = alpha - blas.dot(tmp, tmp)

        # compute M12 = X'*D*inv(Wl1)*lam + Bb*inv(D2)*E'*inv(Wl1)*lam
        tmp = mul(tmp, d2isqrt)
        M12 = matrix(0.0, (n, 1))
        blas.gemv(Bb, tmp, M12, alpha=1.0)
        tmp = mul(d, mul(W['di'][:m], lam))
        blas.gemv(X, tmp, M12, trans='T', alpha=1.0, beta=1.0)

        # form and factor M
        sBb = Bb * spmatrix(d2isqrt, range(k), range(k))
        base.syrk(sBb, Ab, alpha=-1.0, beta=1.0)
        M = matrix([[Ab, M12.T], [M12, a]])
        lapack.potrf(M)

        def f(x, y, z):

            # residuals
            rwt = x[:n + k]
            rb = x[n + k]
            rv = x[n + k + 1:n + k + 1 + m]
            iw_rl1 = mul(W['di'][:m], z[:m])
            iw_rl2 = mul(W['di'][m:2 * m], z[m:2 * m])
            ri = [
                z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)]
                for i in range(k)
            ]

            # compute 'derived' residuals
            # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1
            rbwt = +rwt
            for i in range(k):
                tmp = +ri[i]
                qscal(tmp, W['beta'][i], W['v'][i], inv=True)
                qscal(tmp, W['beta'][i], W['v'][i], inv=True)
                rbwt[n + i] -= tmp[0]
                blas.gemv(P[i], tmp[1:], rbwt, trans='T', alpha=-1.0, beta=1.0)
            tmp = mul(W['di'][:m], iw_rl1)
            tmp2 = matrix(0.0, (k, 1))
            base.gemv(E, tmp, tmp2, trans='T')
            rbwt[n:] += tmp2
            tmp = mul(d, tmp)  # tmp = D*inv(Wl1)^2*rl1
            blas.gemv(X, tmp, rbwt, trans='T', alpha=-1.0, beta=1.0)

            # rbb = rb - d'*inv(Wl1)^2*rl1
            rbb = rb - sum(tmp)

            # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1
            rbv = rv - mul(W['di'][m:2 * m], iw_rl2) - mul(W['di'][:m], iw_rl1)

            # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv
            tmp = mul(W['di'][:m]**2, mul(dbi, rbv))
            rtt = +rbwt[n:]
            base.gemv(E, tmp, rtt, trans='T', alpha=1.0, beta=1.0)
            rtw = +rbwt[:n]
            tmp = mul(d, tmp)
            blas.gemv(X, tmp, rtw, trans='T', alpha=-1.0, beta=1.0)

            # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv
            rtb = rbb - sum(tmp)

            # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt]
            tmp = mul(d2i, rtt)
            tmp2 = matrix(0.0, (n, 1))
            blas.gemv(Bb, tmp, tmp2)
            dwdb = matrix([rtw - tmp2, rtb + blas.dot(mul(d2i, lt), rtt)])
            lapack.potrs(M, dwdb)

            # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db)
            tmp2 = matrix(0.0, (k, 1))
            blas.gemv(Bb, dwdb[:n], tmp2, trans='T')
            dt = mul(d2i, rtt - tmp2 + lt * dwdb[-1])

            # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db))
            dv = matrix(0.0, (m, 1))
            blas.gemv(X, dwdb[:n], dv, alpha=-1.0)
            dv = mul(d, dv) - d * dwdb[-1]
            base.gemv(E, dt, dv, beta=1.0)
            tmp = +dv  # tmp = E*dt - D*X*dw - d*db
            dv = mul(dbi, rbv + mul(W['di'][:m]**2, dv))

            # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1)
            wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1

            # compute wdz2 = - inv(Wl2)*(dv + rl2)
            wdz2 = -mul(W['di'][m:2 * m], dv) - iw_rl2

            # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri)
            wdzi = []
            tmp = matrix(0.0, (n, 1))
            for i in range(k):
                blas.gemv(P[i], dwdb[:n], tmp, alpha=-1.0, beta=0.0)
                tmp1 = matrix([-dt[i], tmp])
                blas.axpy(ri[i], tmp1, alpha=-1.0)
                qscal(tmp1, W['beta'][i], W['v'][i], inv=True)
                wdzi.append(tmp1)

            # solution
            x[:n] = dwdb[:n]
            x[n:n + k] = dt
            x[n + k] = dwdb[-1]
            x[n + k + 1:] = dv
            z[:m] = wdz1
            z[m:2 * m] = wdz2
            for i in range(k):
                z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] = wdzi[i]

        return f
Beispiel #43
0
        def f(x,y,z):
            
            # residuals
            rwt = x[:n+k]
            rb = x[n+k]
            rv = x[n+k+1:n+k+1+m]
            iw_rl1 = mul(W['di'][:m],z[:m])
            iw_rl2 = mul(W['di'][m:2*m],z[m:2*m])
            ri = [z[2*m+i*(n+1):2*m+(i+1)*(n+1)] for i in range(k)]
            
            # compute 'derived' residuals 
            # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1
            rbwt = +rwt
            for i in range(k):
                tmp = +ri[i]
                qscal(tmp,W['beta'][i],W['v'][i],inv=True)
                qscal(tmp,W['beta'][i],W['v'][i],inv=True)
                rbwt[n+i] -= tmp[0]
                blas.gemv(P[i], tmp[1:], rbwt, trans = 'T', alpha = -1.0, beta = 1.0)
            tmp = mul(W['di'][:m],iw_rl1)
            tmp2 = matrix(0.0,(k,1))
            base.gemv(E,tmp,tmp2,trans='T')
            rbwt[n:] += tmp2
            tmp = mul(d,tmp) # tmp = D*inv(Wl1)^2*rl1
            blas.gemv(X,tmp,rbwt,trans='T', alpha = -1.0, beta = 1.0)
            
            # rbb = rb - d'*inv(Wl1)^2*rl1
            rbb = rb - sum(tmp)

            # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1
            rbv = rv - mul(W['di'][m:2*m],iw_rl2) - mul(W['di'][:m],iw_rl1) 
            
            # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv 
            tmp = mul(W['di'][:m]**2, mul(dbi,rbv))
            rtt = +rbwt[n:] 
            base.gemv(E, tmp, rtt, trans = 'T', alpha = 1.0, beta = 1.0)
            rtw = +rbwt[:n]
            tmp = mul(d,tmp)
            blas.gemv(X, tmp, rtw, trans = 'T', alpha = -1.0, beta = 1.0)

            # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv
            rtb = rbb - sum(tmp)
            
            # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt]
            tmp = mul(d2i,rtt)
            tmp2 = matrix(0.0,(n,1))
            blas.gemv(Bb,tmp,tmp2)
            dwdb = matrix([rtw - tmp2,rtb + blas.dot(mul(d2i,lt),rtt)]) 
            lapack.potrs(M,dwdb)

            # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db)
            tmp2 = matrix(0.0,(k,1))
            blas.gemv(Bb, dwdb[:n], tmp2, trans='T')
            dt = mul(d2i, rtt - tmp2 + lt*dwdb[-1])

            # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db))
            dv = matrix(0.0,(m,1))
            blas.gemv(X,dwdb[:n],dv,alpha = -1.0)
            dv = mul(d,dv) - d*dwdb[-1]
            base.gemv(E, dt, dv, beta = 1.0)
            tmp = +dv  # tmp = E*dt - D*X*dw - d*db
            dv = mul(dbi, rbv + mul(W['di'][:m]**2,dv))

            # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1)
            wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1

            # compute wdz2 = - inv(Wl2)*(dv + rl2)
            wdz2 = - mul(W['di'][m:2*m],dv) - iw_rl2

            # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri)
            wdzi = []
            tmp = matrix(0.0,(n,1))
            for i in range(k):
                blas.gemv(P[i],dwdb[:n],tmp, alpha = -1.0, beta = 0.0) 
                tmp1 = matrix([-dt[i],tmp])
                blas.axpy(ri[i],tmp1,alpha = -1.0)
                qscal(tmp1,W['beta'][i],W['v'][i],inv=True)
                wdzi.append(tmp1)

            # solution
            x[:n] = dwdb[:n]
            x[n:n+k] = dt
            x[n+k] = dwdb[-1]
            x[n+k+1:] = dv
            z[:m] = wdz1 
            z[m:2*m] = wdz2
            for i in range(k):
                z[2*m+i*(n+1):2*m+(i+1)*(n+1)] = wdzi[i]
Beispiel #44
0
                 x0=[0.5,0.5,0.5],
                 lb=lb, ub=ub,
                 method='bar',
                 disp=3, full_output=True)

xhat,output = ip(objFH.cost, objFH.gradient, hessian=None, x0=[0.5,0.5,0.5], lb=lb, ub=ub,disp=3,full_output=True)

xhat,output = ipD(objFH.cost, objFH.gradient, hessian=objFH.jtj, x0=[0.5,0.5,0.5], lb=lb, ub=ub,disp=3,full_output=True)

xhat,output = ipD(objFH.cost, objFH.gradient, hessian=None, x0=[0.5,0.5,0.5], lb=lb, ub=ub,disp=3,full_output=True)

from pygotools.optutils.consMani import addLBUBToInequality
G,h = addLBUBToInequality(lb,ub)
G = matrix(G)
h = matrix(h)
z = qpOut['z']

numpy.einsum('ji,ik->jk',G.T, G*z )
print mul(matrix(G),matrix(z)[:,matrix(0,(1,len(G[0])))])

numpy.einsum('ji,ik->jk',G.T, mul(matrix(G),matrix(z)[:,matrix(0,(1,G.size[1]))]))
from cvxopt import blas 
y = matrix(0.0,(G.size[1],1))
blas.gemv(Gs, matrix(1.0,(G.size[0],1)),y,'T')

C = numpy.zeros((4,4))

for i in range(3):
    C += numpy.outer(GT[:,i],G[i])
    
Beispiel #45
0
    def F(W): 
        """
        Custom solver for the system

        [  It  0   0    Xt'     0     At1' ...  Atk' ][ dwt  ]   [ rwt ]
        [  0   0   0    -d'     0      0   ...   0   ][ db   ]   [ rb  ]
        [  0   0   0    -I     -I      0   ...   0   ][ dv   ]   [ rv  ]
        [  Xt -d  -I  -Wl1^-2                        ][ dzl1 ]   [ rl1 ]
        [  0   0  -I         -Wl2^-2                 ][ dzl2 ] = [ rl2 ]
        [ At1  0   0                -W1^-2           ][ dz1  ]   [ r1  ] 
        [  |   |   |                       .         ][  |   ]   [  |  ]
        [ Atk  0   0                          -Wk^-2 ][ dzk  ]   [ rk  ]

        where

        It = [ I 0 ]  Xt = [ -D*X E ]  Ati = [ 0   -e_i' ]  
             [ 0 0 ]                         [ -Pi   0   ] 

        dwt = [ dw ]  rwt = [ rw ]
              [ dt ]        [ rt ].

        """

        # scalings and 'intermediate' vectors
        # db = inv(Wl1)^2 + inv(Wl2)^2
        db = W['di'][:m]**2 + W['di'][m:2*m]**2
        dbi = div(1.0,db)
        
        # dt = I - inv(Wl1)*Dbi*inv(Wl1)
        dt = 1.0 - mul(W['di'][:m]**2,dbi)
        dtsqrt = sqrt(dt)

        # lam = Dt*inv(Wl1)*d
        lam = mul(dt,mul(W['di'][:m],d))

        # lt = E'*inv(Wl1)*lam
        lt = matrix(0.0,(k,1))
        base.gemv(E, mul(W['di'][:m],lam), lt, trans = 'T')

        # Xs = sqrt(Dt)*inv(Wl1)*X
        tmp = mul(dtsqrt,W['di'][:m])
        Xs = spmatrix(tmp,range(m),range(m))*X

        # Es = D*sqrt(Dt)*inv(Wl1)*E
        Es = spmatrix(mul(d,tmp),range(m),range(m))*E

        # form Ab = I + sum((1/bi)^2*(Pi'*Pi + 4*(v'*v + 1)*Pi'*y*y'*Pi)) + Xs'*Xs
        #  and Bb = -sum((1/bi)^2*(4*ui*v'*v*Pi'*y*ei')) - Xs'*Es
        #  and D2 = Es'*Es + sum((1/bi)^2*(1+4*ui^2*(v'*v - 1))
        Ab = matrix(0.0,(n,n))
        Ab[::n+1] = 1.0
        base.syrk(Xs,Ab,trans = 'T', beta = 1.0)
        Bb = matrix(0.0,(n,k))
        Bb = -Xs.T*Es # inefficient!?
        D2 = spmatrix(0.0,range(k),range(k))
        base.syrk(Es,D2,trans = 'T', partial = True)
        d2 = +D2.V
        del D2
        py = matrix(0.0,(n,1))
        for i in range(k):
            binvsq = (1.0/W['beta'][i])**2
            Ab += binvsq*Pt[i]
            dvv = blas.dot(W['v'][i],W['v'][i])
            blas.gemv(P[i], W['v'][i][1:], py, trans = 'T', alpha = 1.0, beta = 0.0)
            blas.syrk(py, Ab, alpha = 4*binvsq*(dvv+1), beta = 1.0)
            Bb[:,i] -= 4*binvsq*W['v'][i][0]*dvv*py
            d2[i] += binvsq*(1+4*(W['v'][i][0]**2)*(dvv-1))
        
        d2i = div(1.0,d2)
        d2isqrt = sqrt(d2i)

        # compute a = alpha - lam'*inv(Wl1)*E*inv(D2)*E'*inv(Wl1)*lam
        alpha = blas.dot(lam,mul(W['di'][:m],d))
        tmp = matrix(0.0,(k,1))
        base.gemv(E,mul(W['di'][:m],lam), tmp, trans = 'T')
        tmp = mul(tmp, d2isqrt) #tmp = inv(D2)^(1/2)*E'*inv(Wl1)*lam
        a = alpha - blas.dot(tmp,tmp)

        # compute M12 = X'*D*inv(Wl1)*lam + Bb*inv(D2)*E'*inv(Wl1)*lam
        tmp = mul(tmp, d2isqrt)
        M12 = matrix(0.0,(n,1))
        blas.gemv(Bb,tmp,M12, alpha = 1.0)
        tmp = mul(d,mul(W['di'][:m],lam))
        blas.gemv(X,tmp,M12, trans = 'T', alpha = 1.0, beta = 1.0)

        # form and factor M
        sBb = Bb * spmatrix(d2isqrt,range(k), range(k)) 
        base.syrk(sBb, Ab, alpha = -1.0, beta = 1.0)
        M = matrix([[Ab, M12.T],[M12, a]])
        lapack.potrf(M)
        
        def f(x,y,z):
            
            # residuals
            rwt = x[:n+k]
            rb = x[n+k]
            rv = x[n+k+1:n+k+1+m]
            iw_rl1 = mul(W['di'][:m],z[:m])
            iw_rl2 = mul(W['di'][m:2*m],z[m:2*m])
            ri = [z[2*m+i*(n+1):2*m+(i+1)*(n+1)] for i in range(k)]
            
            # compute 'derived' residuals 
            # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1
            rbwt = +rwt
            for i in range(k):
                tmp = +ri[i]
                qscal(tmp,W['beta'][i],W['v'][i],inv=True)
                qscal(tmp,W['beta'][i],W['v'][i],inv=True)
                rbwt[n+i] -= tmp[0]
                blas.gemv(P[i], tmp[1:], rbwt, trans = 'T', alpha = -1.0, beta = 1.0)
            tmp = mul(W['di'][:m],iw_rl1)
            tmp2 = matrix(0.0,(k,1))
            base.gemv(E,tmp,tmp2,trans='T')
            rbwt[n:] += tmp2
            tmp = mul(d,tmp) # tmp = D*inv(Wl1)^2*rl1
            blas.gemv(X,tmp,rbwt,trans='T', alpha = -1.0, beta = 1.0)
            
            # rbb = rb - d'*inv(Wl1)^2*rl1
            rbb = rb - sum(tmp)

            # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1
            rbv = rv - mul(W['di'][m:2*m],iw_rl2) - mul(W['di'][:m],iw_rl1) 
            
            # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv 
            tmp = mul(W['di'][:m]**2, mul(dbi,rbv))
            rtt = +rbwt[n:] 
            base.gemv(E, tmp, rtt, trans = 'T', alpha = 1.0, beta = 1.0)
            rtw = +rbwt[:n]
            tmp = mul(d,tmp)
            blas.gemv(X, tmp, rtw, trans = 'T', alpha = -1.0, beta = 1.0)

            # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv
            rtb = rbb - sum(tmp)
            
            # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt]
            tmp = mul(d2i,rtt)
            tmp2 = matrix(0.0,(n,1))
            blas.gemv(Bb,tmp,tmp2)
            dwdb = matrix([rtw - tmp2,rtb + blas.dot(mul(d2i,lt),rtt)]) 
            lapack.potrs(M,dwdb)

            # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db)
            tmp2 = matrix(0.0,(k,1))
            blas.gemv(Bb, dwdb[:n], tmp2, trans='T')
            dt = mul(d2i, rtt - tmp2 + lt*dwdb[-1])

            # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db))
            dv = matrix(0.0,(m,1))
            blas.gemv(X,dwdb[:n],dv,alpha = -1.0)
            dv = mul(d,dv) - d*dwdb[-1]
            base.gemv(E, dt, dv, beta = 1.0)
            tmp = +dv  # tmp = E*dt - D*X*dw - d*db
            dv = mul(dbi, rbv + mul(W['di'][:m]**2,dv))

            # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1)
            wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1

            # compute wdz2 = - inv(Wl2)*(dv + rl2)
            wdz2 = - mul(W['di'][m:2*m],dv) - iw_rl2

            # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri)
            wdzi = []
            tmp = matrix(0.0,(n,1))
            for i in range(k):
                blas.gemv(P[i],dwdb[:n],tmp, alpha = -1.0, beta = 0.0) 
                tmp1 = matrix([-dt[i],tmp])
                blas.axpy(ri[i],tmp1,alpha = -1.0)
                qscal(tmp1,W['beta'][i],W['v'][i],inv=True)
                wdzi.append(tmp1)

            # solution
            x[:n] = dwdb[:n]
            x[n:n+k] = dt
            x[n+k] = dwdb[-1]
            x[n+k+1:] = dv
            z[:m] = wdz1 
            z[m:2*m] = wdz2
            for i in range(k):
                z[2*m+i*(n+1):2*m+(i+1)*(n+1)] = wdzi[i]

        return f
Beispiel #46
0
        def solve(x, y, z):
            """

            1. Solve for usx[0]:

               Asc'(Asc(usx[0]))
                   = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
                   = bx0 + Asc'( ( bsz0 + S * ( bsx[1] - bssz1) S ) 
                     ./ sqrtG)

               where bsx[1] = U^-1 * bx[1] * U^-T, bsz0 = U' * bz0 * U, 
               bsz1 = U' * bz1 * U, bssz1 = S^-1 * bsz1 * S^-1 

            2. Solve for usx[1]:

               usx[1] + S * usx[1] * S 
                   = S * ( As(usx[0]) + bsx[1] - bsz0 ) * S - bsz1 

               usx[1] 
                   = ( S * (As(usx[0]) + bsx[1] - bsz0) * S - bsz1) ./ Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 - bsz1 + S * bsx[1] * S ) . / Gamma
                   = -bsz0 + (S * As(usx[0]) * S) ./ Gamma
                     + (bsz0 + S * ( bsx[1] - bssz1 ) * S ) . / Gamma

               Unscale ux[1] = Uti * usx[1] * Uti'

            3. Compute usz0, usz1

               r0' * uz0 * r0 = r0^-1 * ( A(ux[0]) - ux[1] - bz0 ) * r0^-T
               r1' * uz1 * r1 = r1^-1 * ( -ux[1] - bz1 ) * r1^-T

            """

            # z0 := U' * z0 * U 
            #     = bsz0
            __cngrnc(U, z, trans = 'T')

            # z1 := Us' * bz1 * Us 
            #     = S^-1 * U' * bz1 * U * S^-1
            #     = S^-1 * bsz1 * S^-1
            __cngrnc(Us, z, trans = 'T', offsetx = msq)

            # x[1] := Uti' * x[1] * Uti 
            #       = bsx[1]
            __cngrnc(Uti, x[1], trans = 'T')
        
            # x[1] := x[1] - z[msq:] 
            #       = bsx[1] - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], alpha = -1.0, offsetx = msq)


            # x1 = (S * x[1] * S + z[:msq] ) ./ sqrtG
            #    = (S * ( bsx[1] - S^-1 * bsz1 * S^-1) * S + bsz0 ) ./ sqrtG
            #    = (S * bsx[1] * S - bsz1 + bsz0 ) ./ sqrtG
            # in packed storage
            blas.copy(x[1], x1)
            blas.tbmv(S, x1, n = msq, k = 0, ldA = 1)
            blas.axpy(z, x1, n = msq)
            blas.tbsv(sqrtG, x1, n = msq, k = 0, ldA = 1)
            misc.pack2(x1, {'l': 0, 'q': [], 's': [m]})

            # x[0] := x[0] + Asc'*x1 
            #       = bx0 + Asc'( ( bsz0 - bsz1 + S * bsx[1] * S ) ./ sqrtG)
            #       = bx0 + As'( ( bz0 - bz1 + S * bx[1] * S ) ./ Gamma )
            blas.gemv(Asc, x1, x[0], m = mpckd, trans = 'T', beta = 1.0)

            # x[0] := H^-1 * x[0]
            #       = ux[0]
            lapack.potrs(H, x[0])


            # x1 = Asc(x[0]) .* sqrtG  (unpacked)
            #    = As(x[0])  
            blas.gemv(Asc, x[0], tmp, m = mpckd)
            misc.unpack(tmp, x1, {'l': 0, 'q': [], 's': [m]})
            blas.tbmv(sqrtG, x1, n = msq, k = 0, ldA = 1)


            # usx[1] = (x1 + (x[1] - z[:msq])) ./ sqrtG**2 
            #        = (As(ux[0]) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1) 
            #           ./ Gamma

            # x[1] := x[1] - z[:msq] 
            #       = bsx[1] - bsz0 - S^-1 * bsz1 * S^-1
            blas.axpy(z, x[1], -1.0, n = msq)

            # x[1] := x[1] + x1
            #       = As(ux) + bsx[1] - bsz0 - S^-1 * bsz1 * S^-1 
            blas.axpy(x1, x[1])

            # x[1] := x[1] / Gammma
            #       = (As(ux) + bsx[1] - bsz0 + S^-1 * bsz1 * S^-1 ) / Gamma
            #       = S^-1 * usx[1] * S^-1
            blas.tbsv(Gamma, x[1], n = msq, k = 0, ldA = 1)
            

            # z[msq:] := r1' * U * (-z[msq:] - x[1]) * U * r1
            #         := -r1' * U * S^-1 * (bsz1 + ux[1]) * S^-1 *  U * r1
            #         := -r1' * uz1 * r1
            blas.axpy(x[1], z, n = msq, offsety = msq)
            blas.scal(-1.0, z, offset = msq)
            __cngrnc(U, z, offsetx = msq)
            __cngrnc(W['r'][1], z, trans = 'T', offsetx = msq)

            # x[1] :=  S * x[1] * S
            #       =  usx1 
            blas.tbmv(S, x[1], n = msq, k = 0, ldA = 1)

            # z[:msq] = r0' * U' * ( x1 - x[1] - z[:msq] ) * U * r0
            #         = r0' * U' * ( As(ux) - usx1 - bsz0 ) * U * r0
            #         = r0' * U' *  usz0 * U * r0
            #         = r0' * uz0 * r0
            blas.axpy(x1, z, -1.0, n = msq)
            blas.scal(-1.0, z, n = msq)
            blas.axpy(x[1], z, -1.0, n = msq)
            __cngrnc(U, z)
            __cngrnc(W['r'][0], z, trans = 'T')

            # x[1] := Uti * x[1] * Uti'
            #       = ux[1]
            __cngrnc(Uti, x[1])
Beispiel #47
0
def _reconEngine(mmTheta_, vvSig_, iK):
    """
    This is the engine of the reconstruction.

    Basis pursuit problem:

       minimize    ||A*x - y||_2^2 + k * ||x||_1

    where:
         1. A - Theta matrix
            A = B * C:
                   B - observation matirx
                   C - dictionary matrix

         2. y - observed signal
         3. x - vector with coefficients we are looking for
         4. k - noise wage coefficient

    ----------------------------------------------------------------------

    The engine of this reconstruction is based on the fact that a problem:

        minimize    ||A*x - y||_2^2 + ||x||_1

    can be translated to:

        minimize    x'*A'*A*x - 2.0*y'*A*x + 1'*u
        subject to  -u <= x <= u

    variables x (n),  u (n).

    ----------------------------------------------------------------------

    Args:
        mTheta_ (cvxopt matrix):  Theta matrix
        vvSig_ (cvxopt vector):   vector with an observed signal
        iK (float):               k parameter

    Returns:
        vvCoef (cvxopt vector):   vector with found coefficients

    NOTE: 'cvxopt vector' is nothing but a 'cvxopt matrix' of a size (N x 1)
    """

    # --------------------------------------------------------------------
    # Get the input Theta matrix and make it global
    global mmTh
    mmTh = mmTheta_

    # --------------------------------------------------------------------
    # Get the size of the Theta matrix
    global iR  # The number of rows
    global iC  # The number of columns
    iR, iC = mmTh.size

    # --------------------------------------------------------------------
    # Silence the outoput from the cvxopt
    solvers.options["show_progress"] = False

    # --------------------------------------------------------------------

    # Q = -2.0 * A' * y
    vvQ = matrix(float(iK), (2 * iC, 1))
    blas.gemv(mmTh, vvSig_, vvQ, alpha=-2.0, trans="T")

    # Run the solver
    mmH = matrix(0.0, (2 * iC, 1))
    vvCoef = solvers.coneqp(P, vvQ, G, mmH, kktsolver=Fkkt)["x"][:iC]

    # --------------------------------------------------------------------
    # Return the vecto with coefficients
    return vvCoef
Beispiel #48
0
def softmargin(X,
               d,
               gamma,
               kernel='linear',
               sigma=1.0,
               degree=1,
               theta=1.0,
               Q=None):
    """
    Solves the 'soft-margin' SVM problem

        maximize    -(1/2)*z'*Q*z + d'*z
        subject to  0 <= diag(d)*z <= gamma*ones
                    sum(z) = 0

    (with variables z), and its dual problem

        minimize    (1/2)*y'*Q^{-1}*y + gamma*sum(v)
        subject to  diag(d)*(y + b*ones) + v >= 1
                    v >= 0

    (with variables y, v, b).

    Q is given by Q_ij = K(xi, xj) where K is a kernel function and xi is
    the ith row of X (xi' = X[i,:]).  If Q is singular, we replace Q^{-1}
    in the dual with its pseudo-inverse and add a constraint y in Range(Q).
    We can also use make a change of variables y = Q*u to obtain

        minimize    (1/2)*u'*Q*u + gamma*sum(v)
        subject to  diag(d)*(Q*u + b*ones) + v >= 1
                    v >= 0

    For the linear kernel (Q = X*X'), a change of variables w = X'*u allows
    us to write this in the more common form

        minimize    (1/2)*w'*w + gamma*sum(v)
        subject to  diag(d)*(X*w + b*ones) + v >= 1
                    v >= 0.


    Input arguments.

        X is an N x n matrix.

        d is an N-vector with elements -1 or 1; d[i] is the label of
        row X[i,:].

        gamma is a positive parameter.

        kernel is a string with values 'linear', 'rfb', 'poly', or 'tanh'.
        'linear': k(u,v) = u'*v/sigma.
        'rbf':    k(u,v) = exp(-||u - v||^2 / (2*sigma)).
        'poly':   k(u,v) = (u'*v/sigma)**degree.
        'tanh':   k(u,v) = tanh(u'*v/sigma - theta).

        sigma and theta are positive numbers.

        degree is a positive integer.


    Output.

        Returns a dictionary with the keys:

        'classifier'
           a Python function object that takes an M x n matrix with
           test vectors as rows and returns a vector with labels

        'z'
           a sparse m-vector

        'cputime'
           a tuple (Ttot, Tqp, Tker) where Ttot is the total
           CPU time, Tqp is the CPU time spent solving the QP, and
           Tker is the CPU time spent computing the kernel matrix

        'iterations'
           the number of interior-point iteations

        'misclassified'
           a tuple (L1, L2) where L1 is a list of indices of
           misclassified training vectors from class 1, and L2 is a
           list of indices of misclassified training vectors from
           class 2
    """

    Tstart = cputime()

    if verbose: solvers.options['show_progress'] = True
    else: solvers.options['show_progress'] = False
    N, n = X.size

    if Q is None:
        Q, a = kernel_matrix(X,
                             kernel,
                             sigma=sigma,
                             degree=degree,
                             theta=theta)
    else:
        if not (Q.size[0] == N and Q.size[1] == N):
            raise ValueError("invalid kernel matrix dimensions")
        elif not type(Q) is cvxopt.base.matrix:
            raise ValueError("invalid kernel matrix type")
        elif verbose:
            print("using precomputed kernel matrix ..")
        if kernel == 'rbf':
            Ad = spmatrix(0.0, range(N), range(N))
            base.syrk(X, V, partial=True)
            a = Ad.V
            del Ad

    Tkernel = cputime(Tstart)

    # build qp
    Tqp = cputime()
    q = matrix(-d, tc='d')
    # Inequality constraints  0 <= diag(d)*z <= gamma*ones
    G = spmatrix([], [], [], size=(2 * N, N))
    G[::2 * N + 1], G[N::2 * N + 1] = d, -d
    h = matrix(0.0, (2 * N, 1))

    if weights is 'proportional':
        dlist = list(d)
        C1 = 0.5 * N * gamma / dlist.count(1)
        C2 = 0.5 * N * gamma / dlist.count(-1)
        gvec = matrix([C1 if w == 1 else C2 for w in dlist], (N, 1))
        del dlist
        h[:N] = gvec
    elif weights is 'equal':
        h[:N] = gamma
    else:
        raise ValueError("invalid weight type")

    # solve qp
    sol = solvers.qp(Q, q, G, h, matrix(1.0, (1, N)), matrix(0.0))
    Tqp = cputime(Tqp)
    if verbose: print("utime = %f, stime = %f." % Tqp)

    # extract solution
    z, b, v = sol['x'], sol['y'][0], sol['z'][:N]

    # extract nonzero support vectors
    nrmz = max(abs(z))
    sv = [k for k in range(N) if abs(z[k]) > Tsv * nrmz]
    N, X, z = len(sv), X[sv, :], z[sv]
    zs = spmatrix(z, sv, [0 for i in range(N)], (len(d), 1))
    if verbose: print("%d support vectors." % N)

    # find misclassified training vectors
    err1 = [i for i in range(Q.size[0]) if (v[i] > 1 and d[i] == 1)]
    err2 = [i for i in range(Q.size[0]) if (v[i] > 1 and d[i] == -1)]
    if verbose:
        e1, n1 = len(err1), list(d).count(1)
        e2, n2 = len(err2), list(d).count(-1)
        print("class 1: %i/%i = %.1f%% misclassified." %
              (e1, n1, 100. * e1 / n1))
        print("class 2: %i/%i = %.1f%% misclassified." %
              (e2, n2, 100. * e2 / n2))
        del e1, e2, n1, n2

    # create classifier function object
    if kernel == 'linear':

        # w = X'*z / sigma
        w = matrix(0.0, (n, 1))
        blas.gemv(X, z, w, trans='T', alpha=1.0 / sigma)

        def classifier(Y, soft=False):
            M = Y.size[0]
            x = matrix(b, (M, 1))
            blas.gemv(Y, w, x, beta=1.0)
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'rbf':

        def classifier(Y, soft=False):
            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(0.0, (M, N))
            blas.gemm(Y, X, K, transB='T', alpha=1.0 / sigma)

            # c[i] = ||Yi||^2 / sigma
            ones = matrix(1.0, (max([M, N, n]), 1))
            c = Y**2 * ones[:n]
            blas.scal(1.0 / sigma, c)

            # Kij := Kij - 0.5 * (ci + aj)
            #      = || yi - xj ||^2 / (2*sigma)
            blas.ger(c, ones, K, alpha=-0.5)
            blas.ger(ones, a[sv], K, alpha=-0.5)
            x = exp(K) * z + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'tanh':

        def classifier(Y, soft=False):
            M = Y.size[0]

            # K = Y*X' / sigma - theta
            K = matrix(theta, (M, N))
            blas.gemm(Y, X, K, transB='T', alpha=1.0 / sigma, beta=-1.0)

            K = exp(K)
            x = div(K - K**-1, K + K**-1) * z + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    elif kernel == 'poly':

        def classifier(Y, soft=False):
            M = Y.size[0]

            # K = Y*X' / sigma
            K = matrix(0.0, (M, N))
            blas.gemm(Y, X, K, transB='T', alpha=1.0 / sigma)

            x = K**degree * z + b
            if soft: return x
            else: return matrix([2 * (xk > 0.0) - 1 for xk in x])

    Ttotal = cputime(Tstart)

    return {
        'classifier': classifier,
        'cputime': (sum(Ttotal), sum(Tqp), sum(Tkernel)),
        'iterations': sol['iterations'],
        'z': zs,
        'misclassified': (err1, err2)
    }
y = mul(1.0 + 0.5 * sin(11 * ts), sin(30 * sin(5 * ts)))

# Basis pursuit problem
#
#     minimize    ||A*x - y||_2^2 + ||x||_1
#
#     minimize    x'*A'*A*x - 2.0*y'*A*x + 1'*u
#     subject to  -u <= x <= u
#
# Variables x (n),  u (n).

m, n = A.size
r = matrix(0.0, (m, 1))

q = matrix(1.0, (2 * n, 1))
blas.gemv(A, y, q, alpha=-2.0, trans='T')


def P(u, v, alpha=1.0, beta=0.0):
    """
    Function and gradient evaluation of

        v := alpha * 2*A'*A * u + beta * v
    """

    blas.gemv(A, u, r)
    blas.gemv(A, r, v, alpha=2.0 * alpha, beta=beta, trans='T')


def G(u, v, alpha=1.0, beta=0.0, trans='N'):
    """
Beispiel #50
0
        def f(x, y, z):

            # residuals
            rwt = x[:n + k]
            rb = x[n + k]
            rv = x[n + k + 1:n + k + 1 + m]
            iw_rl1 = mul(W['di'][:m], z[:m])
            iw_rl2 = mul(W['di'][m:2 * m], z[m:2 * m])
            ri = [
                z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)]
                for i in range(k)
            ]

            # compute 'derived' residuals
            # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1
            rbwt = +rwt
            for i in range(k):
                tmp = +ri[i]
                qscal(tmp, W['beta'][i], W['v'][i], inv=True)
                qscal(tmp, W['beta'][i], W['v'][i], inv=True)
                rbwt[n + i] -= tmp[0]
                blas.gemv(P[i], tmp[1:], rbwt, trans='T', alpha=-1.0, beta=1.0)
            tmp = mul(W['di'][:m], iw_rl1)
            tmp2 = matrix(0.0, (k, 1))
            base.gemv(E, tmp, tmp2, trans='T')
            rbwt[n:] += tmp2
            tmp = mul(d, tmp)  # tmp = D*inv(Wl1)^2*rl1
            blas.gemv(X, tmp, rbwt, trans='T', alpha=-1.0, beta=1.0)

            # rbb = rb - d'*inv(Wl1)^2*rl1
            rbb = rb - sum(tmp)

            # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1
            rbv = rv - mul(W['di'][m:2 * m], iw_rl2) - mul(W['di'][:m], iw_rl1)

            # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv
            tmp = mul(W['di'][:m]**2, mul(dbi, rbv))
            rtt = +rbwt[n:]
            base.gemv(E, tmp, rtt, trans='T', alpha=1.0, beta=1.0)
            rtw = +rbwt[:n]
            tmp = mul(d, tmp)
            blas.gemv(X, tmp, rtw, trans='T', alpha=-1.0, beta=1.0)

            # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv
            rtb = rbb - sum(tmp)

            # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt]
            tmp = mul(d2i, rtt)
            tmp2 = matrix(0.0, (n, 1))
            blas.gemv(Bb, tmp, tmp2)
            dwdb = matrix([rtw - tmp2, rtb + blas.dot(mul(d2i, lt), rtt)])
            lapack.potrs(M, dwdb)

            # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db)
            tmp2 = matrix(0.0, (k, 1))
            blas.gemv(Bb, dwdb[:n], tmp2, trans='T')
            dt = mul(d2i, rtt - tmp2 + lt * dwdb[-1])

            # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db))
            dv = matrix(0.0, (m, 1))
            blas.gemv(X, dwdb[:n], dv, alpha=-1.0)
            dv = mul(d, dv) - d * dwdb[-1]
            base.gemv(E, dt, dv, beta=1.0)
            tmp = +dv  # tmp = E*dt - D*X*dw - d*db
            dv = mul(dbi, rbv + mul(W['di'][:m]**2, dv))

            # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1)
            wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1

            # compute wdz2 = - inv(Wl2)*(dv + rl2)
            wdz2 = -mul(W['di'][m:2 * m], dv) - iw_rl2

            # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri)
            wdzi = []
            tmp = matrix(0.0, (n, 1))
            for i in range(k):
                blas.gemv(P[i], dwdb[:n], tmp, alpha=-1.0, beta=0.0)
                tmp1 = matrix([-dt[i], tmp])
                blas.axpy(ri[i], tmp1, alpha=-1.0)
                qscal(tmp1, W['beta'][i], W['v'][i], inv=True)
                wdzi.append(tmp1)

            # solution
            x[:n] = dwdb[:n]
            x[n:n + k] = dt
            x[n + k] = dwdb[-1]
            x[n + k + 1:] = dv
            z[:m] = wdz1
            z[m:2 * m] = wdz2
            for i in range(k):
                z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] = wdzi[i]