0

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
anabstudent
  • 61
  • 1
  • 1
  • 9
  • Clean up your imports. Then break up that complicated statement into multiple steps to see which line the error will come from until you know what operation or object is at fault. – Harrichael Oct 03 '16 at 19:44
  • each of the three major "blurbs" are separated, I am sorry if that was misleading. the problem starts in the for loop and i do not know why. I will not know if the bessel function is clear or not until I get this out of the way first – anabstudent Oct 03 '16 at 19:50
  • It seems that (x/c) cannot be interpreted as an integer. Have you looked at what kind of object that is? Does it make sense to have an integer value? If so, look at the object type with type(x/c), find what library that defines that type, and google "library type integer representation". – Harrichael Oct 03 '16 at 19:52
  • it says `sympy.core.mul.Mul` for `type(x/c)` – anabstudent Oct 03 '16 at 20:04
  • Don't use `*` for imports, it makes things more confusing than they need to be. – kylieCatt Oct 03 '16 at 20:16
  • for the x/c it would make sense if it were an integer, but that is because it should be an element of the real numbers as is. looking at the second diagram [on here] (http://docs.sympy.org/dev/tutorial/manipulation.html) is not telling me very much however. – anabstudent Oct 03 '16 at 20:29
  • @IanAuld i took your comment into account, thanks for the advice. i believe you wanted me to write `import sympy` as whatever – anabstudent Oct 03 '16 at 20:30
  • Why should it matter if it were an integer, imaginary, non-set theory number, anything really. Maybe a bit far on that last one, but what is it that is stopping python??? – anabstudent Oct 03 '16 at 22:27
  • `range` is a python builtin that requires integer input afaik. It does not make sense to pass a sympy object. Also check your syntax: `sympy.Symbol("x", Real=True).is_real` --> None `sympy.Symbol("x", real=True).is_real` --> True – dnalow Oct 04 '16 at 10:54

1 Answers1

2

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)
asmeurer
  • 86,894
  • 26
  • 169
  • 240