コード例 #1
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
コード例 #2
0
 def F(x=None, z=None):
     if x is None: return 0, matrix(1.0, (n, 1))
     if min(x) <= 0.0: return None
     f = -sum(log(x))
     Df = -(x**-1).T
     if z is None: return matrix(f), Df
     H = spdiag(z[0] * x**-2)
     return f, Df, H
コード例 #3
0
def F(x = None, z = None):  
     if x is None:  return 0, matrix(0.0, (3,1))  
     if max(abs(x)) >= 1.0:  return None  
     u = 1 - x**2  
     val = -sum(log(u))  
     Df = div(2*x, u).T  
     if z is None:  return val, Df  
     H = spdiag(2 * z[0] * div(1 + u**2, u**2))  
     return val, Df, H  
コード例 #4
0
def acent(A,b):
    """  
    Computes analytic center of A*x <= b with A m by n of rank n. 
    We assume that b > 0 and the feasible set is bounded.
    """

    MAXITERS = 100
    ALPHA = 0.01
    BETA = 0.5
    TOL = 1e-8

    ntdecrs = []
    m, n = A.size
    x = matrix(0.0, (n,1))
    H = matrix(0.0, (n,n))

    for iter in range(MAXITERS):
        
        # Gradient is g = A^T * (1./(b-A*x)).
        d = (b-A*x)**-1
        g = A.T * d

        # Hessian is H = A^T * diag(1./(b-A*x))^2 * A.
        Asc = mul( d[:,n*[0]], A)
        blas.syrk(Asc, H, trans='T')

        # Newton step is v = H^-1 * g.
        v = -g
        lapack.posv(H, v)

        # Directional derivative and Newton decrement.
        lam = blas.dot(g, v)
        ntdecrs += [ sqrt(-lam) ]
        print("%2d.  Newton decr. = %3.3e" %(iter,ntdecrs[-1]))
        if ntdecrs[-1] < TOL: return x, ntdecrs

        # Backtracking line search.
        y = mul(A*v, d)
        step = 1.0
        while 1-step*max(y) < 0: step *= BETA 
        while True:
            if -sum(log(1-step*y)) < ALPHA*step*lam: break
            step *= BETA
        x += step*v
コード例 #5
0
def covsel(Y):
    """
    Returns the solution of
 
        minimize    -log det K + tr(KY)
        subject to  K_ij = 0  if (i,j) not in zip(I, J).

    Y is a symmetric sparse matrix with nonzero diagonal elements.
    I = Y.I,  J = Y.J.
    """

    cholmod.options['supernodal'] = 2

    I, J = Y.I, Y.J
    n, m = Y.size[0], len(I) 
    # non-zero positions for one-argument indexing 
    N = I + J*n         
    # position of diagonal elements
    D = [ k for k in range(m) if I[k]==J[k] ]  

    # starting point: symmetric identity with nonzero pattern I,J
    K = spmatrix(0.0, I, J) 
    K[::n+1] = 1.0

    # Kn is used in the line search
    Kn = spmatrix(0.0, I, J)

    # symbolic factorization of K 
    F = cholmod.symbolic(K)

    # Kinv will be the inverse of K
    Kinv = matrix(0.0, (n,n))

    for iters in range(100):

        # numeric factorization of K
        cholmod.numeric(K, F)
        d = cholmod.diag(F)

        # compute Kinv by solving K*X = I 
        Kinv[:] = 0.0
        Kinv[::n+1] = 1.0
        cholmod.solve(F, Kinv)
        
        # solve Newton system
        grad = 2 * (Y.V - Kinv[N])
        hess = 2 * ( mul(Kinv[I,J], Kinv[J,I]) + 
               mul(Kinv[I,I], Kinv[J,J]) )
        v = -grad
        lapack.posv(hess,v) 
                                                  
        # stopping criterion
        sqntdecr = -blas.dot(grad,v) 
        print("Newton decrement squared:%- 7.5e" %sqntdecr)
        if (sqntdecr < 1e-12):
            print("number of iterations: %d" %(iters+1))
            break

        # line search
        dx = +v
        dx[D] *= 2      
        f = -2.0*sum(log(d))      # f = -log det K
        s = 1
        for lsiter in range(50):
            Kn.V = K.V + s*dx
            try: 
                cholmod.numeric(Kn, F)
            except ArithmeticError: 
                s *= 0.5
            else:
                d = cholmod.diag(F)
                fn = -2.0 * sum(log(d)) + 2*s*blas.dot(v,Y.V)
                if (fn < f - 0.01*s*sqntdecr): break
                else: s *= 0.5

        K.V = Kn.V

    return K
コード例 #6
0
# The small GP of section 9.3 (Geometric programming).

from kvxopt import matrix, log, exp, solvers

Aflr = 1000.0
Awall = 100.0
alpha = 0.5
beta = 2.0
gamma = 0.5
delta = 2.0

F = matrix([[-1., 1., 1., 0., -1., 1., 0., 0.],
            [-1., 1., 0., 1., 1., -1., 1., -1.],
            [-1., 0., 1., 1., 0., 0., -1., 1.]])
g = log(
    matrix([
        1.0, 2 / Awall, 2 / Awall, 1 / Aflr, alpha, 1 / beta, gamma, 1 / delta
    ]))
K = [1, 2, 1, 1, 1, 1, 1]
h, w, d = exp(solvers.gp(K, F, g)['x'])
print("\n h = %f,  w = %f, d = %f.\n" % (h, w, d))