Beispiel #1
0
    def spy(P,i=None,file=None,scale=None):
        """Generates sparsity plot using Pylab"""
        if type(P) is spmatrix:
            V = chompack.symmetrize(chompack.tril(P))
            n = V.size[0]
        else:
            if not P._A: raise AttributeError, "SDP data missing"
            n = +P.n; 
            if i == None: V = chompack.symmetrize(P.V)
            elif i>=0 and i<=P.m and P._A:
                r = P._A.CCS[1][P._A.CCS[0][i]:P._A.CCS[0][i+1]]
                if type(r) is int: I = [r%n]; J = [r/n]
                else: I,J = misc.ind2sub(n,r)
                V = chompack.symmetrize(spmatrix(0.,I,J,(n,n)))
            else: raise ValueError, "index out of range"

        from math import floor
        msize = max(1,int(floor(100./n)))

        if file==None: pylab.ion()
        else: pylab.ioff()
        f = pylab.figure(figsize=(6,6)); f.clf()
        if scale is None: scale = 1.0 
        I = V.I*scale+1; J = (n-V.J)*scale
        p = pylab.plot(I,J, 's', linewidth = 1, hold = 'False')
        pylab.setp(p, markersize = msize, markerfacecolor = 'k')
        g = pylab.gca()
        pylab.axis([0.5,n*scale+0.5,0.5,n*scale+0.5])
        g.set_aspect('equal')
        locs,labels = pylab.yticks()
        locs = locs[locs<=n*scale]; locs = locs[locs>=1]
        pylab.yticks(locs[::-1]-(locs[-1]-n*scale-1)-locs[0],
                     [str(int(loc)) for loc in locs])
        if file: pylab.savefig(file)
Beispiel #2
0
    def setUp(self):
        I = list(range(17)) + [
            2, 2, 3, 3, 4, 14, 4, 14, 8, 14, 15, 8, 15, 7, 8, 14, 8, 14, 14,
            15, 10, 12, 13, 16, 12, 13, 16, 12, 13, 15, 16, 13, 15, 16, 15, 16,
            15, 16, 16
        ]
        J = list(range(17)) + [
            0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,
            9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15
        ]
        self.A = spmatrix(matrix(range(len(I)), tc='d'), I, J, (17, 17))

        n = 23
        nz = [
            1, 2, 10, 12, 13, 14, 15, 16, 19, 24, 48, 58, 71, 76, 81, 85, 91,
            103, 108, 109, 111, 114, 116, 117, 118, 134, 143, 145, 161, 174,
            178, 180, 183, 192, 194, 202, 203, 205, 212, 214, 219, 224, 226,
            227, 228, 229, 235, 240, 241, 243, 247, 255, 256, 260, 269, 273,
            275, 279, 280, 314, 315, 320, 321, 328, 340, 342, 344, 345, 349,
            350, 357, 359, 370, 372, 375, 384, 385, 394, 399, 402, 411, 412,
            419, 420, 422, 433, 439, 441, 447, 452, 454, 458, 460, 474, 476,
            479, 481, 483, 485, 497, 506, 517, 519, 523, 526, 527
        ]
        self.A_nc = cp.tril(spmatrix(matrix(range(1,len(nz)+1),tc='d')/len(nz),[ni%n for ni in nz],[int(ii/n) for ii in nz],(n,n)))\
          + spmatrix(10.0,range(n),range(n))
