Пример #1
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:] ) 
Пример #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:])
Пример #3
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:])
Пример #4
0
        def f(x, y, z):
            """
            Solve
                          -diag(z)                           = bx
                -diag(x) - inv(rti*rti') * z * inv(rti*rti') = bs

            On entry, x and z contain bx and bs.  
            On exit, they contain the solution, with z scaled
            (inv(rti)'*z*inv(rti) is returned instead of z).

            We first solve 

                ((rti*rti') .* (rti*rti')) * x = bx - diag(t*bs*t) 

            and take z  = -rti' * (diag(x) + bs) * rti.
            """

            # tbst := t * zs * t = t * bs * t
            tbst = matrix(z, (n, n))
            cngrnc(t, tbst)

            # x := x - diag(tbst) = bx - diag(rti*rti' * bs * rti*rti')
            x -= tbst[::n + 1]

            # x := (t.*t)^{-1} * x = (t.*t)^{-1} * (bx - diag(t*bs*t))
            lapack.potrs(tsq, x)

            # z := z + diag(x) = bs + diag(x)
            z[::n + 1] += x

            # z := -rti' * z * rti = -rti' * (diag(x) + bs) * rti
            cngrnc(rti, z, alpha=-1.0)
Пример #5
0
        def f(x, y, z):

            # z := - W**-T * z 
            z[:n] = -div( z[:n], d1 )
            z[n:2*n] = -div( z[n:2*n], d2 )
            z[2*n:] -= 2.0*v*( v[0]*z[2*n] - blas.dot(v[1:], z[2*n+1:]) ) 
            z[2*n+1:] *= -1.0
            z[2*n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2*n], d2) + As.T * z[-(m+1):]
            x[n:] += div(z[:n], d1) + div(z[n:2*n], d2) 

            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]
            
            x[:n] -= mul( div(d1**2 - d2**2, d1**2 + d2**2), x[n:]) 
            lapack.potrs(S, x)
            
            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]
             
            x[n:] += mul( d1**-2 - d2**-2, x[:n])
            x[n:] = div( x[n:], d1**-2 + d2**-2)

            # z := z + W^-T * G*x 
            z[:n] += div( x[:n] - x[n:2*n], d1) 
            z[n:2*n] += div( -x[:n] - x[n:2*n], d2) 
            z[2*n:] += As*x[:n]
Пример #6
0
 def f(x, y, z):
     uz = -d * (x + P * z)
     #uz  =   matrix(numpy.linalg.solve(KKT1, uz))  # slow version
     #lapack.gesv(KKT1,uz)  #  JZ: gesv have cond issue
     lapack.potrs(KKT1, uz)
     x[:] = matrix(-z - d * uz)
     blas.copy(uz, z)
Пример #7
0
        def f(x, y, z):

            # z := - W**-T * z
            z[:n] = -div(z[:n], d1)
            z[n:2 * n] = -div(z[n:2 * n], d2)
            z[2 * n:] -= 2.0 * v * (v[0] * z[2 * n] -
                                    blas.dot(v[1:], z[2 * n + 1:]))
            z[2 * n + 1:] *= -1.0
            z[2 * n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2 * n], d2) + As.T * z[-(m + 1):]
            x[n:] += div(z[:n], d1) + div(z[n:2 * n], d2)

            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]

            x[:n] -= mul(div(d1**2 - d2**2, d1**2 + d2**2), x[n:])
            lapack.potrs(S, x)

            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]

            x[n:] += mul(d1**-2 - d2**-2, x[:n])
            x[n:] = div(x[n:], d1**-2 + d2**-2)

            # z := z + W^-T * G*x
            z[:n] += div(x[:n] - x[n:2 * n], d1)
            z[n:2 * n] += div(-x[:n] - x[n:2 * n], d2)
            z[2 * n:] += As * x[:n]
Пример #8
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:])
Пример #9
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])
Пример #10
0
        def f(x, y, z):
            """
            On entry, x contains bx, y is empty, and z contains bz stored
            in column major order.
            On exit, they contain the solution, with z scaled
            (vec(r'*z*r) is returned instead of z).

            We first solve

               ((rti*rti') .* (rti*rti')) * x = bx - diag(t*bz*t)

            and take z = - rti' * (diag(x) + bz) * rti.
            """

            # tbst := t * bz * t
            tbst = +z
            cngrnc(t, tbst)

            # x := x - diag(tbst) = bx - diag(rti*rti' * bz * rti*rti')
            x -= tbst[::n+1]

            # x := (t.*t)^{-1} * x = (t.*t)^{-1} * (bx - diag(t*bz*t))
            lapack.potrs(tsq, x)

            # z := z + diag(x) = bz + diag(x)
            z[::n+1] += x

            # z := -vec(rti' * z * rti)
            #    = -vec(rti' * (diag(x) + bz) * rti
            cngrnc(rti, z, alpha = -1.0)
Пример #11
0
        def solve(x, y, z):

            # Solve
            #
            #     [ P           GG'*W^{-1} ]   [ ux   ]   [ bx        ]
            #     [ W^{-T}*GG   -I         ]   [ W*uz ]   [ W^{-T}*bz ]
            #
            # and return ux, uy, W*uz.
            #
            # On entry, x, y, z contain bx, by, bz.  On exit, they contain
            # the solution ux, uy, W*uz.
            #
            # z=W^-T z
            scale(z, W, trans = 'T', inverse = 'I')

            # x=x+Gs^T z
#            blas.gemv(Gs, z, x, beta = 1.0, trans = 'T', m = n)          
            WGGW_C.Gs_mv(Gs, z, x, 1,1, n)
            
            #solve Kx
            lapack.potrs(K, x, n = n, offsetA = 0, offsetB = 0)

            # z=z-Gs^T x
            #blas.gemv(Gs, x, z, alpha = 1.0, beta = -1.0, m = n)
            WGGW_C.Gs_mv(Gs, x, z, -1,0, n)
Пример #12
0
        def f(x, y, z):
            """
            Solve
                          -diag(z)                           = bx
                -diag(x) - inv(rti*rti') * z * inv(rti*rti') = bs

            On entry, x and z contain bx and bs.  
            On exit, they contain the solution, with z scaled
            (inv(rti)'*z*inv(rti) is returned instead of z).

            We first solve 

                ((rti*rti') .* (rti*rti')) * x = bx - diag(t*bs*t) 

            and take z  = -rti' * (diag(x) + bs) * rti.
            """
            # tbst := t * zs * t = t * bs * t
            tbst = matrix(z, (n,n))
            cngrnc(t, tbst) 

            # x := x - diag(tbst) = bx - diag(rti*rti' * bs * rti*rti')
            x -= tbst[::n+1]

            # x := (t.*t)^{-1} * x = (t.*t)^{-1} * (bx - diag(t*bs*t))
            lapack.potrs(tsq, x)

            # z := z + diag(x) = bs + diag(x)
            z[::n+1] += x

            # z := -rti' * z * rti = -rti' * (diag(x) + bs) * rti 
            cngrnc(rti, z, alpha = -1.0)
Пример #13
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:])
Пример #14
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])
Пример #15
0
        def f(x, y, z):

            minor = 0
            if not helpers.sp_minor_empty():
                minor = helpers.sp_minor_top()
            else:
                global loopf
                loopf += 1
                minor = loopf
            helpers.sp_create("00-f", minor)

            # z := - W**-T * z
            z[:n] = -div(z[:n], d1)
            z[n:2 * n] = -div(z[n:2 * n], d2)

            z[2 * n:] -= 2.0 * v * (v[0] * z[2 * n] -
                                    blas.dot(v[1:], z[2 * n + 1:]))
            z[2 * n + 1:] *= -1.0
            z[2 * n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2 * n], d2) + As.T * z[-(m + 1):]
            x[n:] += div(z[:n], d1) + div(z[n:2 * n], d2)
            helpers.sp_create("15-f", minor)

            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]

            x[:n] -= mul(div(d1**2 - d2**2, d1**2 + d2**2), x[n:])
            helpers.sp_create("25-f", minor)

            lapack.potrs(S, x)
            helpers.sp_create("30-f", minor)

            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]

            x[n:] += mul(d1**-2 - d2**-2, x[:n])
            helpers.sp_create("35-f", minor)

            x[n:] = div(x[n:], d1**-2 + d2**-2)
            helpers.sp_create("40-f", minor)

            # z := z + W^-T * G*x
            z[:n] += div(x[:n] - x[n:2 * n], d1)
            helpers.sp_create("44-f", minor)

            z[n:2 * n] += div(-x[:n] - x[n:2 * n], d2)
            helpers.sp_create("48-f", minor)

            z[2 * n:] += As * x[:n]
            helpers.sp_create("50-f", minor)
