Beispiel #1
0
    def logWeighting(self, x):
        """
        Log re-weighting function used in sparse optimization.

        Parameters
        ----------
        x: np.ndarray
            Array of parameters for weighting.
        """
        ncoeff = x.size[0]
        return log(div(blas.asum(x) + ncoeff * self.eps, abs(x) + self.eps))
Beispiel #2
0
    def Fgp(x = None, z = None):

        if x is None: return mnl, matrix(0.0, (n,1))

        f = matrix(0.0, (mnl+1,1))
        Df = matrix(0.0, (mnl+1,n))

        # y = F*x+g
        blas.copy(g, y)
        base.gemv(F, x, y, beta=1.0)

        if z is not None: H = matrix(0.0, (n,n))

        for i, start, stop in ind:

            # yi := exp(yi) = exp(Fi*x+gi)
            ymax = max(y[start:stop])
            y[start:stop] = base.exp(y[start:stop] - ymax)

            # fi = log sum yi = log sum exp(Fi*x+gi)
            ysum = blas.asum(y, n=stop-start, offset=start)
            f[i] = ymax + math.log(ysum)

            # yi := yi / sum(yi) = exp(Fi*x+gi) / sum(exp(Fi*x+gi))
            blas.scal(1.0/ysum, y, n=stop-start, offset=start)

            # gradfi := Fi' * yi
            #        = Fi' * exp(Fi*x+gi) / sum(exp(Fi*x+gi))
            base.gemv(F, y, Df, trans='T', m=stop-start, incy=mnl+1,
                offsetA=start, offsetx=start, offsety=i)

            if z is not None:

                # Hi = Fi' * (diag(yi) - yi*yi') * Fi
                #    = Fisc' * Fisc
                # where
                # Fisc = diag(yi)^1/2 * (I - 1*yi') * Fi
                #      = diag(yi)^1/2 * (Fi - 1*gradfi')

                Fsc[:K[i], :] = F[start:stop, :]
                for k in range(start,stop):
                   blas.axpy(Df, Fsc, n=n, alpha=-1.0, incx=mnl+1,
                       incy=Fsc.size[0], offsetx=i, offsety=k-start)
                   blas.scal(math.sqrt(y[k]), Fsc, inc=Fsc.size[0],
                       offset=k-start)

                # H += z[i]*Hi = z[i] * Fisc' * Fisc
                blas.syrk(Fsc, H, trans='T', k=stop-start, alpha=z[i],
                    beta=1.0)

        if z is None:
            return f, Df
        return f, Df, H
Beispiel #3
0
def mineig(H, x=None, maxit=1000, tol=1.0e-2):
    'Function to use power iteration to obtain mineig of a pd matrix.'

    # Upper bound of the maximum eig
    n = H.size[1]
    nrm1 = 0
    for i in range(n):
        nrm1 = max(nrm1, asum(matrix(H[i, :])))

#    diag = float(np.linalg.norm(H,1))
    diag = nrm1
    Diag = spdiag([diag] * n)
    norm, it, x = poweriter(Diag - H, x, maxit, tol)
    norm = diag - norm
    return (norm, it, x)
