CyLP icon indicating copy to clipboard operation
CyLP copied to clipboard

Use of numpy.matrix not recommended

Open akeeman opened this issue 4 years ago • 9 comments

The use of numpy.matrix is discuraged since numpy 1.15

From the docs(1.15 / stable):

Note It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future.

Using regular arrays gives some problems, like in the first example:

import numpy as np
from cylp.cy import CyClpSimplex
from cylp.py.modeling.CyLPModel import CyLPArray

s = CyClpSimplex()

# Add variables
x = s.addVariable('x', (3, 1))  # should be 2-d now
y = s.addVariable('y', (2, 1))  # should be 2-d now

# Create coefficients and bounds
A = np.array([[1., 2., 0], [1., 0, 1.]])  # use array
B = np.array([[1., 0, 0], [0, 0, 1.]])  # use array
D = np.array([[1., 2.], [0, 1]])  # use array
a = CyLPArray([5, 2.5])
b = CyLPArray([4.2, 3])
x_u = CyLPArray([2., 3.5])

# Add constraints
s += A @ x <= a  # use matmul operator
s += 2 <= B @ x + D @ y <= b  # use matmul operator
s += y >= 0
s += 1.1 <= x[1:3] <= x_u

# Set the objective function
c = CyLPArray([1., -2., 3.])
s.objective = c @ x + 2 * y.sum()  # use matmul operator

# Solve using primal Simplex
s.primal()
print(s.primalVariableSolution['x'])
Traceback (most recent call last):
  File "/path/to/example.py", line 20, in <module>
    s += A @ x <= a
ValueError: matmul: Input operand 1 does not have enough dimensions (has 0, gufunc core with signature (n?,k),(k,m?)->(n?,m?) requires 1)

Process finished with exit code 1

akeeman avatar May 01 '20 07:05 akeeman

Ah, OK, I did not realize this. It seems to me that using the matmul operator is probably not going to work in any case, since this operation is not defined for the classes within CyLP. Do you have the same issue if you use the regular mul operator?

tkralphs avatar May 01 '20 15:05 tkralphs

Hmm, using the mul operator also gives an error, but a different one. It's not exactly clear to me what's going on. It doesn't appear that np.matrix is actually being used anywhere underneath, just in the example, to construct the matrix. The matrices are stored internally using scipy's sparse matrix classes. Somehow, there is a shape mismatch.

tkralphs avatar May 01 '20 20:05 tkralphs

Has anyone been able to find a workaround for this issue?

GalPerelman avatar Feb 17 '21 11:02 GalPerelman

I found that np.asmatrix solves the problem As simple as: A = np.asmatrix([[1., 2., 0],[1., 0, 1.]])

The NumPy documentation does not contain the warning about future use: https://numpy.org/doc/stable/reference/generated/numpy.asmatrix.html

GalPerelman avatar Feb 17 '21 13:02 GalPerelman

That should not be the case as you still work with the matrix class, while you are encouraged not to, as the class may be removed in the future:

It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future.

I so guess the documentation could be improved.

From the source:

@set_module('numpy')
def asmatrix(data, dtype=None):
   """
   <docs left out for brevity>
   """
   return matrix(data, dtype=dtype, copy=False)

akeeman avatar Feb 17 '21 14:02 akeeman

@akeeman you are absolutely right I should have had to check it out myself

GalPerelman avatar Feb 17 '21 14:02 GalPerelman

Sorry, haven't had a chance to dig into this.

tkralphs avatar Feb 22 '21 02:02 tkralphs

For future similar questions, I'm using this workaround:

from scipy import sparse
A= sparse.csr_matrix(A)

GalPerelman avatar Oct 15 '21 11:10 GalPerelman

This sounds like it should be the right thing to do.

tkralphs avatar Oct 17 '21 15:10 tkralphs