Пример #16
0
def lapack_potrs(a, b):
    """
    Inverse using LaPaCK potrs (hermitian) algorithm.

    :param a:
    :param b:
    :return:
    """
    b_her = matrix(b)
    lapack.potrs(matrix(a), b_her)
    return b_her
Пример #17
0
        def f(x, y, z):
            x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) 
                + mul( .5*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

            u = P*x[:n]
            x[n:] =  div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + 
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )

            z[:m] = div(u-x[n:]-z[:m], d1)
            z[m:] = div(-u-x[n:]-z[m:], d2)
Пример #18
0
        def f(x, y, z):

            minor = 0
            if not helpers.sp_minor_empty():
                minor = helpers.sp_minor_top()
            else:
                global loopf
                loopf += 1
                minor = loopf
            helpers.sp_create("00-f", minor)

            # z := - W**-T * z 
            z[:n] = -div( z[:n], d1 )
            z[n:2*n] = -div( z[n:2*n], d2 )

            z[2*n:] -= 2.0*v*( v[0]*z[2*n] - blas.dot(v[1:], z[2*n+1:]) ) 
            z[2*n+1:] *= -1.0
            z[2*n:] /= beta

            # x := x - G' * W**-1 * z
            x[:n] -= div(z[:n], d1) - div(z[n:2*n], d2) + As.T * z[-(m+1):]
            x[n:] += div(z[:n], d1) + div(z[n:2*n], d2) 
            helpers.sp_create("15-f", minor)
  
            # Solve for x[:n]:
            #
            #    S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:]
            
            x[:n] -= mul( div(d1**2 - d2**2, d1**2 + d2**2), x[n:]) 
            helpers.sp_create("25-f", minor)

            lapack.potrs(S, x)
            helpers.sp_create("30-f", minor)
            
            # Solve for x[n:]:
            #
            #    (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n]
             
            x[n:] += mul( d1**-2 - d2**-2, x[:n])
            helpers.sp_create("35-f", minor)

            x[n:] = div( x[n:], d1**-2 + d2**-2)
            helpers.sp_create("40-f", minor)

            # z := z + W^-T * G*x 
            z[:n] += div( x[:n] - x[n:2*n], d1) 
            helpers.sp_create("44-f", minor)

            z[n:2*n] += div( -x[:n] - x[n:2*n], d2) 
            helpers.sp_create("48-f", minor)

            z[2*n:] += As*x[:n]
            helpers.sp_create("50-f", minor)
Пример #19
0
        def f(x, y, z):

            x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) 
                + mul( .5*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

            u = P*x[:n]
            x[n:] =  div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + 
                mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )

            z[:m] = div(u-x[n:]-z[:m], d1)
            z[m:] = div(-u-x[n:]-z[m:], d2)
Пример #20
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])
Пример #21
0
        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])
Пример #22
0
            def f(x, y, z):

                # z := mat(z)
                #    = mat(bz)
                z.size = N, m

                # x := x + D .* z
                #    = bx + mat(bz) ./ d.^2
                x += mul(D, z)

                # y := y - sum_k (Q + Dk)^-1 * X[:,k]
                #    = by - sum_k (Q + Dk)^-1 * (bxk + Dk * bzk)
                for k in range(m):
                    blas.symv(H[k], x[:, k], y, alpha=-1.0, beta=1.0)

                # y := H^-1 * y
                #    = -uy
                lapack.potrs(S, y)

                # x[:,k] := H[k] * (x[:,k] + y)
                #         = (Q + Dk)^-1 * (bxk + bzk ./ d.^2 + y)
                #         = ux[:,k]
                w = matrix(0.0, (N, 1))
                for k in range(m):

                    # x[:,k] := x[:,k] + y
                    blas.axpy(y, x, offsety=N * k, n=N)

                    # w := H[k] * x[:,k]
                    #    = (Q + Dk)^-1 * (bxk + bzk ./ d.^2 + y)
                    blas.symv(H[k], x, w, offsetx=N * k)

                    # x[:,k] := w
                    #         = ux[:,k]
                    blas.copy(w, x, offsety=N * k)

                # y := -y
                #    = uy
                blas.scal(-1.0, y)

                # z := (x - z) ./ d
                blas.axpy(x, z, -1.0)
                blas.tbsv(W['d'], z, n=m * N, k=0, ldA=1)
                blas.scal(-1.0, z)
                z.size = N * m, 1
