I am trying to develop a plot for my helioseismology class and the question had provided a piecewise function describing the dynamics of the "fluids" in a star as if it is one thing its this and if its another its that. I am receiving over and over again this 'Mul' object cannot be interpreted as an integer
but I am working with numbers in the reals not just the integer set. I do not know how to get around this and need guidance. The code is as follows.
import sympy as sy
from sympy import *
from sympy.physics.units import Unit
import numpy as np
import sys
import math
import scipy as sp
from scipy import special
phi = Symbol('phi', Variable = True)
x = Symbol('x', Variable = True, Real = True)
t = Symbol('t', Variable = True, Real = True)
xi = Symbol('xi', Function = True)
Solar_Radius = Symbol('R', Constant = True, unit = "meters")
Sound_Speed = Symbol('c', Constant = True, unit = "meters per second", Real = True)
gamma = Symbol('gamma', Constant = True)
gravity = Symbol('g', Constant = True, unit = "meters per second per second")
Solar_Radius = 6.963 * 10 ** 6
gamma = 5/3
g = 274.8265625336
gas_constant = 8201.25
c = 8.1 * 10 ** 3
for t in range(0,x/c):
xi[x,t] = 0
for t in range(x/c,00):
xi[x,t] = (1/2)*sy.exp(gamma*g*x/(2*c**2))*mpmath.besselj(0, (gamma*g/(2*c)*sy.sqrt(t**2 - ((x/c)**2))),derivative = 0)
Full Traceback:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-50-3506376f1686> in <module>()
----> 1 for t in range(0,x/c):
2 xi[x,t] = 0
3 for t in range(x/c,00):
4 xi[x,t] = (1/2)*sy.exp(gamma*g*x/(2*c**2))*mpmath.besselj(0, (gamma*g/(2*c)*sy.sqrt(t**2 - ((x/c)**2))),derivative = 0)
TypeError: 'Mul' object cannot be interpreted as an integer
There are quite a few issues here:
None of the keyword arguments (Constant, Variable, unit, Real) that you are passing to Symbol are things that are recognized by SymPy. The only one that is close is real
, which should be lowercase (like Symbol('x', real=True)
). The rest do nothing. If you want units, you should use the SymPy units module in sympy.physics.units
. There is no need to specify if a symbol is constant or variable.
You have redefined Solar_Radius
and gamma
as numbers. That means that the Symbol definitions for those variables are pointless.
If you are using Python 2, make sure to include from __future__ import division
at the top of the file, or else things like 1/2
and 5/3
will be truncated with integer division (this isn't an issue in Python 3).
range(0, x/c)
doesn't make sense. range
creates a list of numbers, like range(0, 3)
-> [0, 1, 2]
. But x/c
is not a number, it's a symbolic expression.
Additionally, xi[x, t] = ...
doesn't make sense. xi
is a Symbol, which doesn't allow indexing and certainly doesn't allow assignment.
Don't mix numeric (math, mpmath, numpy, scipy) functions with SymPy functions. They won't work with symbolic expressions. You should use only SymPy functions. If you create a symbolic expression and want to convert it to a numeric one (e.g., for plotting), use lambdify
.
What you want here is Piecewise
. The syntax is Piecewise((expr, cond), (expr, cond), ..., (expr, True))
, where expr
is an expression that is used when cond
is true ((expr, True)
is the "otherwise" condition).
For your example, I believe you want
expr = Piecewise((0, t < x/c), (sy.exp(gamma*g*x/(2*c**2))*sy.besselj(0, (gamma*g/(2*c)*sy.sqrt(t**2 - (x/c)**2)))/2, t >= x/c))
If you want to turn this into a numeric function in x
and t
, use
xi = lambdify((x, t), expr)