How to Define a Piecewise Function in Python with Multiple Variables
<p>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 <code>'Mul' object cannot be interpreted as an integer</code> 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.</p>

<pre><code>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)
</code></pre>

<p>Full Traceback:</p>

<pre><code>---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
&lt;ipython-input-50-3506376f1686&gt; in &lt;module&gt;()
----&gt; 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
</code></pre>

<p>There are quite a few issues here:</p>

<ul>
<li><p>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 <code>real</code>, which should be lowercase (like <code>Symbol('x', real=True)</code>). The rest do nothing. If you want units, you should use the SymPy units module in <code>sympy.physics.units</code>. There is no need to specify if a symbol is constant or variable. </p></li>
<li><p>You have redefined <code>Solar_Radius</code> and <code>gamma</code> as numbers. That means that the Symbol definitions for those variables are pointless. </p></li>
<li><p>If you are using Python 2, make sure to include <code>from __future__ import division</code> at the top of the file, or else things like <code>1/2</code> and <code>5/3</code> will be truncated with integer division (this isn't an issue in Python 3). </p></li>
<li><p><code>range(0, x/c)</code> doesn't make sense. <code>range</code> creates a list of numbers, like <code>range(0, 3)</code> -> <code>[0, 1, 2]</code>. But <code>x/c</code> is not a number, it's a symbolic expression.</p></li>
<li><p>Additionally, <code>xi[x, t] = ...</code> doesn't make sense. <code>xi</code> is a Symbol, which doesn't allow indexing and certainly doesn't allow assignment.</p></li>
<li><p>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 <code>lambdify</code>.</p></li>
</ul>

<p>What you want here is <code>Piecewise</code>. The syntax is <code>Piecewise((expr, cond), (expr, cond), ..., (expr, True))</code>, where <code>expr</code> is an expression that is used when <code>cond</code> is true (<code>(expr, True)</code> is the "otherwise" condition). </p>

<p>For your example, I believe you want</p>

<pre><code>expr = Piecewise((0, t &lt; 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 &gt;= x/c))
</code></pre>

<p>If you want to turn this into a numeric function in <code>x</code> and <code>t</code>, use</p>

<pre><code>xi = lambdify((x, t), expr)
</code></pre>

python for-loop sympy bessel-functions