Пример #23
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:]) ).

            x[:n] += P.T * ( mul( div(d1-d2, d1+d2), x[n:]) + 
                mul( 2*D, z[:m]-z[m:] ) )
            lapack.potrs(A, x)

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

            u = P*x[:n]
            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:])
Пример #24
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:]) ).

            x[:n] += P.T * (mul(div(d1 - d2, d1 + d2), x[n:]) +
                            mul(2 * D, z[:m] - z[m:]))
            lapack.potrs(A, x)

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

            u = P * x[:n]
            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:])
Пример #25
0
    def fsolve(x, y, z):
        """
        Solves the system of equations

            [ 0  G'*W^{-1} ] [ ux ] = [ bx ]
            [ G  -W'       ] [ uz ]   [ bz ]
        
        """
        #  Compute bx := bx + G'*W^{-1}*W^{-T}*bz
        v = matrix(0., (N, 1))
        for i in range(N):
            blas.symv(z, rr, v, ldA=N, offsetA=1, n=N, offsetx=N * i)
            x[i] += blas.dot(rr, v, n=N, offsetx=N * i)
        blas.symv(z, q, v, ldA=N, offsetA=1, n=N)
        x[N] += blas.dot(q, v) + z[0] * W['di'][0]**2
        #  Solve G'*W^{-1}*W^{-T}*G*ux = bx
        lapack.potrs(H, x)

        # Compute bz := -W^{-T}*(bz-G*ux)
        # z -= G*x
        z[1::N + 1] -= x[:-1]
        z -= x[-1]
        # Apply scaling
        z[0] *= -W['di'][0]
        blas.scal(0.5, z, n=N, offset=1, inc=N + 1)
        tmp = +r
        blas.trmm(z, tmp, ldA=N, offsetA=1, n=N, m=N)
        blas.syr2k(r,
                   tmp,
                   z,
                   trans='T',
                   offsetC=1,
                   ldC=N,
                   n=N,
                   k=N,
                   alpha=-1.0)
Пример #26
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:])
Пример #27
0
def F(x=None, z=None):
    if x is None:  
        return m, matrix([ 1.0, 0.0, 1.0, 0.0, 0.0 ])

    # Factor A as A = L*L'.  Compute inverse B = A^-1.
    A = matrix( [x[0], x[1], x[1], x[2]], (2,2))
    L = +A
    try: lapack.potrf(L)
    except: return None
    B = +L
    lapack.potri(B)
    B[0,1] = B[1,0]

    # f0 = -log det A    
    f = matrix(0.0, (m+1,1))
    f[0] = -2.0 * (log(L[0,0]) + log(L[1,1]))

    # fk = xk'*A*xk - 2*xk'*b + b*A^-1*b - 1 
    #    = (xk - c)' * A * (xk - c) - 1  where c = A^-1*b  
    c = x[3:]
    lapack.potrs(L, c)  
    for k in range(m):
        f[k+1] = (X[k,:].T - c).T * A * (X[k,:].T - c) - 1.0 

    # gradf0 = (-A^-1, 0) = (-B, 0)
    Df = matrix(0.0, (m+1,5))
    Df[0,0], Df[0,1], Df[0,2] = -B[0,0], -2.0*B[1,0], -B[1,1]

    # gradfk = (xk*xk' - A^-1*b*b'*A^-1,  2*(-xk + A^-1*b))
    #        = (xk*xk' - c*c', 2*(-xk+c))
    Df[1:,0] = X[:m,0]**2 - c[0]**2
    Df[1:,1] = 2.0 * (mul(X[:m,0], X[:m,1]) - c[0]*c[1])
    Df[1:,2] = X[:m,1]**2 - c[1]**2
    Df[1:,3] = 2.0 * (-X[:m,0] + c[0])
    Df[1:,4] = 2.0 * (-X[:m,1] + c[1])

    if z is None: return f, Df
    
    # hessf0(Y, y) = (A^-1*Y*A^-1, 0) = (B*YB, 0)
    H0 = matrix(0.0, (5,5))
    H0[0,0] = B[0,0]**2
    H0[1,0] = 2.0 * B[0,0] * B[1,0]
    H0[2,0] = B[1,0]**2
    H0[1,1] = 2.0 * ( B[0,0] * B[1,1] + B[1,0]**2 )
    H0[2,1] = 2.0 * B[1,0] * B[1,1]
    H0[2,2] = B[1,1]**2
 
    # hessfi(Y, y) 
    #     = ( A^-1*Y*A^-1*b*b'*A^-1 + A^-1*b*b'*A^-1*Y*A^-1 
    #             - A^-1*y*b'*A^-1 - A^-1*b*y'*A^-1, 
    #         -2*A^-1*Y*A^-1*b + 2*A^-1*y ) 
    #     = ( B*Y*c*c' + c*c'*Y*B - B*y*c' - c*y'*B,  -2*B*Y*c + 2*B*y )
    #     = ( B*(Y*c-y)*c' + c*(Y*c-y)'*B, -2*B*(Y*c - y) ) 
    H1 = matrix(0.0, (5,5))
    H1[0,0] = 2.0 * c[0]**2 * B[0,0] 
    H1[1,0] = 2.0 * ( c[0] * c[1] * B[0,0] + c[0]**2 * B[1,0] )
    H1[2,0] = 2.0 * c[0] * c[1] * B[1,0] 
    H1[3:,0] = -2.0 * c[0] * B[:,0] 
    H1[1,1] = 2.0 * c[0]**2 * B[1,1] + 4.0 * c[0]*c[1]*B[1,0]  + \
              2.0 * c[1]**2 + B[0,0]
    H1[2,1] = 2.0 * (c[1]**2 * B[1,0] + c[0]*c[1]*B[1,1])
    H1[3:,1] = -2.0 * B * c[[1,0]]
    H1[2,2] = 2.0 * c[1]**2 * B[1,1]
    H1[3:,2] = -2.0 * c[1] * B[:,1] 
    H1[3:,3:] = 2*B

    return f, Df, z[0]*H0 + sum(z[1:])*H1
