2

Using the following code, I got the first two piecewise equations right but the third one returns -99.

Clear[x];
{PiecewiseExpand[Which[x < -1, -1, x < 1, x, True, 1]],
 PiecewiseExpand[If[x < -1, -1, If[x < 1, x, 1]]],
 PiecewiseExpand[If[x < -1, -1, If[x < 1, x, 1], -99]]} 

Similarly, the third one always returns -99 when I use the following code.

{Which[x < -1, -1, x < 1, x, True, 1], 
  If[x < -1, -1, If[x < 1, x, 1]], 
  If[x < -1, -1, If[x < 1, x, 1], -99]} /. {{x -> 3/5}, {x -> n}}

However, things turn correct if I use

x = 3/5; {Which[x < -1, -1, x < 1, x, True, 1], 
 If[x < -1, -1, If[x < 1, x, 1]], If[x < -1, -1, If[x < 1, x, 1], -99]}
x = n; {Which[x < -1, -1, x < 1, x, True, 1], 
 If[x < -1, -1, If[x < 1, x, 1]], 
 If[x < -1, -1, If[x < 1, x, 1], -99]}

What's wrong with the third equation If[x < -1, -1, If[x < 1, x, 1], -99]?

Richard
  • 49
  • 1

2 Answers2

1

From the docs:

If[condition,t,f,u] gives u if condition evaluates to neither True nor False.

If x has not been assigned a value yet, it will return -99. Try the code below separately and see the results.

Clear[x]
If[x < -1, -1, If[x < 1, x, 1], -99]

-99

x = 10;
If[x < -1, -1, If[x < 1, x, 1], -99]

1

Syed
  • 52,495
  • 4
  • 30
  • 85
  • But why If[x < -1, -1, If[x < 1, x, 1], -99]/.{x->10} doesn't work? – Richard Sep 09 '21 at 19:53
  • Because the output is -99 and applying the rule x->10 afterwards cannot change a number. Change -99 in your comment above to x^2 and see the effect. – Syed Sep 09 '21 at 20:02
  • I changed -99 to x^2 and tried If[x < -1, -1, If[x < 1, x, 1], x^2] /. {x -> -2}. The result is 4. No matter what value is assigned to x, I can never get -1 or x--it's always x^2. However, if completely remove x^2 and use f[x < -1, -1, If[x < 1, x, 1]] /. {x -> -2}, the result is -1, which is correct. It seems something is wrong with the neither TRUE nor FALSE value of x^2. What is the problem? – Richard Sep 09 '21 at 21:22
  • Also from the docs "If the condition is neither True nor False, If remains unevaluated" and "The form with an explicit case for an undetermined condition evaluates in any case". Look under Examples / Scope / Evaluation. – Rohit Namjoshi Sep 10 '21 at 02:16
0

What you are seeing here are the two faces of Which and If--The first face as a control-flow conditional the second face as an implicit function.

In the first (imperative) face you typically do want to include a default value that the control flows into if no test matches because it makes debugging and error-handling easier. This is because if no test matches you obtain a succinct, meaningful output that lets you know where the control-flow ended-up.

Hence here the control-flow depends on the value of x

x = 3/5;
If[x < -1, -1, If[x < 1, x, 1], -99]

(* 3/5 *)

or if no matching takes place then the control flow generates a -99 (error message)

x = n;
If[x < -1, -1, If[x < 1, x, 1], -99]

(* 99 *)

In the second (functional) face you typically do not want to include a default value because if no test matches then it might just mean that no test matches yet and you don't want to forego the possibility that it might match later with some downstream symbolic manipulation or value setting.

Hence in this case you want the function's structure preserved which is why the whole expression returns unevaluated.

fn = If[x < -1, -1, If[x < 1, x, 1]]

(* If[x < -1, -1, If[x < 1, x, 1]] *)

but now it can act as a function using ReplaceAll substitutions on desired "arguments".

fn /. {{x -> 3/5}, {x -> n}}

(* {3/5, If[n < -1, -1, If[n < 1, n, 1]]} *)

Note that generally however, you don't want to define and apply functions in this way because without any local encapsulation you are likely to run into difficulties managing variable leakage/pollution (n.b. the Clear@x at the outset).

Hence it is generally better programming practice to define functions using := and decide whether or not to include a final default value depending on its intended use in an imperative or functional setting.

f[x_] := If[x < -1, -1, If[x < 1, x, 1], -99];

g[x_] := If[x < -1, -1, If[x < 1, x, 1]];

{{f[3/5], f[n]}, {g[3/5], g[n]}}

(* {{3/5, -99}, {3/5, If[n < -1, -1, If[n < 1, n, 1]]}} *)

Ronald Monson
  • 6,076
  • 26
  • 46