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
,A22
usingscipy.sparse.diags
- And stack them together as
A = scipy.sparse.bmat([[A11, A12], [A21, A22]])
- (This also means that
A
is not symmetric, and hence some efficient translations intoQP
problems 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.LCP
crashes with my matrices, I assume it converts the matrices to dense before continuingcompecon-python
outright fails with some error, it apparently requires dense matrices and has no fallback for sparsityB
is 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). – hpauljLCP
methods I found atopenopt
appeared not to work - what exactly can I do withnonOptMisc
? – FooBar