Search code examples
pythonsympytaylor-series

Taylor expansion of matrix-valued function with sympy


I am currently trying to represent symbolically the truncated Taylor expansion of the matrix-exponential function. To do so, I am using Python along with the sympy library.

My code looks like

import sympy as sy

def taylor_exponential(x: sy.Symbol, order: int):
    res = sy.Integer(1)
    for k in range(1, order):
        res += (x ** k) / sy.factorial(k)
    return res
    # return sy.series(sy.exp(x), x, n=order)

n = sy.symbols("n")
lambd = sy.symbols("lambda")
H0 = sy.MatrixSymbol("H_0", n, n)

print(taylor_exponential(H0 * lambd, 2))

and the following exception is raised before the end of the code:

Traceback (most recent call last):
  File "mwe.py", line 14, in <module>
    H0 = sy.MatrixSymbol("H_0", n, n)
  File "mwe.py", line 6, in taylor_exponential
    for k in range(1, order):
  File "[path]/lib64/python3.6/site-packages/sympy/core/numbers.py", line 2088, in __add__
    return Rational.__add__(self, other)
# [ More lines of errors ]
  File "[path]/lib64/python3.6/site-packages/sympy/matrices/expressions/matexpr.py", line 95, in __radd__
    return MatAdd(other, self).doit()
  File "[path]/lib64/python3.6/site-packages/sympy/matrices/expressions/matadd.py", line 36, in __new__
    validate(*args)
  File "[path]/lib64/python3.6/site-packages/sympy/matrices/expressions/matadd.py", line 67, in validate
    raise TypeError("Mix of Matrix and Scalar symbols")
TypeError: Mix of Matrix and Scalar symbols

After some researches, I found a code online that works as expected and that seems to also use a mix of Matrix and Scalar symbols (source):

from sympy import *

A = MatrixSymbol("A", 3, 3)
x = MatrixSymbol("x", 3, 1)
dt = symbols("dt")
k1 = A * x
k2 = A * (x + S(1) / 2 * k1 * dt)
k3 = A * (x + S(1) / 2 * k2 * dt)
k4 = A * (x + k3 * dt)
final = dt * S(1) / 6 * (k1 + k2 + k3 + k4)  # a matrix expression
ex = Matrix(final)  # an explicit representation of expressions, now in the 

My question is the following: why is the second snippet of code working while mine is throwing an exception? Is there a way to achieve what I am trying to do (representing the taylor expansion of lambda * H where lambda is a scalar symbol and H a matrix)?


Solution

  • You can multiply a matrix by a scalar but you can't add a matrix and a scalar:

    In [1]: M = MatrixSymbol('M', 2, 2)                                                                                               
    
    In [2]: M                                                                                                                         
    Out[2]: M
    
    In [3]: 2*M                                                                                                                       
    Out[3]: 2⋅M
    
    In [4]: 2 + M                                                                                                                     
    ---------------------------------------------------------------------------
    TypeError: Mix of Matrix and Scalar symbols
    

    The problem in your case is that res is an integer. It should be the identity matrix. I don't know how to create an identity matrix of symbolic dimension though so instead I'll just use a symbol I:

    import sympy as sy
    
    def taylor_exponential(x: sy.Symbol, order: int):
        res = sy.MatrixSymbol('I', *x.shape)
        for k in range(1, order):
            res += (x ** k) / sy.factorial(k)
        return res
        # return sy.series(sy.exp(x), x, n=order)
    
    n = sy.symbols("n")
    lambd = sy.symbols("lambda")
    H0 = sy.MatrixSymbol("H_0", n, n)
    
    print(taylor_exponential(H0 * lambd, 4))
    

    Output:

    lambda*H_0 + (1/2)*(lambda*H_0)**2 + (1/6)*(lambda*H_0)**3 + I