16

I need to solve a set of simultaneous equations of the form Ax = B for x. I've used the numpy.linalg.solve function, inputting A and B, but I get the error

LinAlgError: Last 2 dimensions of the array must be square

Here's my code:

A = numpy.matrix([(-0.56, -0.52), (0.44, 0.46), (0.69, 0.71)])
B = [(-0.38, -24.09, 0.0)]
x = numpy.linalg.solve(A, B)

x should have the form (x1,x2,0).

How do I fix this?

cottontail
  • 10,268
  • 18
  • 50
  • 51
K Jackson
  • 161
  • 1
  • 1
  • 5
  • Please add your code to the question - we can't see how you're calling `numpy.linalg.solve` – Avery Feb 21 '18 at 15:30
  • 1
    Your `A` matrix is (3,2) shape. That's not a square matrix (equal number of rows and columns). `solve` is not meant for over or under determined linear equations. – hpaulj Feb 21 '18 at 17:15
  • `x should have the form (x1,x2,0)` no, if anything x shoud be of length 2, not 3. – P. Camilleri Feb 21 '18 at 17:29

3 Answers3

28

In case you still haven't found an answer, or in case someone in the future has this question.

To solve Ax=b:

numpy.linalg.solve uses LAPACK gesv. As mentioned in the documentation of LAPACK, gesv requires A to be square:

LA_GESV computes the solution to a real or complex linear system of equations AX = B, where A is a square matrix and X and B are rectangular matrices or vectors. Gaussian elimination with row interchanges is used to factor A as A = PL*U , where P is a permutation matrix, L is unit lower triangular, and U is upper triangular. The factored form of A is then used to solve the above system.

If A matrix is not square, it means that you either have more variables than your equations or the other way around. In these situations, you can have the cases of no solution or infinite number of solutions. What determines the solution space is the rank of the matrix compared to the number of columns. Therefore, you first have to check the rank of the matrix.

That being said, you can use another method to solve your system of linear equations. I suggest having a look at factorization methods like LU or QR or even SVD. In LAPACK you can use getrs, in Python you can different things:

  • first do the factorization like QR and then feed the resulting matrices to a method like scipy.linalg.solve_triangular
  • solve the least-squares using numpy.linalg.lstsq

Also have a look here where a simple example is formulated and solved.

Keivan
  • 673
  • 7
  • 15
  • 1
    To be fair even if A is square there are cases where there are no solutions. For instance, `[ 1 0 ; 0 0 ] x = [ 0 ; 1 ]`. Personally, I think my solution to this issue will be to use np.linalg.pinv and numpy.matmul to calculate a least squares soln (which is equal to the soln if one exists). – Samie Bencherif Nov 21 '20 at 19:47
3

A square matrix is a matrix with the same number of rows and columns. The matrix you are doing is a 3 by 2. Add a column of zeroes to fix this problem.

ashish trehan
  • 413
  • 1
  • 5
  • 9
  • 4
    I tried doing this, and ended up with the error 'LinAlgError: Singular matrix'? – K Jackson Feb 21 '18 at 17:29
  • Yes I know what a singular matrix is, and I know that I shouldn't be getting one as the calculation works in LabView, but I don't understand why it doesn't work in python. – K Jackson Feb 22 '18 at 15:07
  • Actually what ashish trehan said is correct. This should be the the accepted answer, because *your matrix is singular*. You can easily verify this, by verifying that the 2x2 by matrix already has full rank: `numpy.linalg.matrix_rank(numpy.matrix([(-0.56, -0.52), (0.44, 0.46)])) == 2`. Since the matrix already has full rank with 2 vectors adding a third vector means that you are adding a linearly dependent vector, which means there are infinite solutions, which means your matrix is singular. Whatever you did in LabView is either incorrect or you've misinterpreted the result. – Lodewijk Bogaards Jul 31 '23 at 11:47
0

Another common way this error may occur is when an operation that was intended to be performed element-wise is called on a numpy.matrix() object. The following example reproduces this error. In this case, arr is a numpy ndarray, while mat is a numpy matrix object. As you can see, element-wise squaring works for arr but it doesn't work for mat because **2 is a matrix square which is equivalent to dot product. To get around the issue, convert the matrix to ndarray.

import numpy as np
arr = np.array([[1,2]])
mat = np.matrix([[1,2]])

x1 = arr**2             # array([[1, 4]])
y1 = mat**2             # LinAlgError: Last 2 dimensions of the array must be square
y2 = np.array(mat)**2   # array([[1, 4]])
cottontail
  • 10,268
  • 18
  • 50
  • 51