Beispiel #3
0
def embed_SDP(P,order="AMD",cholmod=False):
    if not isinstance(P,SDP): raise ValueError, "not an SDP object"
    if order=='AMD':
        from cvxopt.amd import order
    elif order=='METIS':
        from cvxopt.metis import order
    else: raise ValueError, "unknown ordering: %s " %(order)
    p = order(P.V)

    if cholmod:
        from cvxopt import cholmod
        V = +P.V + spmatrix([float(i+1) for i in xrange(P.n)],xrange(P.n),xrange(P.n))
        F = cholmod.symbolic(V,p=p)
        cholmod.numeric(V,F)
        f = cholmod.getfactor(F)
        fd = [(j,i) for i,j in enumerate(f[:P.n**2:P.n+1])]
        fd.sort()
        ip = matrix([j for _,j in fd])
        Ve = chompack.tril(chompack.perm(chompack.symmetrize(f),ip))
        Ie = misc.sub2ind((P.n,P.n),Ve.I,Ve.J)
    else:
        #Vc,n = chompack.embed(P.V,p)
        symb = chompack.symbolic(P.V,p)
        #Ve = chompack.sparse(Vc)
        Ve = symb.sparsity_pattern(reordered=False)
        Ie = misc.sub2ind((P.n,P.n),Ve.I,Ve.J)
    Pe = SDP()
    Pe._A = +P.A; Pe._b = +P.b
    Pe._A[:,0] += spmatrix(0.0,Ie,[0 for i in range(len(Ie))],(Pe._A.size[0],1))
    Pe._agg_sparsity()
    Pe._pname = P._pname + "_embed"
    Pe._ischordal = True; Pe._blockstruct = P._blockstruct
    return Pe      