Beispiel #4
0
        def g(x, y, z):

            # Solve
            #
            #     [ K    d3    ] [ ux_y ]
            #     [            ] [      ] =
            #     [ d3'  1'*d3 ] [ ux_b ]
            #
            #         [ bx_y ]   [ D  ]
            #         [      ] - [    ] * D3 * (D2 * bx_v + bx_z - bx_w).
            #         [ bx_b ]   [ d' ]

            x[:N] -= mul(d, mul(d3, mul(d2, x[-N:]) + z[:N] - z[-N:]))
            x[N] -= blas.dot(d, mul(d3, mul(d2, x[-N:]) + z[:N] - z[-N:]))

            # Solve dy1 := K^-1 * x[:N]
            blas.copy(x, dy1, n=N)
            chompack.trsm(L, dy1, trans='N')
            chompack.trsm(L, dy1, trans='T')

            # Find ux_y = dy1 - ux_b * dy2 s.t
            #
            #     d3' * ( dy1 - ux_b * dy2 + ux_b ) = x[N]
            #
            # i.e.  x[N] := ( x[N] - d3'* dy1 ) / ( d3'* ( 1 - dy2 ) ).

            x[N] = ( x[N] - blas.dot(d3, dy1) ) / \
                ( blas.asum(d3) - blas.dot(d3, dy2) )
            x[:N] = dy1 - x[N] * dy2

            # ux_v = D4 * ( bx_v -  D1^-1 (bz_z + D * (ux_y + ux_b))
            #     - D2^-1 * bz_w )

            x[-N:] = mul(
                d4, x[-N:] - div(z[:N] + mul(d, x[:N] + x[N]), d1) -
                div(z[N:], d2))

            # uz_z = - D1^-1 * ( bx_z - D * ( ux_y + ux_b ) - ux_v )
            # uz_w = - D2^-1 * ( bx_w - uz_w )
            z[:N] += base.mul(d, x[:N] + x[N]) + x[-N:]
            z[-N:] += x[-N:]
            blas.scal(-1.0, z)

            # Return W['di'] * uz
            blas.tbmv(W['di'], z, n=2 * N, k=0, ldA=1)
Beispiel #5
0
q = matrix(0.0, (2*n,1))
q[:n] = -A.T*b
I = matrix(0.0, (n,n)) 
I[::n+1] = 1.0
G = matrix([[I, -I, matrix(0.0, (1,n))], [-I, -I, matrix(1.0, (1,n))]])
h = matrix(0.0, (2*n+1,1))

# Least-norm solution
xln = matrix(0.0, (n,1))
xln[:m] = b
lapack.gels(+A, xln)

nopts = 100
res = [ blas.nrm2(b) ]
card = [ 0 ]
alphas = blas.asum(xln)/(nopts-1) * matrix(range(1,nopts), tc='d')
for alpha in alphas:

    #    minimize    ||A*x-b||_2
    #    subject to  ||x||_1 <= alpha

    h[-1] = alpha
    x = solvers.qp(P, q, G, h)['x'][:n]
    xmax = max(abs(x))
    I = [ k for k in range(n) if abs(x[k]) > tol*xmax ]
    if len(I) <= m:
        xs = +b 
        lapack.gels(A[:,I], xs)
        x[:] = 0.0
        x[I] = xs[:len(I)]
        res += [ blas.nrm2(A*x-b) ]
Beispiel #6
0
            # z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:])
            z[:n-1] = mul(W['di'][:n-1], u - x[n:] - z[:n-1])
            z[n-1:] = mul(W['di'][n-1:], -u - x[n:] - z[n-1:])

        return g

    return solvers.coneqp(P, q, G, h, kktsolver = Fkkt)['x'][:n]


nopts = 15
deltas = -3.0 + (3.0-(-3.0))/(nopts-1) * matrix(list(range(nopts)))
cost1, cost2 = [], []
for delta, k in zip(deltas, range(nopts)):
    xtv = tv(10**delta)
    cost1 += [blas.nrm2(xtv - corr)] 
    cost2 += [blas.asum(xtv[1:] - xtv[:-1])] 
mv1, k1 = min(zip([abs(c - 20.0) for c in cost2], range(nopts)))
xtv1 = tv(10**deltas[k1])
mv2, k2 = min(zip([abs(c - 8.0) for c in cost2], range(nopts)))
xtv2 = tv(10**deltas[k2])
mv3, k3 = min(zip([abs(c - 5.0) for c in cost2], range(nopts)))
xtv3 = tv(10**deltas[k3])

if pylab_installed:
    pylab.figure(4, facecolor='w', figsize=(8,5))
    pylab.subplot(211)
    pylab.plot(t, ex)
    pylab.ylabel('x[i]')
    pylab.xlabel('i')
    pylab.axis([0, 2000, -2, 2])
    pylab.title('Original and corrupted signal (fig. 6.11)')
