42
$\begingroup$

There are a few builtin symbolic constants which behave like numbers, e.g. E, Pi, EulerGamma, etc.

How can I define my own in such a way that the system will treat them just like the builtin ones?

$\endgroup$

1 Answer 1

45
$\begingroup$

I was recently reminded that the following "functions" are settable, and I was surprised (even though I've seen this before). So I thought that it is valuable to share this information.

There are three critical properties of symbolic constants:

  • The Constant attribute, which is used by Dt

  • The ability to tell that it is a numeric expression (NumericQ[Pi] === True).

  • The ability to compute the value to any precision.

We can implement all three by direct assignment. Let the symbol sqrt2 represent $\sqrt{2}$:

SetAttributes[sqrt2, Constant]
NumericQ[sqrt2] = True;
N[sqrt2, prec___] := N[Sqrt[2], prec]

Note that it wasn't necessary to unprotect any symbols.

Now sqrt2 doesn't evaluate:

sqrt2
(* sqrt2 *)

But it can be computed numerically:

N[sqrt2, 100]
(* 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573 *)

It is numeric:

NumericQ[sqrt2]
(* True *)

Which means that many functions work well with it without the need for additional definitions:

Positive[sqrt2]
(* True *)

Im[sqrt2]
(* 0 *)

Integrate[Exp[-sqrt2 x], {x, 0, Infinity}]
(* 1/sqrt2 *)

Integrate wouldn't give the same result with an arbitrary symbolic parameter:

Integrate[Exp[-s x], {x, 0, Infinity}]
(* ConditionalExpression[1/s, Re[s] > 0] *)

And of course it works with Dt

Dt[sqrt2 x, x]
(* sqrt2 *)

Update: How do we clear such a symbol? Like this:

ClearAll[sqrt2]
NumericQ[sqrt2] =.

I do not know where the NumericQ setting is stored. It doesn't seem to be associated either with NumericQ or sqrt2. Also, NumericQ is clearly set up to handle this usage and will not accept invalid values.


Did I miss anything? If so, let me know!

$\endgroup$
9
  • 1
    $\begingroup$ @xzczd Where is it stored? I have no idea. It doesn't seem to be associated either with NumericQ or sqrt2. But I can tell you how to clear it: NumericQ[sqrt2] =. If you asked the same question about N then the answer would be NValues[sqrt2]. $\endgroup$
    – Szabolcs
    Commented Oct 11, 2016 at 14:58
  • 2
    $\begingroup$ OK. Another "missing" truth: the sqrt2 is compilable. $\endgroup$
    – xzczd
    Commented Oct 11, 2016 at 15:07
  • 7
    $\begingroup$ One thing this approach misses is missing relations. Mathematica knows for example that Log[E] == 1 and Sin[Pi] == 0, but it doesn't know sqrt2^2 == 2. I suppose this is a case by case issue though... $\endgroup$
    – Greg Hurst
    Commented Oct 11, 2016 at 15:15
  • 5
    $\begingroup$ Though through spelunking, one can find that FunctionExpand (and therefore FullSimplify) can be taught rules by adding them to SimplifyDump`$FSTab and your symbol can be hooked in by adding your symbol to SimplifyDump`PositiveRules. $\endgroup$
    – Greg Hurst
    Commented Oct 11, 2016 at 19:54
  • 1
    $\begingroup$ When clearing could you remove the need to Unset NumericQ[sqrt2] by using UpSet? NumericQ[sqrt2] ^= True $\endgroup$
    – Edmund
    Commented Feb 4, 2017 at 1:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.