Пример #28
0
    return f, Df, z[0]*H0 + sum(z[1:])*H1
    
sol = solvers.cp(F)
A = matrix( sol['x'][[0, 1, 1, 2]], (2,2)) 
b = sol['x'][3:]

if pylab_installed:
    pylab.figure(1, facecolor='w')
    pylab.plot(X[:,0], X[:,1], 'ko', X[:,0], X[:,1], '-k')
    
    # Ellipsoid in the form { x | || L' * (x-c) ||_2 <= 1 }
    L = +A
    lapack.potrf(L)
    c = +b
    lapack.potrs(L, c)    
    
    # 1000 points on the unit circle
    nopts = 1000
    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
    circle = matrix(0.0, (2,nopts))
    circle[0,:], circle[1,:] = cos(angles), sin(angles)
    
    # ellipse = L^-T * circle + c
    blas.trsm(L, circle, transA='T')
    ellipse = circle + c[:, nopts*[0]]
    ellipse2 = 0.5 * circle + c[:, nopts*[0]]
    
    pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k-')
    pylab.fill(ellipse2[0,:].T, ellipse2[1,:].T, facecolor = '#F0F0F0')
    pylab.title('Loewner-John ellipsoid (fig 8.3)')
Пример #29
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]
Пример #30
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])
Пример #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)  
Пример #32
0
            def f(x, y, z):
                """
                1. Compute 

                   uy = D^-1 * (I + Y * S^-1 * Y') * D^-1 * 
                        ( -by + sum_k (Dk^2 - Dk^2 * X * Hk^-1 * X' * Dk^2)
                        * ( bxk + Dk^-2 *bzk ) )
 
                2. For k = 1, ..., m:

                   uxk = (Dk^2 - Dk^2 * X * Hk^-1 * X' * Dk^2) * 
                         (-uy + bxk + Dk^-2 * bzk)

                3. Solve for uz

                   d .* uz = ( ux - mat(bz) ) ./ d.
        
                Return ux, uy, d .* uz.
                """

                ###
                utime0, stime0 = cputime()
                ###

                # xk := Dk^2 * xk + zk
                #     = Dk^2 * bxk + bzk
                blas.tbmv(dsq, x, n=N * m, k=0, ldA=1)
                blas.axpy(z, x)

                # y := -y + sum_k ( I - Dk^2 * X * Hk^-1 * X' ) * xk
                #    = -y + x*ones - sum_k Dk^2 * X * Hk^-1 * X' * xk

                # y := -y + x*ones
                blas.gemv(x, ones, y, alpha=1.0, beta=-1.0)

                # wnm = X' * x  (wnm interpreted as an n x m matrix)
                blas.gemm(X, x, wnm, m=n, k=N, n=m, transA='T', ldB=N, ldC=n)

                # wnm[:,k] = Hk \ wnm[:,k] (for wnm as an n x m matrix)
                for k in range(m):
                    lapack.potrs(H[k], wnm, offsetB=k * n)

                for k in range(m):

                    # wN = X * wnm[:,k]
                    blas.gemv(X, wnm, wN, offsetx=n * k)

                    # wN = Dk^2 * wN
                    blas.tbmv(dsq[:, k], wN, n=N, k=0, ldA=1)

                    # y := y - wN
                    blas.axpy(wN, y, -1.0)

                # y = D^-1 * (I + Y * S^-1 * Y') * D^-1 * y
                #
                # Y = [Y1 ... Ym ], Yk = D^-1 * Dk^2 * X * Lk^-T.

                # y := D^-1 * y
                blas.tbsv(D, y, n=N, k=0, ldA=1)

                # wnm =  Y' * y  (interpreted as an Nm vector)
                #     = [ L1^-1 * X' * D1^2 * D^-1 * y;
                #         L2^-1 * X' * D2^2 * D^-1 * y;
                #         ...
                #         Lm^-1 * X' * Dm^2 * D^-1 * y ]

                for k in range(m):

                    # wN = D^-1 * Dk^2 * y
                    blas.copy(y, wN)
                    blas.tbmv(dsq, wN, n=N, k=0, ldA=1, offsetA=k * N)
                    blas.tbsv(D, wN, n=N, k=0, ldA=1)

                    # wnm[:,k] = X' * wN
                    blas.gemv(X, wN, wnm, trans='T', offsety=k * n)

                    # wnm[:,k] = Lk^-1 * wnm[:,k]
                    blas.trsv(H[k], wnm, offsetx=k * n)

                # wnm := S^-1 * wnm  (an mn-vector)
                lapack.potrs(S, wnm)

                # y := y + Y * wnm
                #    = y + D^-1 * [ D1^2 * X * L1^-T ... D2^k * X * Lk^-T]
                #      * wnm

                for k in range(m):

                    # wnm[:,k] = Lk^-T * wnm[:,k]
                    blas.trsv(H[k], wnm, trans='T', offsetx=k * n)

                    # wN = X * wnm[:,k]
                    blas.gemv(X, wnm, wN, offsetx=k * n)

                    # wN = D^-1 * Dk^2 * wN
                    blas.tbmv(dsq, wN, n=N, k=0, ldA=1, offsetA=k * N)
                    blas.tbsv(D, wN, n=N, k=0, ldA=1)

                    # y += wN
                    blas.axpy(wN, y)

                # y := D^-1 *  y
                blas.tbsv(D, y, n=N, k=0, ldA=1)

                # For k = 1, ..., m:
                #
                # xk = (I - Dk^2 * X * Hk^-1 * X') * (-Dk^2 * y + xk)

                # x = x - [ D1^2 * y ... Dm^2 * y] (as an N x m matrix)
                for k in range(m):
                    blas.copy(y, wN)
                    blas.tbmv(dsq, wN, n=N, k=0, ldA=1, offsetA=k * N)
                    blas.axpy(wN, x, -1.0, offsety=k * N)

                # wnm  = X' * x (as an n x m matrix)
                blas.gemm(X, x, wnm, transA='T', m=n, n=m, k=N, ldB=N, ldC=n)

                # wnm[:,k] = Hk^-1 * wnm[:,k]
                for k in range(m):
                    lapack.potrs(H[k], wnm, offsetB=n * k)

                for k in range(m):

                    # wN = X * wnm[:,k]
                    blas.gemv(X, wnm, wN, offsetx=k * n)

                    # wN = Dk^2 * wN
                    blas.tbmv(dsq, wN, n=N, k=0, ldA=1, offsetA=k * N)

                    # x[:,k] := x[:,k] - wN
                    blas.axpy(wN, x, -1.0, n=N, offsety=k * N)

                # z := ( x - z ) ./ d
                blas.axpy(x, z, -1.0)
                blas.scal(-1.0, z)
                blas.tbsv(d, z, n=N * m, k=0, ldA=1)

                ###
                utime, stime = cputime()
                print("Solve:       utime = %.2f, stime = %.2f" \
                    %(utime-utime0, stime-stime0))
