Search code examples
pythonscipysympy

How to solve a system of matrices with SymPy


import sys 
import os 
sys.path.append(os.getcwd())
import sympy as sp 
import numpy as np 
from includes.Truss import Truss 

U = sp.Matrix([[0,0],[0,10]])

boundary_conditions=[]
boundary_conditions.append([0])
boundary_conditions.append([''])

truss = Truss(U,boundary_conditions,30000000,2.0,10.0,2)
ke = truss.ke(10.0)

f = sp.Matrix([[0,-100.0]])

u = np.linalg.solve(ke,f)

ux = u[0]
uy = u[1]

print(f'ux = {ux}, uy = {uy}')

I have a 2x2 SymPy matrix ke. I need to solve the system keu=f (f is given...). u is a placeholder for ux and uy which are the unknown displacement quantities to solve for. I have at this point tried all different ways and couldn't yet solve for ux,uy of keu=f. Currently the problem is:

Traceback (most recent call last):
  File "c:\Users\famatto\OneDrive\Documents\birnic\test\trussexample002.py", line 19, in <module>  
    u = np.linalg.solve(ke,f)
        ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\famatto\OneDrive\Documents\birnic\.venv\Lib\site-packages\numpy\linalg\linalg.py", line 409, in solve
    r = gufunc(a, b, signature=signature, extobj=extobj)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
numpy.core._exceptions._UFuncInputCastingError: Cannot cast ufunc 'solve' input 0 from dtype('O') to dtype('float64') with casting rule 'same_kind'
PS C:\Users\famatto\OneDrive\Documents\birnic> 

Is there a way to get a solution for ux,uy to come out of python either with SymPy, numpy or really any way possible is OK with me. I would really like to see the floating point values for ux and uy start to come out....

This is what ke looks like:

Matrix([[5000000.00000000, -5000000.00000000], [-5000000.00000000, 5000000.00000000]])

So far my attempts to use:

u = ke.solve(f) 

have led to:

Traceback (most recent call last):
  File "c:\Users\famatto\OneDrive\Documents\birnic\test\trussexample003.py", line 26, in <module>  
    u = ke.solve(f)
        ^^^^^^^^^^^
  File "C:\Users\famatto\OneDrive\Documents\birnic\.venv\Lib\site-packages\sympy\matrices\matrices.py", line 2144, in solve
    return _solve(self, rhs, method=method)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\famatto\OneDrive\Documents\birnic\.venv\Lib\site-packages\sympy\matrices\solvers.py", line 758, in _solve
    raise NonInvertibleMatrixError("Matrix det == 0; not invertible.")
sympy.matrices.common.NonInvertibleMatrixError: Matrix det == 0; not invertible.
PS C:\Users\famatto\OneDrive\Documents\birnic>

Solution

  • As mentioned in the comments, you should not mix symbolic libraries, such as sympy, with numerical libraries, such as numpy as scipy, since their datatypes are incompatible. (The only time you'd really switch over is when you make the intentional transition from symbolic to numerical, such as when using sympy.lambdify.)

    Since you have sympy matrices for ke and f you can solve the system as per the documentation:

    u = ke.solve(f)
    

    I'm not sure if the last matrix in your question is the ke matrix, but if it is then you won't be able to solve this problem because the determinant of that matrix is 0. But that is a linear algebra problem, not a sympy problem.