Beispiel #7
0
    def Fgp(x=None, z=None):

        if x is None: return mnl, matrix(0.0, (n, 1))

        f = matrix(0.0, (mnl + 1, 1))
        Df = matrix(0.0, (mnl + 1, n))

        # y = F*x+g
        blas.copy(g, y)
        base.gemv(F, x, y, beta=1.0)

        if z is not None: H = matrix(0.0, (n, n))

        for i, start, stop in ind:

            # yi := exp(yi) = exp(Fi*x+gi)
            ymax = max(y[start:stop])
            y[start:stop] = base.exp(y[start:stop] - ymax)

            # fi = log sum yi = log sum exp(Fi*x+gi)
            ysum = blas.asum(y, n=stop - start, offset=start)
            f[i] = ymax + math.log(ysum)

            # yi := yi / sum(yi) = exp(Fi*x+gi) / sum(exp(Fi*x+gi))
            blas.scal(1.0 / ysum, y, n=stop - start, offset=start)

            # gradfi := Fi' * yi
            #        = Fi' * exp(Fi*x+gi) / sum(exp(Fi*x+gi))
            base.gemv(F,
                      y,
                      Df,
                      trans='T',
                      m=stop - start,
                      incy=mnl + 1,
                      offsetA=start,
                      offsetx=start,
                      offsety=i)

            if z is not None:

                # Hi = Fi' * (diag(yi) - yi*yi') * Fi
                #    = Fisc' * Fisc
                # where
                # Fisc = diag(yi)^1/2 * (I - 1*yi') * Fi
                #      = diag(yi)^1/2 * (Fi - 1*gradfi')

                Fsc[:K[i], :] = F[start:stop, :]
                for k in range(start, stop):
                    blas.axpy(Df,
                              Fsc,
                              n=n,
                              alpha=-1.0,
                              incx=mnl + 1,
                              incy=Fsc.size[0],
                              offsetx=i,
                              offsety=k - start)
                    blas.scal(math.sqrt(y[k]),
                              Fsc,
                              inc=Fsc.size[0],
                              offset=k - start)

                # H += z[i]*Hi = z[i] * Fisc' * Fisc
                blas.syrk(Fsc,
                          H,
                          trans='T',
                          k=stop - start,
                          alpha=z[i],
                          beta=1.0)

        if z is None:
            return f, Df
        return f, Df, H
            # z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:])
            z[:n - 1] = mul(W['di'][:n - 1], u - x[n:] - z[:n - 1])
            z[n - 1:] = mul(W['di'][n - 1:], -u - x[n:] - z[n - 1:])

        return g

    return solvers.coneqp(P, q, G, h, kktsolver=Fkkt)['x'][:n]


nopts = 15
deltas = -3.0 + (3.0 - (-3.0)) / (nopts - 1) * matrix(list(range(nopts)))
cost1, cost2 = [], []
for delta, k in zip(deltas, range(nopts)):
    xtv = tv(10**delta)
    cost1 += [blas.nrm2(xtv - corr)]
    cost2 += [blas.asum(xtv[1:] - xtv[:-1])]
mv1, k1 = min(zip([abs(c - 20.0) for c in cost2], range(nopts)))
xtv1 = tv(10**deltas[k1])
mv2, k2 = min(zip([abs(c - 8.0) for c in cost2], range(nopts)))
xtv2 = tv(10**deltas[k2])
mv3, k3 = min(zip([abs(c - 5.0) for c in cost2], range(nopts)))
xtv3 = tv(10**deltas[k3])