Пример #33
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])
Пример #34
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]
Пример #35
0
        def solve(x, y, z):

            # Solve
            #
            #     [ H          A'  GG'*W^{-1} ]   [ ux   ]   [ bx        ]
            #     [ A          0   0          ] * [ uy   ] = [ by        ]
            #     [ W^{-T}*GG  0   -I         ]   [ W*uz ]   [ W^{-T}*bz ]
            #
            # and return ux, uy, W*uz.
            #
            # If not F['singular']:
            #
            #     K*uy = A * S^{-1} * ( bx + GG'*W^{-1}*W^{-T}*bz ) - by
            #     S*ux = bx + GG'*W^{-1}*W^{-T}*bz - A'*uy
            #     W*uz = W^{-T} * ( GG*ux - bz ).
            #
            # If F['singular']:
            #
            #     K*uy = A * S^{-1} * ( bx + GG'*W^{-1}*W^{-T}*bz + A'*by )
            #            - by
            #     S*ux = bx + GG'*W^{-1}*W^{-T}*bz + A'*by - A'*y.
            #     W*uz = W^{-T} * ( GG*ux - bz ).

            # z := W^{-1} * z = W^{-1} * bz
            scale(z, W, trans='T', inverse='I')

            # If not F['singular']:
            #     x := L^{-1} * P * (x + GGs'*z)
            #        = L^{-1} * P * (x + GG'*W^{-1}*W^{-T}*bz)
            #
            # If F['singular']:
            #     x := L^{-1} * P * (x + GGs'*z + A'*y))
            #        = L^{-1} * P * (x + GG'*W^{-1}*W^{-T}*bz + A'*y)

            if mnl:
                base.gemv(F['Dfs'], z, x, trans='T', beta=1.0)
            base.gemv(F['Gs'], z, x, offsetx=mnl, trans='T',
                      beta=1.0)
            if F['singular']:
                base.gemv(A, y, x, trans='T', beta=1.0)
            if type(F['S']) is matrix:
                blas.trsv(F['S'], x)
            else:
                cholmod.solve(F['Sf'], x, sys=7)
                cholmod.solve(F['Sf'], x, sys=4)

            # y := K^{-1} * (Asc*x - y)
            #    = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz) - by)
            #      (if not F['singular'])
            #    = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz +
            #      A'*by) - by)
            #      (if F['singular']).

            base.gemv(Asct, x, y, trans='T', beta=-1.0)
            if type(F['K']) is matrix:
                lapack.potrs(F['K'], y)
            else:
                cholmod.solve(Kf, y)

            # x := P' * L^{-T} * (x - Asc'*y)
            #    = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz - A'*y)
            #      (if not F['singular'])
            #    = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz + A'*by - A'*y)
            #      (if F['singular'])

            base.gemv(Asct, y, x, alpha=-1.0, beta=1.0)
            if type(F['S']) is matrix:
                blas.trsv(F['S'], x, trans='T')
            else:
                cholmod.solve(F['Sf'], x, sys=5)
                cholmod.solve(F['Sf'], x, sys=8)

            # W*z := GGs*x - z = W^{-T} * (GG*x - bz)
            if mnl:
                base.gemv(F['Dfs'], x, z, beta=-1.0)
            base.gemv(F['Gs'], x, z, beta=-1.0, offsety=mnl)
