47

I want to solve a linear equation with three or more variables. Is there a good library in python to do it?

Jason Sundram
  • 12,225
  • 19
  • 71
  • 86
station
  • 6,715
  • 14
  • 55
  • 89

6 Answers6

70

Yes, the very-popular NumPy package has a function to do this. Their example:

Solve the system of equations 3 * x0 + x1 = 9 and x0 + 2 * x1 = 8:

>>> import numpy as np
>>> a = np.array([[3,1], [1,2]])
>>> b = np.array([9,8])
>>> x = np.linalg.solve(a, b)
>>> x
array([ 2.,  3.]) 

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.linalg.solve.html

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Jeremy
  • 1
  • 85
  • 340
  • 366
  • 2
    Can I use the np.linalg.solve(a, b) function to solve system of equations modulo 2 (over the Galois Field)? Or if you know another package which would solve that problem it would be really helpful :) – giliev Dec 12 '15 at 19:26
  • 4
    numpy's "solve" will not solve systems of equations with more equations than variables (my use-case). For that, use sympy instead. – Bitcoin Cash - ADA enthusiast May 26 '17 at 06:19
32

See http://sympy.org/ and Link.

Specifically, http://docs.scipy.org/doc/numpy/reference/routines.linalg.html

And http://docs.sympy.org/0.7.0/tutorial.html#algebra, http://docs.sympy.org/dev/modules/solvers/solvers.html

Edit: Added solvers link from the comment.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
agf
  • 171,228
  • 44
  • 289
  • 238
9

You can use least square method in python to solve system of equations for example for solving equations 3x+4y=7 and 5x+6y=8

>>> import numpy
>>> a=[[3,4],[5,6]]
>>> b=[7,8]
>>> numpy.linalg.lstsq(a,b)
(array([-5. ,  5.5]), array([], dtype=float64), 2, array([ 9.27110906,  0.21572392]))
Andro Selva
  • 53,910
  • 52
  • 193
  • 240
004
  • 89
  • 1
  • 4
7

Using @Jeremy's example:

from sympy import *
x0, x1 = symbols(['x0', 'x1'])
sol = solve([3 * x0 + x1 - 9, x0 + 2 * x1 - 8], [x0, x1])
print(sol)

output:

{x0: 2, x1: 3}

Using @004 example with slightly different notation:

from sympy import *
x, y = symbols(['x', 'y'])
system = [
    Eq(3*x + 4*y, 7),
    Eq(5*x + 6*y, 8)
]
soln = solve(system, [x, y])
print(soln)

{x: -5, y: 11/2}

Note: Sometimes one may see the following notation for symbols: x, y = symbols('x, y'), which seems to be less pythonic.

garej
  • 508
  • 1
  • 8
  • 24
2

You can write a simple function which solves a system of linear equations.

def solve(equations):
     #the constants of a system of linear equations are stored in a list for each equation in the system
     """
     for example the system below:
          2x+9y-3z+7w+8=0
          7x-2y+6z-1w-10=0
          -8x-3y+2z+5w+4=0
          0x+2y+z+w+0=0
     is expressed as the list:
          [[2,9,-3,7,8],[7,-2,6,-1,-10],[-8,-3,2,5,4],[0,2,1,1,0]]
     """
     lists=[] # I failed to name it meaningfully
     for eq in range(len(equations)):
          #print "equations 1", equations
          #find an equation whose first element is not zero and call it index
          index=0
          for i in range(len(equations)):
               if equations[i][0]<>0:
                    index=i;
                    break;
          #print "index "+str(eq)+": ",index
          #for the equation[index] calc the lists next itam  as follows
          lists.append([-1.0*i/equations[index][0] for i in equations[index][1:]])
          #print "list"+str(eq)+": ", lists[-1]
          #remve equation[index] and modify the others
          equations.pop(index)
          for i in equations:
               for j in range(len(lists[-1])):
                    i[j+1]+=i[0]*lists[-1][j]
               i.pop(0)

     lists.reverse()

     answers=[lists[0][0]]
     for i in range(1,len(lists)):
          tmpans=lists[i][-1]
          for j in range(len(lists[i])-1):
               tmpans+=lists[i][j]*answers[-1-j]
          answers.append(tmpans)
     answers.reverse()
     return answers
user2653663
  • 2,818
  • 1
  • 18
  • 22
0

You can also add constrains (upper bound and lower bound) on x with lsq_linear: scipy.optimize.lsq_linear