if pylab_installed:
    pylab.figure(4, facecolor='w', figsize=(8, 5))
    pylab.subplot(211)
    pylab.plot(t, ex)
    pylab.ylabel('x[i]')
    pylab.xlabel('i')
    pylab.axis([0, 2000, -2, 2])
    pylab.title('Original and corrupted signal (fig. 6.11)')
    def invert(self, Ain, bin, penalty, eps=1.0e-4, pconst=0.0):
        """
        Calls CVXOPT Cone quadratic program solver.

        Arguments:
        Ain                     input design array of size (M x N)
        bin                     input data array of size (M)
        penalty                 floating point penalty parameter (lambda)
        eps                     small number to provide stability for re-weighting.

        Returns:
        x                       regularized least-squares solution of size (N)
        q                       array of weights used in regularization (diagonals of F)
        """

        from cvxopt import matrix, spdiag, mul, div, sqrt, log
        from cvxopt import blas, lapack, solvers, sparse, spmatrix

        solvers.options['show_progress'] = False
        arrflag = isinstance(penalty, np.ndarray)

        # Convert Numpy arrays to CVXOPT matrices
        b = matrix(bin)
        A = matrix(Ain)
        m,n = A.size
        nspl = n - self.cutoff

        # Fill q (will modify for re-weighting)
        q = matrix(0.0, (2*n,1))
        q[:n] = -A.T * b
        q[n+self.cutoff:] = penalty

        # Fill h
        h = matrix(0.0, (2*n,1))

        # Fill P
        P = matrix(0.0, (2*n,2*n))
        P[:n,:n] = A.T * A
        P[list(range(n)),list(range(n))] += pconst
        P = sparse(P)

        # Fill G
        G = matrix(0.0, (2*n,2*n))
        eye = spmatrix(1.0, range(n), range(n))
        G[:n,:n] = eye
        G[:n,n:] = -1.0 * eye
        G[n:,:n] = -1.0 * eye
        G[n:,n:] = -1.0 * eye
        G = sparse(G)

        # Perform re-weighting by calling solvers.coneqp()
        for iters in range(self.maxiter):
            x = solvers.qp(P, q, G=G, h=h)['x'][:n]
            xspl = x[self.cutoff:]
            wnew = log(div(blas.asum(xspl) + nspl*eps, abs(xspl) + eps))
            if arrflag: # if outputting array, use only 1 re-weight iteration
                q[n+self.cutoff:] = wnew
            else:
                q[n+self.cutoff:] = penalty * wnew
        
        return np.array(x).squeeze(), np.array(q[n:]).squeeze()
Beispiel #10
0
            # z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:])
            z[: n - 1] = mul(W["di"][: n - 1], u - x[n:] - z[: n - 1])
            z[n - 1 :] = mul(W["di"][n - 1 :], -u - x[n:] - z[n - 1 :])

        return g

    return solvers.coneqp(P, q, G, h, kktsolver=Fkkt)["x"][:n]


nopts = 15
deltas = -3.0 + (3.0 - (-3.0)) / (nopts - 1) * matrix(list(range(nopts)))
cost1, cost2 = [], []
for delta, k in zip(deltas, range(nopts)):
    xtv = tv(10 ** delta)
    cost1 += [blas.nrm2(xtv - corr)]
    cost2 += [blas.asum(xtv[1:] - xtv[:-1])]
mv1, k1 = min(zip([abs(c - 20.0) for c in cost2], range(nopts)))
xtv1 = tv(10 ** deltas[k1])
mv2, k2 = min(zip([abs(c - 8.0) for c in cost2], range(nopts)))
xtv2 = tv(10 ** deltas[k2])
mv3, k3 = min(zip([abs(c - 5.0) for c in cost2], range(nopts)))
xtv3 = tv(10 ** deltas[k3])

if pylab_installed:
    pylab.figure(4, facecolor="w", figsize=(8, 5))
    pylab.subplot(211)
    pylab.plot(t, ex)
    pylab.ylabel("x[i]")
    pylab.xlabel("i")
    pylab.axis([0, 2000, -2, 2])
    pylab.title("Original and corrupted signal (fig. 6.11)")