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))
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
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)
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)
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) ]
# 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 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()
# 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)")