EDWhyte
EDWhyte

Reputation: 351

Write a sympy matrix to a python file

I have a script that automatically generates equations and adds them to a list.

e.g. :

eq = [a*b, a + b*c -d, c**2 + a, d*a - 2]

with a, b, c, d all sympy symbols.

It then converts the list to a sympy matrix and calculates the jacobian matrix

eq = sympy.Matrix(eq)
jacobi = eq.jacobian([a, b, c, d])

I want to save this jacobian in a python file in order for me to use it in another python script.

Currently I create a definition using a list of strings and write it to a python file

variable_list = [a, b, c, d]

jacobian_lines = ["def jacobian(variables):",
                           '    """ Returns the evaluated jacobian matrix',
                           '    :param variables: a list of numeric values to evaluate the jacobian',
                           '    """', '', '    {} = variables'.format(str(variable_list)), '',
                           '    j = {}'.format(jacobi), '', "    return j"]

file_path = 'jacobian.py'
file = open(file_path, 'w')

for line in jacobian_lines:
    file.write('{}\n'.format(line))

Is there a more correct/better way to do this?

Upvotes: 1

Views: 1739

Answers (2)

Chris Wells Wood
Chris Wells Wood

Reputation: 21

Not sure if you've came across this before but you can write arbitrary Python objects to a file using the pickle module from the standard library. This would allow you to do the following to save the jacobian:

import pickle
import sympy

a = sympy.symbols('a')
b = sympy.symbols('b')
c = sympy.symbols('c')
d = sympy.symbols('d')

eq = [a*b, a + b*c -d, c**2 + a, d*a - 2]
eq = sympy.Matrix(eq)
jacobi = eq.jacobian([a, b, c, d])

with open('~/Desktop/jacobian.pickle', 'wb') as outf:
    outf.write(pickle.dumps(jacobi))

Then when you want to load it in your other script you can load that jacobian back into memory like this:

import pickle
import sympy

with open('~/Desktop/jacobian.pickle', 'rb') as inf:    
   jacobi = pickle.loads(inf.read())
print(jacobi)

Outputs:

Matrix([
[b, a,   0,  0],
[1, c,   b, -1],
[1, 0, 2*c,  0],
[d, 0,   0,  a]])

Upvotes: 2

Ishaq Khan
Ishaq Khan

Reputation: 173

I can make your code little simple

The job can be done without 'for loop':

variable_list = [a, b, c, d]

jacobian_lines = ["def jacobian(variables):",
                           '    """ Returns the evaluated jacobian matrix',
                           '    :param variables: a list of numeric values to evaluate the jacobian',
                           '    """', '', '    {} = variables'.format(str(variable_list)), '',
                           '    j = {}'.format(jacobi), '', "    return j"]

file_path = 'jacobian.py'
file = open(file_path, 'w').write('\n'.join(jacobian_lines))

Upvotes: 1

Related Questions