Пример #36
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)  
Пример #37
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)
Пример #38
0
def F(x=None, z=None):
    if x is None:
        return m, matrix([1.0, 0.0, 1.0, 0.0, 0.0])

    # Factor A as A = L*L'.  Compute inverse B = A^-1.
    A = matrix([x[0], x[1], x[1], x[2]], (2, 2))
    L = +A
    try:
        lapack.potrf(L)
    except:
        return None
    B = +L
    lapack.potri(B)
    B[0, 1] = B[1, 0]

    # f0 = -log det A
    f = matrix(0.0, (m + 1, 1))
    f[0] = -2.0 * (log(L[0, 0]) + log(L[1, 1]))

    # fk = xk'*A*xk - 2*xk'*b + b*A^-1*b - 1
    #    = (xk - c)' * A * (xk - c) - 1  where c = A^-1*b
    c = x[3:]
    lapack.potrs(L, c)
    for k in range(m):
        f[k + 1] = (X[k, :].T - c).T * A * (X[k, :].T - c) - 1.0

    # gradf0 = (-A^-1, 0) = (-B, 0)
    Df = matrix(0.0, (m + 1, 5))
    Df[0, 0], Df[0, 1], Df[0, 2] = -B[0, 0], -2.0 * B[1, 0], -B[1, 1]

    # gradfk = (xk*xk' - A^-1*b*b'*A^-1,  2*(-xk + A^-1*b))
    #        = (xk*xk' - c*c', 2*(-xk+c))
    Df[1:, 0] = X[:m, 0]**2 - c[0]**2
    Df[1:, 1] = 2.0 * (mul(X[:m, 0], X[:m, 1]) - c[0] * c[1])
    Df[1:, 2] = X[:m, 1]**2 - c[1]**2
    Df[1:, 3] = 2.0 * (-X[:m, 0] + c[0])
    Df[1:, 4] = 2.0 * (-X[:m, 1] + c[1])

    if z is None: return f, Df

    # hessf0(Y, y) = (A^-1*Y*A^-1, 0) = (B*YB, 0)
    H0 = matrix(0.0, (5, 5))
    H0[0, 0] = B[0, 0]**2
    H0[1, 0] = 2.0 * B[0, 0] * B[1, 0]
    H0[2, 0] = B[1, 0]**2
    H0[1, 1] = 2.0 * (B[0, 0] * B[1, 1] + B[1, 0]**2)
    H0[2, 1] = 2.0 * B[1, 0] * B[1, 1]
    H0[2, 2] = B[1, 1]**2

    # hessfi(Y, y)
    #     = ( A^-1*Y*A^-1*b*b'*A^-1 + A^-1*b*b'*A^-1*Y*A^-1
    #             - A^-1*y*b'*A^-1 - A^-1*b*y'*A^-1,
    #         -2*A^-1*Y*A^-1*b + 2*A^-1*y )
    #     = ( B*Y*c*c' + c*c'*Y*B - B*y*c' - c*y'*B,  -2*B*Y*c + 2*B*y )
    #     = ( B*(Y*c-y)*c' + c*(Y*c-y)'*B, -2*B*(Y*c - y) )
    H1 = matrix(0.0, (5, 5))
    H1[0, 0] = 2.0 * c[0]**2 * B[0, 0]
    H1[1, 0] = 2.0 * (c[0] * c[1] * B[0, 0] + c[0]**2 * B[1, 0])
    H1[2, 0] = 2.0 * c[0] * c[1] * B[1, 0]
    H1[3:, 0] = -2.0 * c[0] * B[:, 0]
    H1[1,1] = 2.0 * c[0]**2 * B[1,1] + 4.0 * c[0]*c[1]*B[1,0]  + \
              2.0 * c[1]**2 + B[0,0]
    H1[2, 1] = 2.0 * (c[1]**2 * B[1, 0] + c[0] * c[1] * B[1, 1])
    H1[3:, 1] = -2.0 * B * c[[1, 0]]
    H1[2, 2] = 2.0 * c[1]**2 * B[1, 1]
    H1[3:, 2] = -2.0 * c[1] * B[:, 1]
    H1[3:, 3:] = 2 * B

    return f, Df, z[0] * H0 + sum(z[1:]) * H1
