f=piecewise([[(0,1),x],[(1,3),2-x],[(3,4),x-4]])
f.end_points()
[0, 1, 3, 4]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-1-3e93894c0576> in <module>()
2 #show(plot(f))
3 f.end_points()
----> 4 f(Integer(1))
/home/sc_serv/sage/local/lib/python2.7/site-packages/sage/symbolic/function_factory.pyc in new_f(ex, *args, **kwds)
400 new_args = list(ex._unpack_operands())
401 new_args.extend(args)
--> 402 return f(ex, *new_args, **kwds)
403 return new_f
/home/sc_serv/sage/local/lib/python2.7/site-packages/sage/functions/piecewise.py in __call__(cls, self, parameters, variable, value, **kwds)
447 if value is not None:
448 substitution[variable] = value
--> 449 return self.subs(substitution)
450
451 def _fast_float_(cls, self, *args):
/home/sc_serv/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.substitute (/home/sc_serv/sage/src/build/cythonized/sage/symbolic/expression.cpp:27845)()
4883
4884 return new_Expression_from_GEx(self._parent,
-> 4885 self._gobj.subs_map(smap, 0))
4886
4887 subs = substitute
/home/sc_serv/sage/local/lib/python2.7/site-packages/sage/functions/piecewise.py in _subs_(self, subs_map, options, parameters, x)
228 if domain.contains(point):
229 return subs_map.apply_to(func, 0)
--> 230 raise ValueError('point {} is not in the domain'.format(point))
231
232 @staticmethod
ValueError: point 1 is not in the domain
def g(x):
var('u')
return numerical_integral(u^2,0,x)[0]
f=piecewise([ [(0,1), g ] ])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-d490d0695d4b> in <module>()
4
5
----> 6 f=piecewise([ [(Integer(0),Integer(1)), g ] ])
7
/home/sc_serv/sage/src/sage/misc/lazy_import.pyx in sage.misc.lazy_import.LazyImport.__call__ (/home/sc_serv/sage/src/build/cythonized/sage/misc/lazy_import.c:3628)()
384 True
385 """
--> 386 return self._get_object()(*args, **kwds)
387
388 def __repr__(self):
/home/sc_serv/sage/local/lib/python2.7/site-packages/sage/functions/piecewise.py in __call__(self, function_pieces, **kwds)
149 function = function()
150 else:
--> 151 function = function(var)
152 function = SR(function)
153 if var is None and len(function.variables()) > 0:
<ipython-input-1-d490d0695d4b> in g(x)
1 def g(x):
2 var('u')
----> 3 return numerical_integral(u**Integer(2),Integer(0),x)[Integer(0)]
4
5
/home/sc_serv/sage/src/sage/gsl/integration.pyx in sage.gsl.integration.numerical_integral (/home/sc_serv/sage/src/build/cythonized/sage/gsl/integration.c:3387)()
329 else:
330 _a=a
--> 331 _b=b
332 W = <gsl_integration_workspace*> gsl_integration_workspace_alloc(n)
333 sig_on()
/home/sc_serv/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.__float__ (/home/sc_serv/sage/src/build/cythonized/sage/symbolic/expression.cpp:10403)()
1384 return float(self._eval_self(float))
1385 except TypeError:
-> 1386 raise TypeError("unable to simplify to float approximation")
1387
1388 def __complex__(self):
TypeError: unable to simplify to float approximation
With all due deference to the work that went into making piecewise functions symbolic, it's too much overhead for purely numerical applications, as for example WKB approximations. Here's some sample code for a uniform approximation to a wavefunction in a power potential constructing symbolic functions from numeric functions, and here's the equivalent code without using piecewise and just plotting the numeric functions.
The code without symbolic functions is expected to be faster, but it really is a lot faster. Wouldn't it make sense to have an option to avoid symbolic functions in some way? Maybe define a numerical_piecewise function