lzcostademoraes
lzcostademoraes

Reputation: 83

Sympy expression simplification

I'm solving an eigenvalue problem when the matrix and the eigenvectors are time dependent. The matrix has dimension 8x8 and is hermitian. The time dependent matrix has the form:

import sympy as sp
t, lbd = sp.symbols(r't,\lambda', real=True)

Had = ...
print(repr(Had))

Matrix([[2*t,0, 0, 0, 0, 0, 0,0],
[ 0,-2*t, 2*t*(1 - t), 0, 0, 0,0,0],
[0, 2*t*(1 - t),0,0, 2 - 2*t, 0,0,0],
[0,0,0,0, 0, 2 - 2*t, 0,0],
[0,0,2 - 2*t,0,0,0,0,0],
[0,0,0, 2 - 2*t,0,0, 2*t*(1 - t),0],
[0,0,0,0,0, 2*t*(1 - t),-2*t,0],
[0,0,0,0,0,0,0,2*t]])

Now the characteristic polynomial has the following for:

 P = p.simplify(sp.collect(sp.factor(Had.charpoly(lbd).as_expr()),lbd))

and get

enter image description here

Then I choose the second term and find the solution for lambda:

P_list = sp.factor_list(P)
a,b = P_list[1]
eq,exp = sp.simplify(b)
sol = sp.solve(eq)

With that I get the roots in a list:

r_list = []
for i in range(len(sol)):
    a = list(sol[i].values())
    r_list.append(a[0]) 

Solving the problem using sp.eigenvecs:

val_mult_vec = Had.eigenvects()
e_vals = []
mults = []
e_vecs = []
for i in range(len(val_mult_vec)):
    val, mult, [vec_i, vec_j] = val_mult_vec[i]
    e_vals.append(val)
    e_vals.append(val)
    mults.append(mult)
    e_vecs.append(vec_i)
    e_vecs.append(vec_j)

Solving the eigenvectors I get complicated expressions like this:

enter image description here

But I know that this complicated expression can be expressed in terms of the solution of the second term in the characteristic polynomial something like this:

enter image description here

Where r1 are one of the roots of that equation. With the solution to the characteristic polynomial how can I rewrite the eigenvectors in a simplified way like the last image using sympy? rewrite e_vec[i] in terms of r_list[j]

Upvotes: 0

Views: 177

Answers (1)

Davide_sd
Davide_sd

Reputation: 13150

Seems like you want to obtain a compact version of the eigenvectors.

Recepy:

  1. We can create as many symbols as the number of eigenvalues. Each symbol represents an eigenvalue.
  2. Loop over the eigenvectors and for each of its elements substitute the long eigenvalue expression with the respective symbol.
r_symbols = symbols("r0:%s" % len(e_vals))
final_evecs = []
for vec, val, s in zip(e_vecs, e_vals, r_symbols):
    final_evecs.append(
        vec.applyfunc(lambda t: t.subs(val, s))
    )

final_evecs is a list containing eigenvectors in a compact notation.

Let's test one output:

final_evecs[7]

enter image description here

Upvotes: 1

Related Questions