Beispiel #4
0
    def test_cspmatrix(self):
        Ac = cp.cspmatrix(self.symb) + self.A
        self.assertTrue(Ac.is_factor is False)
        self.assertTrue(Ac.size[0] == Ac.size[1])
        self.assertTrue(Ac.size[0] == 17)

        diff = list((self.A - Ac.spmatrix(reordered=False,symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        diff = list(cp.symmetrize(self.A) - Ac.spmatrix(reordered=False,symmetric=True))
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        diff = list(cp.symmetrize(self.A)[self.symb.p,self.symb.p] - Ac.spmatrix(reordered=True,symmetric=True))
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        diff = list(cp.tril(cp.symmetrize(self.A)[self.symb.p,self.symb.p]) - Ac.spmatrix(reordered=True,symmetric=False))
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])
                
        diff = list((2*self.A -  (2*Ac).spmatrix(reordered=False,symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        diff = list((2*self.A -  (Ac+Ac).spmatrix(reordered=False,symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        Ac2 = Ac.copy()
        Ac2 += Ac
        diff = list((2*self.A -  Ac2.spmatrix(reordered=False,symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff)*[0.0])

        self.assertAlmostEqualLists(list(Ac.diag(reordered=False)), list(self.A[::18]))
        self.assertAlmostEqualLists(list(Ac.diag(reordered=True)), list(self.A[self.symb.p,self.symb.p][::18]))
Beispiel #5
0
 def setUp(self):
     n = 31
     nnz = int(round(0.15*n**2))
     random.seed(1)
     nz = matrix(random.sample(range(n**2), nnz), tc='i')
     self.A = cp.tril(spmatrix(matrix(range(1,nnz+1),tc='d')/nnz, nz%n, matrix([int(ii) for ii in nz/n]), (n,n)))\
       + spmatrix(10.0,range(n),range(n))
     self.symb = cp.symbolic(self.A, p = amd.order)
Beispiel #6
0
 def setUp(self):
     n = 31
     nnz = int(round(0.15 * n**2))
     random.seed(1)
     nz = matrix(random.sample(range(n**2), nnz), tc='i')
     self.A = cp.tril(spmatrix(matrix(range(1,nnz+1),tc='d')/nnz, nz%n, matrix([int(ii) for ii in nz/n]), (n,n)))\
       + spmatrix(10.0,range(n),range(n))
     self.symb = cp.symbolic(self.A, p=amd.order)
Beispiel #7
0
    def setUp(self):
        I = list(range(17)) + [2,2,3,3,4,14,4,14,8,14,15,8,15,7,8,14,8,14,14,15,10,12,13,16,12,13,16,12,13,15,16,13,15,16,15,16,15,16,16]
        J = list(range(17)) + [0,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,9,9,9,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,15]
        self.A = spmatrix(matrix(range(len(I)),tc='d'),I,J,(17,17))

        n = 23
        nz = [1, 2, 10, 12, 13, 14, 15, 16, 19, 24, 48, 58, 71, 76, 81, 85, 91, 103, 108, 109, 111, 114, 116, 117, 118, 134, 143, 145, 161, 174, 178, 180, 183, 192, 194, 202, 203, 205, 212, 214, 219, 224, 226, 227, 228, 229, 235, 240, 241, 243, 247, 255, 256, 260, 269, 273, 275, 279, 280, 314, 315, 320, 321, 328, 340, 342, 344, 345, 349, 350, 357, 359, 370, 372, 375, 384, 385, 394, 399, 402, 411, 412, 419, 420, 422, 433, 439, 441, 447, 452, 454, 458, 460, 474, 476, 479, 481, 483, 485, 497, 506, 517, 519, 523, 526, 527]
        self.A_nc = cp.tril(spmatrix(matrix(range(1,len(nz)+1),tc='d')/len(nz),[ni%n for ni in nz],[int(ii/n) for ii in nz],(n,n)))\
          + spmatrix(10.0,range(n),range(n))
Beispiel #8
0
    def _gen_randsdp(self,V,m,d,seed):
        """
        Random data generator
        """
        setseed(seed)
        n = self._n
        V = chompack.tril(V)
        N = len(V)
        I = V.I; J = V.J
        Il = misc.sub2ind((n,n),I,J)
        Id = matrix([i for i in range(len(Il)) if I[i]==J[i]])

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

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

        # generate random A1,...,Am
        if type(d) is float:
            nz = min(max(1, int(round(d*N))), N)
            A = sparse([[spmatrix(normal(N,1),Il,[0 for i in range(N)],(n**2,1))],
                        [spmatrix(normal(nz*m,1),
                                  [i for j in range(m) for i in random.sample(Il,nz)],
                                  [j for j in range(m) for i in range(nz)],(n**2,m))]])
        elif type(d) is list:
            if len(d) == m:
                nz = [min(max(1, int(round(v*N))), N) for v in d]
                nnz = sum(nz)
                A = sparse([[spmatrix(normal(N,1),Il,[0 for i in range(N)],(n**2,1))],
                            [spmatrix(normal(nnz,1),
                                      [i for j in range(m) for i in random.sample(Il,nz[j])],
                                      [j for j in range(m) for i in range(nz[j])],(n**2,m))]])
        else: raise TypeError

        # compute A0
        u = +S0.V
        for k in range(m):
            base.gemv(A[:,k+1][Il],matrix(y0[k]),u,beta=1.0,trans='N')
        A[Il,0] = u
        self._A = A

        # compute b
        X0[Il[Id]] *= 0.5
        self._b = matrix(0.,(m,1))
        u = matrix(0.)
        for k in range(m):
            base.gemv(A[:,k+1][Il],X0.V,u,trans='T',alpha=2.0)
            self._b[k] = u
Beispiel #9
0
    def test_cspmatrix(self):
        Ac = cp.cspmatrix(self.symb) + self.A
        self.assertTrue(Ac.is_factor is False)
        self.assertTrue(Ac.size[0] == Ac.size[1])
        self.assertTrue(Ac.size[0] == 17)

        diff = list((self.A - Ac.spmatrix(reordered=False, symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        diff = list(
            cp.symmetrize(self.A) -
            Ac.spmatrix(reordered=False, symmetric=True))
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        diff = list(
            cp.symmetrize(self.A)[self.symb.p, self.symb.p] -
            Ac.spmatrix(reordered=True, symmetric=True))
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        diff = list(
            cp.tril(cp.symmetrize(self.A)[self.symb.p, self.symb.p]) -
            Ac.spmatrix(reordered=True, symmetric=False))
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        diff = list((2 * self.A -
                     (2 * Ac).spmatrix(reordered=False, symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        diff = list((2 * self.A -
                     (Ac + Ac).spmatrix(reordered=False, symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        Ac2 = Ac.copy()
        Ac2 += Ac
        diff = list(
            (2 * self.A - Ac2.spmatrix(reordered=False, symmetric=False)).V)
        self.assertAlmostEqualLists(diff, len(diff) * [0.0])

        self.assertAlmostEqualLists(list(Ac.diag(reordered=False)),
                                    list(self.A[::18]))
        self.assertAlmostEqualLists(
            list(Ac.diag(reordered=True)),
            list(self.A[self.symb.p, self.symb.p][::18]))
Beispiel #10
0
def completion(X):
    """
    Returns maximum-determinant positive definite completion of X
    if it exists, and otherwise an exception is raised.
    """
    from cvxopt.amd import order
    n = X.size[0]
    Xt = chompack.tril(X)
    p = order(Xt)
    # Xc,N = chompack.embed(Xt,p)
    # L = chompack.completion(Xc)
    symb = chompack.symbolic(Xt,p)
    L = chompack.cspmatrix(symb) + Xt
    chompack.completion(L)
    Xt = matrix(0.,(n,n))
    Xt[::n+1] = 1.
    # chompack.solve(L, Xt, mode=0)
    # chompack.solve(L, Xt, mode=1)
    chompack.trsm(L, Xt)
    chompack.trsm(L, Xt, trans = 'T')
    return Xt
Beispiel #11
0
def completion(X):
    """
    Returns maximum-determinant positive definite completion of X
    if it exists, and otherwise an exception is raised.
    """
    from cvxopt.amd import order
    n = X.size[0]
    Xt = chompack.tril(X)
    p = order(Xt)
    # Xc,N = chompack.embed(Xt,p)
    # L = chompack.completion(Xc)
    symb = chompack.symbolic(Xt, p)
    L = chompack.cspmatrix(symb) + Xt
    chompack.completion(L)
    Xt = matrix(0., (n, n))
    Xt[::n + 1] = 1.
    # chompack.solve(L, Xt, mode=0)
    # chompack.solve(L, Xt, mode=1)
    chompack.trsm(L, Xt)
    chompack.trsm(L, Xt, trans='T')
    return Xt
Beispiel #12
0
 def test_cholesky(self):
     L = cp.cspmatrix(self.symb) + self.A
     cp.cholesky(L)
     Lm = L.spmatrix(reordered=True)
     diff = list( (cp.tril(cp.perm(Lm*Lm.T,self.symb.ip)) - self.A).V )
     self.assertAlmostEqualLists(diff, len(diff)*[0.0])
Beispiel #13
0
# generate random sparse matrix
def sp_rand(m,n,a):
    """
    Generates an m-by-n sparse 'd' matrix with round(a*m*n) nonzeros.
    """
    if m == 0 or n == 0: return spmatrix([], [], [], (m,n))
    nnz = min(max(0, int(round(a*m*n))), m*n)
    nz = matrix(random.sample(range(m*n), nnz), tc='i')
    return spmatrix(normal(nnz,1), nz%m, nz/m, (m,n))

# generate random sparsity pattern and sparse SDP problem data
random.seed(1)
m, n = 50, 200
print("Generating random sparse SDP (n=%i, m=%i constraints).."%(n,m))
A = sp_rand(n,n,0.015) + spmatrix(1.0,range(n),range(n))
I = cp.tril(A)[:].I
N = len(I)/50 # each data matrix has 1/50 of total nonzeros in pattern
Ig = []; Jg = []
for j in range(m):
    Ig += sorted(random.sample(I,N))   
    Jg += N*[j]
G = spmatrix(normal(len(Ig),1),Ig,Jg,(n**2,m))
h = G*normal(m,1) + spmatrix(1.0,range(n),range(n))[:]
c = normal(m,1)
dims =  {'l':0, 'q':[], 's': [n]};

# solve SDP with CVXOPT 
print("Solving SDP with CVXOPT..")
prob = (c, G, matrix(h), dims)
sol = solvers.conelp(*prob)
Z1 = matrix(sol['z'], (n,n))
Beispiel #14
0
print("Projected inverse/completion (upd) :  err = %.3e" % (blas.nrm2(tmp)))

# Compute norm of error: At - U
tmp = (At-U).spmatrix().V
print("Hessian factors NN/TN/TI/NI        :  err = %.3e" % (blas.nrm2(tmp)))


# Test triangular matrix products and solve
p = L.symb.p

B = eye(n)
trsm(L, B)
print("trsm, trans = 'N'                  :  err = %.3e" % (blas.nrm2(L.spmatrix(reordered = True)*B[p,p] - eye(n))))

B = eye(n)
trsm(L, B, trans = 'T')
print("trsm, trans = 'T'                  :  err = %.3e" % (blas.nrm2(L.spmatrix(reordered = True).T*B[p,p] - eye(n))))

B = eye(n)
trmm(L, B)
print("trmm, trans = 'N'                  :  err = %.3e" % (blas.nrm2(L.spmatrix(reordered = True) - B[p,p])))

B = eye(n)
trmm(L, B, trans = 'T')
print("trmm, trans = 'T'                  :  err = %.3e" % (blas.nrm2(L.spmatrix(reordered = True).T - B[p,p])))

B = eye(n)
trmm(L,B,trans='T')
trmm(L,B)
print("llt(L) - trmm N/T                  :  err = %.3e" % (blas.nrm2(tril(B - As))))
Beispiel #15
0
 def test_cholesky(self):
     L = cp.cspmatrix(self.symb) + self.A
     cp.cholesky(L)
     Lm = L.spmatrix(reordered=True)
     diff = list((cp.tril(cp.perm(Lm * Lm.T, self.symb.ip)) - self.A).V)
     self.assertAlmostEqualLists(diff, len(diff) * [0.0])
Beispiel #16
0
    def solve(self, solver = "mosek"):
        if self.to_real == False: raise ValueError("Solvers do not support complex-valued data.")
        sol = {}
        c,G,h,dims = self.problem_data
        if solver == "mosek":
            if self.__verbose:
               msk.options[msk.mosek.iparam.log] = 1
            else:
               msk.options[msk.mosek.iparam.log] = 0
            solsta,mu,zz = msk.conelp(c,G,matrix(h),dims)
            sol['status'] = str(solsta).split('.')[-1]
        elif solver == "cvxopt":
            if self.__verbose:
                options = {'show_progress':True}
            else:
                options = {'show_progress':False}
            csol = solvers.conelp(c,G,matrix(h),dims,options=options)
            zz = csol['z']
            mu = csol['x']
            sol['status'] = csol['status']
        else:
            raise ValueError("Unknown solver %s" % (solver))
        if zz is None: return sol

        sol['mu'] = mu
        offset = self.offset
        sol['t'] = zz[:offset['wpl']]
        sol['wpl'] = zz[offset['wpl']:offset['wpu']]
        sol['wpu'] = zz[offset['wpu']:offset['wql']]
        sol['wql'] = zz[offset['wql']:offset['wqu']]
        sol['wqu'] = zz[offset['wqu']:offset['ul']]
        sol['ul'] = zz[offset['ul']:offset['uu']]
        sol['uu'] = zz[offset['uu']:offset['z']]
        sol['z'] = zz[offset['z']:offset['w']]
        sol['w'] = zz[offset['w']:offset['X']]

        if self.conversion:
            dims = self.problem_data[3]
            offset = dims['l'] + sum(dims['q'])
            self.Xc = []
            sol['eigratio'] = []
            for k,sk in enumerate(dims['s']):
                zk = matrix(zz[offset:offset+sk**2],(sk,sk))
                offset += sk**2
                zkr = 0.5*(zk[:sk//2,:sk//2] + zk[sk//2:,sk//2:])
                zki = 0.5*(zk[sk//2:,:sk//2] - zk[:sk//2,sk//2:])
                zki[::sk+1] = 0.0
                zk = zkr + complex(0,1.0)*zki
                self.Xc.append(zk)
                ev = matrix(0.0,(zk.size[0],1),tc='d')
                lapack.heev(+zk,ev)
                ev = sorted(list(ev),reverse=True)
                sol['eigratio'].append(ev[0]/ev[1])

            # Build partial Hermitian matrix
            z = matrix([zk[:] for zk in self.Xc])
            blki,I,J,bn = self.blocks_to_sparse[0]
            X = spmatrix(z[blki],I,J)
            idx = [i for i,ij in enumerate(zip(X.I,X.J)) if ij[0] > ij[1]]
            sol['X'] = chompack.tril(X) + spmatrix(X.V[idx].H, X.J[idx], X.I[idx], X.size)

        else:
            X = matrix(zz[offset['X']:],(2*self.nbus,2*self.nbus))
            Xr = X[:self.nbus,:self.nbus]
            Xi = X[self.nbus:,:self.nbus]
            Xi[::self.nbus+1] = 0.0
            X = Xr + complex(0.0,1.0)*Xi
            sol['X'] = +X

            V = matrix(0.0,(self.nbus,5),tc='z')
            w = matrix(0.0,(self.nbus,1))
            lapack.heevr(X, w, Z = V, jobz='V', range='I', il = self.nbus-4, iu = self.nbus)
            sol['eigratio'] = [w[4]/w[3]]
            if w[4]/w[3] < self.eigtol and self.__verbose:
                print("Eigenvalue ratio smaller than %e."%(self.eigtol))
            sol['eigs'] = w[:5]
            V = V[:,-1]*sqrt(w[4])
            sol['V'] = V

        # Branch injections
        sol['Sf'] = self.baseMVA*(sol['z'][1::6] + complex(0.0,1.0)*sol['z'][2::6])
        sol['St'] = self.baseMVA*(sol['z'][4::6] + complex(0.0,1.0)*sol['z'][5::6])

        # Generation
        sol['Sg'] = (matrix([gen['Pmin'] for gen in self.generators]) +\
                     matrix([0.0 if gen['pslack'] is None else sol['wpl'][gen['pslack']] for gen in self.generators])) +\
                     complex(0.0,1.0)*(matrix([gen['Qmin'] for gen in self.generators]) +\
                     matrix([0.0 if gen['qslack'] is None else sol['wql'][gen['qslack']] for gen in self.generators]))
        Pg = sol['Sg'].real()
        Qg = sol['Sg'].imag()
        for k,gen in enumerate(self.generators):
            gen['Pg'] = Pg[k]
            gen['Qg'] = Qg[k]
        sol['Sg'] *= self.baseMVA

        sol['cost'] = 0.0
        for ii,gen in enumerate(self.generators):
            for nk in range(gen['Pcost']['ncoef']):
                sol['cost'] += gen['Pcost']['coef'][-1-nk]*(Pg[ii]*self.baseMVA)**nk

        sol['cost_objective'] = -(self.problem_data[0].T*mu)[0]*self.cost_scale + self.const_cost

        sol['Vm'] = sqrt(matrix(sol['X'][::self.nbus+1]).real())
        return sol
Beispiel #17
0
    def _gen_randsdp(self, V, m, d, seed):
        """
        Random data generator 
        """
        setseed(seed)
        n = self._n
        V = chompack.tril(V)
        N = len(V)
        I = V.I
        J = V.J
        Il = misc.sub2ind((n, n), I, J)
        Id = matrix([i for i in xrange(len(Il)) if I[i] == J[i]])

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

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

        # generate random A1,...,Am
        if type(d) is float:
            nz = min(max(1, int(round(d * N))), N)
            A = sparse(
                [[
                    spmatrix(normal(N, 1), Il, [0 for i in xrange(N)],
                             (n**2, 1))
                ],
                 [
                     spmatrix(
                         normal(nz * m, 1),
                         [i for j in xrange(m) for i in random.sample(Il, nz)],
                         [j for j in xrange(m) for i in xrange(nz)], (n**2, m))
                 ]])
        elif type(d) is list:
            if len(d) == m:
                nz = [min(max(1, int(round(v * N))), N) for v in d]
                nnz = sum(nz)
                A = sparse(
                    [[
                        spmatrix(normal(N, 1), Il, [0 for i in xrange(N)],
                                 (n**2, 1))
                    ],
                     [
                         spmatrix(normal(nnz, 1), [
                             i for j in xrange(m)
                             for i in random.sample(Il, nz[j])
                         ], [j for j in xrange(m) for i in xrange(nz[j])],
                                  (n**2, m))
                     ]])
        else:
            raise TypeError

        # compute A0
        u = +S0.V
        for k in xrange(m):
            base.gemv(A[:, k + 1][Il], matrix(y0[k]), u, beta=1.0, trans='N')
        A[Il, 0] = u
        self._A = A

        # compute b
        X0[Il[Id]] *= 0.5
        self._b = matrix(0., (m, 1))
        u = matrix(0.)
        for k in xrange(m):
            base.gemv(A[:, k + 1][Il], X0.V, u, trans='T', alpha=2.0)
            self._b[k] = u