I indicate matrices by capital letters, and vectors by small letters.
I need to solve the following system of linear inequalities for vector v:
min(rv - (u + Av), v - s) = 0
where 0 is a vector of zeros.
where r is a scalar, u and s are vectors, and A is a matrix.
Defining z = v-s, B=rI - A, q=-u + Bs, I can rewrite the previous problem as a linear complementarity problem and hope to use an LCP solver, for example from openopt:
LCP(M, z): min(Bz+q, z) = 0
or, in matrix notation:
z'(Bz+q) = 0
z >= 0
Bz + q >= 0
The problem is that my system of equations is huge. To create A, I
- Create four matrices
A11,A12,A21,A22usingscipy.sparse.diags - And stack them together as
A = scipy.sparse.bmat([[A11, A12], [A21, A22]]) - (This also means that
Ais not symmetric, and hence some efficient translations intoQPproblems won't work)
openopt.LCP apparently cannot deal with sparse matrices: When I ran this, my computer crashed. Generally, A.todense() will lead to a memory error. Similarly, compecon-python is not able to solve LCP problems with sparse matrices.
What alternative LCP implementations are fit for this problem?
I really did not think sample data was required for a general "which tools to solve LCP" question were required, but anyways, here we go
from numpy.random import rand
from scipy import sparse
n = 3000
r = 0.03
A = sparse.diags([-rand(n)], [0])
s = rand(n,).reshape((-1, 1))
u = rand(n,).reshape((-1, 1))
B = sparse.eye(n)*r - A
q = -u + B.dot(s)
q.shape
Out[37]: (3000, 1)
B
Out[38]:
<3000x3000 sparse matrix of type '<class 'numpy.float64'>'
with 3000 stored elements in Compressed Sparse Row format>
Some more pointers:
openopt.LCPcrashes with my matrices, I assume it converts the matrices to dense before continuingcompecon-pythonoutright fails with some error, it apparently requires dense matrices and has no fallback for sparsityBis not positive semi-definite, so I cannot rephrase the linear complementarity problem (LCP) as a convex quadratic problem (QP)- All QP sparse solvers from this exposition require the problem to be convex, which mine is not
- In Julia, PATHSolver can solve my problem (given a license). However, there are problems calling it from Python with PyJulia (my issue report here)
- Also Matlab has an LCP solver that apparently can handle sparse matrices, but there implementation is even more wacky (and I really do not want to fallback on Matlab for this)
scipy.sparse. They are built around the idea of linear operator, something with a matrix vector product,A*v. Anything that assumes more about the matrix is likely to have problems with a sparse matrix. It has to explicitly say it works withscipy.sparse(and which format). - hpauljLCPmethods I found atopenoptappeared not to work - what exactly can I do withnonOptMisc? - FooBar