Пример #39
0
    return f, Df, z[0] * H0 + sum(z[1:]) * H1


sol = solvers.cp(F)
A = matrix(sol['x'][[0, 1, 1, 2]], (2, 2))
b = sol['x'][3:]

if pylab_installed:
    pylab.figure(1, facecolor='w')
    pylab.plot(X[:, 0], X[:, 1], 'ko', X[:, 0], X[:, 1], '-k')

    # Ellipsoid in the form { x | || L' * (x-c) ||_2 <= 1 }
    L = +A
    lapack.potrf(L)
    c = +b
    lapack.potrs(L, c)

    # 1000 points on the unit circle
    nopts = 1000
    angles = matrix([a * 2.0 * pi / nopts for a in range(nopts)], (1, nopts))
    circle = matrix(0.0, (2, nopts))
    circle[0, :], circle[1, :] = cos(angles), sin(angles)

    # ellipse = L^-T * circle + c
    blas.trsm(L, circle, transA='T')
    ellipse = circle + c[:, nopts * [0]]
    ellipse2 = 0.5 * circle + c[:, nopts * [0]]

    pylab.plot(ellipse[0, :].T, ellipse[1, :].T, 'k-')
    pylab.fill(ellipse2[0, :].T, ellipse2[1, :].T, facecolor='#F0F0F0')
    pylab.title('Loewner-John ellipsoid (fig 8.3)')
Пример #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)