f[x_] := x /; x<0 
f[x_] := x^2 /; x>=0 

The above does not work (Mathematica returns it unevaluated), but the below does.

g[x_] = Piecewise[{ {x,x<0}, {x^2,x>=0}}] 

Why? More importantly, I've written a lot of code using the /; form: is there any way I can make it work and/or automagically convert it to Piecewise form without having to rewrite my code?

In real life, I'm doing something like Integrate[Cos[n x] f[x], {x, -1, 1}] for arbitrary n, and want a symbolic result, so NIntegrate won't solve my problem.

  • 1
    $\begingroup$ NIntegrate[f[x], {x, -1, 1}] will work and can be used with either Rationalize or RootApproximant to return -1/6. $\endgroup$
    – Bob Hanlon
    Nov 6 '14 at 14:41
  • $\begingroup$ @BobHanlon Unfortunately won't work if the integration contains variables other than x. $\endgroup$
    – user1722
    Nov 6 '14 at 14:51
  • 3
    $\begingroup$ I would consider /; a programming construct, while Piecewise is meant for representing a mathematical concept. Piecewise was designed with symbolic manipulation in mind. /; is for controlling evaluation. These are two entirely different uses, and many constructs have two versions in Mathematica for this reason. Some others don't and the line between 'math' and 'programming' can be blurry (e.g. I'd also consider If a programming construct but it does work in Integrate) ... which can cause problems and confusion. $\endgroup$
    – Szabolcs
    Nov 6 '14 at 16:15

The difference lies in the evaluation of f vs. g. Consider what happens when you supply them with a symbol, e.g.

(* f[x] *)


(* Piecewise[{{x, x < 0}, {x^2, x >= 0}}, 0] *)

So, Integrate does not see the inside of f[x], and, more importantly, it cannot do any symbolic evaluation on it because Condition (/;) prevents it from doing so. A similar problem arises if you use PatternTest, instead, e.g.

h[x_?Negative] := x
h[x_?NonNegative] := x^2
Integrate[h[x], {x, -1, 1}]
(* Integrate[h[x], {x, -1, 1}] *)
  • $\begingroup$ OK, is there any "magic" way to convert one form to the other? (ie, a way that requires minimal effort on my part?) $\endgroup$
    – user1722
    Nov 6 '14 at 14:52
  • 2
    $\begingroup$ @barrycarter I've been thinking about it. Provided that the conditions are simple, this works: Piecewise[(DownValues[f][[All, 2]] /. Verbatim[Condition][a_, b_] :> {a, b})]. $\endgroup$
    – rcollyer
    Nov 6 '14 at 15:07
  • 1
    $\begingroup$ @AlexeyPopkov I added it as neither evaluate to True, so the rhs is never seen by Integrate. Similar problem, same result. $\endgroup$
    – rcollyer
    Nov 6 '14 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy