def getMatrixForTest(): from cylp.py.utils.sparseUtil import csr_matrixPlus import numpy as np indptr = np.array([0, 2, 3, 6]) indices = np.array([0, 2, 2, 0, 1, 2]) data = np.array([1, 2, 3, 4, 5, 6]) return csr_matrixPlus((data, indices, indptr), shape=(3, 3))
def test(self): model = CyLPModel() x = model.addVariable('x', 3) A = np.matrix([[1, 2, 3], [1, 1, 1]]) b = CyLPArray([5, 3]) model.addConstraint(A * x == b) model.addConstraint(x >= 0) model.objective = 1 * x[0] + 1 * x[1] + 1.1 * x[2] # Solve it a first time s = CyClpSimplex(model) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1, 2, 0])) <= 10**-6).all()) # Add a cut s.addConstraint(x[0] >= 1.1) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1])) <= 10**-6).all()) # Change the objective function c = csr_matrixPlus([[1, 10, 1.1]]).T s.objective = c.T * x s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([2, 0, 1])) <= 10**-6).all())
def test(self): model = CyLPModel() x = model.addVariable('x', 3) A = np.matrix([[1,2,3], [1,1,1]]) b = CyLPArray([5, 3]) model.addConstraint(A * x == b) model.addConstraint(x >= 0) model.objective = 1*x[0] + 1*x[1] + 1.1 * x[2] # Solve it a first time s = CyClpSimplex(model) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1,2,0]) ) <= 10**-6).all()) # Add a cut s.addConstraint(x[0] >= 1.1) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1]) ) <= 10**-6).all()) # Change the objective function c = csr_matrixPlus([[1, 10, 1.1]]).T s.objective = c.T * x s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([2, 0, 1]) ) <= 10**-6).all())
def test2(self): 'Same as test1, but use cylp indirectly.' s = CyClpSimplex() x = s.addVariable('x', 3) A = np.matrix([[1, 2, 3], [1, 1, 1]]) b = CyLPArray([5, 3]) s += A * x == b s += x >= 0 s.objective = 1 * x[0] + 1 * x[1] + 1.1 * x[2] # Solve it a first time s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1, 2, 0])) <= 10**-6).all()) # Add a cut s.addConstraint(x[0] >= 1.1) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1])) <= 10**-6).all()) # Change the objective function c = csr_matrixPlus([[1, 10, 1.1]]).T s.objective = c.T * x s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([2, 0, 1])) <= 10**-6).all())
def test2(self): 'Same as test1, but use cylp indirectly.' s = CyClpSimplex() x = s.addVariable('x', 3) A = np.matrix([[1,2,3], [1,1,1]]) b = CyLPArray([5, 3]) s += A * x == b s += x >= 0 s.objective = 1 * x[0] + 1 * x[1] + 1.1 * x[2] # Solve it a first time s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1,2,0]) ) <= 10**-6).all()) # Add a cut s.addConstraint(x[0] >= 1.1) s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1]) ) <= 10**-6).all()) # Change the objective function c = csr_matrixPlus([[1, 10, 1.1]]).T s.objective = c.T * x s.primal() sol = s.primalVariableSolution['x'] self.assertTrue((abs(sol - np.array([2, 0, 1]) ) <= 10**-6).all())
def getQP(m, n): qp = QP() qp.G = csr_matrixPlus(generateRandomPositiveDefiniteMatrix(n, 10)) #getG(n) #qp.c = np.zeros(n) qp.c = np.random.random(n) * 50 qp.C = getA(m, n, 25) qp.c_low = np.ones(m) * -getCoinInfinity() qp.c_up = np.ones(m) # qp.c_low = -np.ones(m) # qp.c_up = np.ones(m) * getCoinInfinity() #qp.c_up = (20 + np.random.random(m) * 40) * 10**-3 qp.b = qp.A = 0 qp.nInEquality = m #qp.C =qp.c_low = qp.c_up = 0 #qp.A = getA(m, n, 17) #qp.b = np.ones(m) qp.nEquality = 0 qp.x_low = np.ones(n) * -getCoinInfinity() qp.x_up = np.ones(n) * getCoinInfinity() qp.n = n qp.nOriginalVar = n qp.objectiveOffset = 0 qp.filename = '/Users/mehdi/Desktop/qptest.txt' return qp
def A(self): a = sparse.lil_matrix((self.nRows, self.nCols)) for nCol in xrange(self.nCols): for nRow in self.cols[nCol]: a[nRow, nCol] = 1 return csr_matrixPlus(a)
def G(self): n = self.nCols ## qp = QP() ## qp.fromQps('/Users/mehdi/Documents/work/benchmarks/qp/CVXQP3_M.SIF') ## #mm = qp.G[:n, :n].todense() ## #print (mm == mm.T).all() ## #l = np.linalg.eigvals(mm) ## #print min(l) ## G = sparse.lil_matrix((2*n, 2*n)) #### G[n/2:n, n/2:n] = qp.G[n/2:n, n/2:n] #### k = 10 #### G[n-k:n, n-k:n] = qp.G[:k, :k] ## dim = min(qp.G.shape[0], n) ## G[:dim, :dim] = qp.G[:dim, :dim] ## if G[2*n-1, 2*n-1] == 0: ## G[2*n-1, 2*n-1] = 10**-10 ## return G #n *= 2 G = sparse.lil_matrix((2*n, 2*n)) for i in xrange(n/2, n): #xrange(n-1): G[i, i] = 1 #G[i+1, i] = -0.2 #G[i, i+1] = -0.2 #G[n - 1, n - 1] = 1 G[2*n-1, 2*n-1] = 10**-10 return csr_matrixPlus(G)
def readQPS(inputFilename): problem = CyCoinMpsIO() problem.readMps(inputFilename) n = problem.nVariables m = problem.nConstraints signs = problem.constraintSigns iEq = [i for i in range(len(signs)) if chr(signs[i]) == 'E'] numberOfEqualities = len(iEq) iInEq = [i for i in range(len(signs)) if i not in iEq] numberOfInequalities = len(iInEq) c = problem.matrixByRow el = c.elements col = c.indices start = c.vectorStarts coefs = csr_matrixPlus((el, col, start), shape=(m, n)) # an invalid value for initialization # This wont make any problems because we always # check number of equalties and # inequalities first, before accessing them A = C = b = c_up = c_low = 0 rhs = problem.rightHandSide if numberOfEqualities: A = csr_matrixPlus(coefs[iEq]) b = rhs[iEq] if numberOfInequalities: C = csr_matrixPlus(coefs[iInEq]) c_up = problem.constraintUpper[iInEq] c_low = problem.constraintLower[iInEq] Hessian = problem.Hessian x_low = problem.variableLower x_up = problem.variableUpper c = problem.objCoefficients return (Hessian, c, A, b, C, c_low, c_up, x_low, x_up, n, len(iEq), len(iInEq), problem.objectiveOffset)
def __getitem__(self, key): ret = sparse.csr_matrix.__getitem__(self, key) if isinstance(ret, (int, long, float)): return ret # This seems to cause some potential problems when the result is 1x1 # It should really be returned as an int/float in that case, but # this prevents it and causes behavior to be different than # sparse.csr_matrix return csr_matrixPlus(ret)
def addVariable(self, name, dim, isInt=False): ''' Create a new instance of :py:class:`CyLPVar` using the given arguments and add it to current model's variable list. ''' if dim == 0: return var = CyLPVar(name, dim, isInt) self.variables.append(var) #If mulidim, correct dim if isinstance(dim, tuple): dim = reduce(mul, dim) if not self.inds.hasVar(var.name): self.inds.addVar(var.name, dim) self.nVars += dim self.varNames.append(var.name) self.pvdims[var.name] = dim if var.dims: var.mpsNames = [var.name + '_' + '_'.join(x) for x in \ product(*[map(str, range(i)) for i in var.dims])] else: var.mpsNames = [ '%s_%s' % (var.name, i) for i in range(var.dim) ] o = self.objective_ if isinstance(o, np.ndarray): o = np.concatenate((o, np.zeros(dim)), axis=0) else: o = sparseConcat(o, csr_matrixPlus(np.zeros(dim)), 'h') # I'm not exactly sure why the objective gets changed into # csr_matrixPlus here when it may not be coming in. Shouldn't it # just always be? self.objective_ = csr_matrixPlus(o) else: raise Exception('Varaible %s already exists.' % var.name) return var
def generateVarObjCoef(self, varName): #dim = self.allParentVarDims[varName] dim = self.pvdims[varName] coef = csr_matrixPlus((1, dim)) obj = self.objective_ keys = [k for k in obj.varCoefs.keys() if k.name == varName] for var in keys: coef = coef + obj.varCoefs[var] return coef
def test_constraint_single3(self): model = self.model x = self.x k = csr_matrixPlus([[3.1], [4.2]]) model.addConstraint(-x[0] + -3 * x[1] + k.T * x[1:3] >= 4.5) cons = model.constraints[0] m, cl, cu, vl, vu = model.makeMatrices() self.assertTrue((abs(m.todense() - np.array([-1, 0.1, 4.2, 0, 0])) < 0.000001).all())
def getG(nCols): n = nCols G = sparse.lil_matrix((n, n)) for i in range(0, n - 1): G[i, i] = 1 #G[i+1, i] = -0.2 #G[i, i+1] = -0.2 G[nCols - 1, nCols - 1] = 1 return csr_matrixPlus(G)
def test_constraint_single3(self): model = self.model x = self.x k = csr_matrixPlus([[3.1], [4.2]]) model.addConstraint(-x[0] + -3 * x[1] + k.T * x[1:3] >= 4.5) cons = model.constraints[0] m, cl, cu, vl, vu = model.makeMatrices() self.assertTrue((abs(m.todense()-np.array( [-1, 0.1, 4.2, 0, 0])) < 0.000001).all())
def removeVariable(self, name): ''' Remove a variable named ``name`` from the model ''' if not self.inds.hasVar(name): raise Exception('Variable "%s" does not exist.' % name) self.nVars -= self.pvdims[name] start = self.inds.varIndex[name][0] end = start + self.pvdims[name] o = self.objective_ if isinstance(o, np.ndarray): o = np.concatenate((o[:start], o[end:]), axis=0) else: if end == o.shape[1]: if start == 0: print('Problem empty.') else: o = o[0, :start] elif start == 0: o = o[0, end:] else: o = sparseConcat(o[0, :start], o[0, end:], how='h') # I'm not exactly sure why the objective gets changed into # csr_matrixPlus here when it may not be coming in. Shouldn't it # just always be? self.objective_ = csr_matrixPlus(o) del self.pvdims[name] self.varNames.remove(name) self.inds.removeVar(name) for i in range(len(self.variables)): var = self.variables[i] if var.name == name: del self.variables[i] break #Removing the variable from the constraints cons = self.constraints for c in cons: if name in c.varNames: c.varNames.remove(name) del c.parentVarDims[name] for v in list(c.varCoefs.keys()): if v.name == name: del c.varCoefs[v] for c in cons[:]: self.inds if not c.varCoefs: self.removeConstraint(c.name)
def addVariable(self, name, dim, isInt=False): ''' Create a new instance of :py:class:`CyLPVar` using the given arguments and add it to current model's variable list. ''' if dim == 0: return var = CyLPVar(name, dim, isInt) self.variables.append(var) #If mulidim, correct dim if isinstance(dim, tuple): dim = reduce(mul, dim) if not self.inds.hasVar(var.name): self.inds.addVar(var.name, dim) self.nVars += dim self.varNames.append(var.name) self.pvdims[var.name] = dim if var.dims: var.mpsNames = [var.name + '_' + '_'.join(x) for x in \ product(*[map(str, range(i)) for i in var.dims])] else: var.mpsNames = ['%s_%s' % (var.name, i) for i in xrange(var.dim)] o = self.objective_ if isinstance(o, np.ndarray): o = np.concatenate((o, np.zeros(dim)), axis=0) else: o = sparseConcat(o, csr_matrixPlus(np.zeros(dim)), 'h') self.objective_ = csr_matrixPlus(o) else: raise Exception('Varaible %s already exists.' % var.name) return var
def removeVariable(self, name): ''' Remove a variable named ``name`` from the model ''' if not self.inds.hasVar(name): raise Exception('Variable "%s" does not exist.' % name) self.nVars -= self.pvdims[name] start = self.inds.varIndex[name][0] end = start + self.pvdims[name] o = self.objective_ if isinstance(o, np.ndarray): o = np.concatenate((o[:start], o[end:]), axis=0) else: if end == o.shape[1]: if start == 0: print 'Problem empty.' else: o = o[0, :start] elif start == 0: o = o[0, end:] else: o = sparseConcat(o[0, :start], o[0, end:], how='h') self.objective_ = csr_matrixPlus(o) del self.pvdims[name] self.varNames.remove(name) self.inds.removeVar(name) for i in range(len(self.variables)): var = self.variables[i] if var.name == name: del self.variables[i] break #Removing the variable from the constraints cons = self.constraints for c in cons: if name in c.varNames: c.varNames.remove(name) del c.parentVarDims[name] for v in c.varCoefs.keys(): if v.name == name: del c.varCoefs[v] for c in cons[:]: self.inds if not c.varCoefs: self.removeConstraint(c.name)
def getA(nRows, nCols, nnzPerCol): '''Return a sparse coef. matrix of a set-partitioning problem *nnzPerCol* specifies the number of non-zero elements in each column. ''' A = sparse.lil_matrix((nRows, nCols)) solCols = [] for nRow in range(nRows): nCol = random.randint(0, nCols - 1) A[nRow, nCol] = 1 solCols.append(nCol) for nCol in [j for j in range(nCols) if j not in solCols]: for i in range(nnzPerCol): #if random.randint(0, 1): A[random.randint(0, nRows - 1), nCol] = 1 #else: # A[random.randint(0, nRows-1), nCol] = -1 return csr_matrixPlus(A)
def __getitem__(self, key): ret = sparse.csr_matrix.__getitem__(self, key) if isinstance(ret, (int, long, float)): return ret return csr_matrixPlus(ret)
def T(self): return csr_matrixPlus(sparse.csc_matrix.transpose(self))
def sparseConcat(a, b, how, v_offset=0, h_offset=0): ''' Concatenate two sparse matrices, ``a`` and ``b``, horizontally if ``how = 'h'``, and vertically if ``how = 'v'``. Add zero rows and columns if dimensions don't align. ``v_offset`` specifies how to align ``b`` along side ``a``. The value of ``v_offset`` will be added to each row index of ``b``. ``v_offset=-1`` means that we want the greatest possible offset without changeing the dimensions. ``h_offset`` is a similar argument but to specify horizontal offset. **Usage** >>> from scipy import sparse >>> from cylp.py.utils.sparseUtil import sparseConcat, csc_matrixPlus >>> s1 = csc_matrixPlus.getMatrixForTest() >>> s2 = sparse.lil_matrix([[1,0,2],[0,5,0]]) >>> sparseConcat(s1, s2, 'v').todense() matrix([[1, 0, 4], [0, 0, 5], [2, 3, 6], [1, 0, 2], [0, 5, 0]]) >>> sparseConcat(s1, s2, 'h').todense() matrix([[1, 0, 4, 1, 0, 2], [0, 0, 5, 0, 5, 0], [2, 3, 6, 0, 0, 0]]) If ``a = None`` then return ``b``. This makes possible an incremental construction of large sparse matrices from scratch without the hassle of the initial value check. >>> s3 = None >>> ((sparseConcat(s3, s1, 'h').todense() == s1.todense()).all() and ... (sparseConcat(s3, s1, 'v').todense() == s1.todense()).all()) True ''' if a == None: if b == None: return None return csr_matrixPlus(b) if b == None: return csr_matrixPlus(a) assert(h_offset >= -1 and v_offset >= -1) a = sparse.coo_matrix(a) b = sparse.coo_matrix(b) if how == 'h': if v_offset == -1: assert(a.shape[0] > b.shape[0]) v_offset = a.shape[0] - b.shape[0] assert(h_offset >= 0) row = np.concatenate((a.row, b.row + v_offset), axis=0) col = np.concatenate((a.col, b.col + (a.shape[1] + h_offset)), axis=0) data = np.concatenate((a.data, b.data), axis=0) nRows = max(a.shape[0], b.shape[0] + v_offset) nCols = a.shape[1] + b.shape[1] + h_offset a = csr_matrixPlus((data, (row, col)), shape=(nRows, nCols)) elif how == 'v': if h_offset == -1: assert(a.shape[1] > b.shape[1]) h_offset = a.shape[1] - b.shape[1] assert(v_offset >= 0) row = np.concatenate((a.row, b.row + (a.shape[0] + v_offset)), axis=0) col = np.concatenate((a.col, b.col + h_offset), axis=0) data = np.concatenate((a.data, b.data), axis=0) nCols = max(a.shape[1], b.shape[1] + h_offset) nRows = a.shape[0] + b.shape[0] + v_offset a = csr_matrixPlus((data, (row, col)), shape=(nRows, nCols)) return a
def __setitem__(self, location, val): ''' Sets the item in row ``i`` and col ``j`` to ``val``. Increases matrix's ``shape[1]`` if necessary **Usage** >>> from cylp.py.utils.sparseUtil import csr_matrixPlus >>> import numpy as np >>> indptr = np.array([0, 2, 3, 6]) >>> indices = np.array([0, 2, 2, 0, 1, 2]) >>> data = np.array([1, 2, 3, 4, 5, 6]) >>> s = csr_matrixPlus((data, indices, indptr), shape=(3, 3)) >>> s[5,2] = 11 >>> print(s.todense()) [[ 1 0 2] [ 0 0 3] [ 4 5 6] [ 0 0 0] [ 0 0 0] [ 0 0 11]] ''' iRow, iCol = location if not isinstance(val, (int, long, float)): return sparse.csr_matrix.__setitem__(self, (iRow, iCol), val) nRows = self.shape[0] nCols = self.shape[1] l = self.tolil() if iCol >= nCols: l._shape = (nRows, iCol + 1) nCols = iCol + 1 if iRow >= nRows: l._shape = (iRow + 1, nCols) nRowsToAdd = iRow + 1 - nRows l_temp = sparse.lil_matrix((nRowsToAdd, 1)) l.data = np.concatenate((l.data, l_temp.data)) l.rows = np.concatenate((l.rows, l_temp.rows)) l[iRow, iCol] = val s = csr_matrixPlus(l) self._nnz = s.nnz self._shape = s._shape self.indices = s.indices self.indptr = s.indptr self.data = s.data self.has_sorted_indices = s.has_sorted_indices return nRows = self.shape[0] if iCol >= self.shape[1]: self._shape = (self.shape[0], iCol + 1) if iRow < nRows: for i in range(self.indptr[iRow], self.indptr[iRow + 1]): if self.indices[i] == iCol: self.data[i] = val return #if we reach here it means that index does NOT exist for i in range(iRow + 1, nRows + 1): self.indptr[i] += 1 indexOfElement = self.indptr[iRow + 1] - 1 # If indices is empty if indexOfElement == 0: self.indices = np.array([iCol], dtype=np.int32) self.data = np.array([val]) else: self.indices = np.concatenate( (self.indices[:indexOfElement], np.array([iCol], dtype=np.int32), self.indices[indexOfElement:]), axis=0) self.data = np.concatenate( (self.data[:indexOfElement], np.array( [val]), self.data[indexOfElement:]), axis=0) else: #We don't have enough columns, increase dimension 1 self.addRows(iRow - nRows + 1) self.indptr[iRow + 1] += 1 self.indices = np.concatenate( (self.indices, np.array([iCol], dtype=np.int32)), axis=0) self.data = np.concatenate( (self.data, np.array([val], dtype=np.int32)), axis=0) self._shape = (iRow + 1, self._shape[1])
def sparseConcat(a, b, how, v_offset=0, h_offset=0): ''' Concatenate two sparse matrices, ``a`` and ``b``, horizontally if ``how = 'h'``, and vertically if ``how = 'v'``. Add zero rows and columns if dimensions don't align. ``v_offset`` specifies how to align ``b`` along side ``a``. The value of ``v_offset`` will be added to each row index of ``b``. ``v_offset=-1`` means that we want the greatest possible offset without changeing the dimensions. ``h_offset`` is a similar argument but to specify horizontal offset. **Usage** >>> from scipy import sparse >>> from cylp.py.utils.sparseUtil import sparseConcat, csc_matrixPlus >>> s1 = csc_matrixPlus.getMatrixForTest() >>> s2 = sparse.lil_matrix([[1,0,2],[0,5,0]]) >>> sparseConcat(s1, s2, 'v').todense() matrix([[1, 0, 4], [0, 0, 5], [2, 3, 6], [1, 0, 2], [0, 5, 0]]) >>> sparseConcat(s1, s2, 'h').todense() matrix([[1, 0, 4, 1, 0, 2], [0, 0, 5, 0, 5, 0], [2, 3, 6, 0, 0, 0]]) If ``a = None`` then return ``b``. This makes possible an incremental construction of large sparse matrices from scratch without the hassle of the initial value check. >>> s3 = None >>> ((sparseConcat(s3, s1, 'h').todense() == s1.todense()).all() and ... (sparseConcat(s3, s1, 'v').todense() == s1.todense()).all()) True ''' if a is None: if b is None: return None return csr_matrixPlus(b) if b is None: return csr_matrixPlus(a) assert (h_offset >= -1 and v_offset >= -1) a = sparse.coo_matrix(a) b = sparse.coo_matrix(b) if how == 'h': if v_offset == -1: assert (a.shape[0] > b.shape[0]) v_offset = a.shape[0] - b.shape[0] assert (h_offset >= 0) row = np.concatenate((a.row, b.row + v_offset), axis=0) col = np.concatenate((a.col, b.col + (a.shape[1] + h_offset)), axis=0) data = np.concatenate((a.data, b.data), axis=0) nRows = max(a.shape[0], b.shape[0] + v_offset) nCols = a.shape[1] + b.shape[1] + h_offset a = csr_matrixPlus((data, (row, col)), shape=(nRows, nCols)) elif how == 'v': if h_offset == -1: assert (a.shape[1] > b.shape[1]) h_offset = a.shape[1] - b.shape[1] assert (v_offset >= 0) row = np.concatenate((a.row, b.row + (a.shape[0] + v_offset)), axis=0) col = np.concatenate((a.col, b.col + h_offset), axis=0) data = np.concatenate((a.data, b.data), axis=0) nCols = max(a.shape[1], b.shape[1] + h_offset) nRows = a.shape[0] + b.shape[0] + v_offset a = csr_matrixPlus((data, (row, col)), shape=(nRows, nCols)) return a