8
$\begingroup$

I am trying to define some symbols as being numeric by using TagSet and encountered the following different behaviors between NumericQ and e.g. IntegerQ.

TagSet with IntegerQ, together with other built-in functions I've tried, also works when the symbol takes an argument.

f/:IntegerQ[f[_]]=True;
IntegerQ[f]
IntegerQ[f[1]]
(* ==>
False
True
*)

However, while trying to do the same with NumericQ it does not work.

g/:NumericQ[g[_]]=True;
NumericQ[g]
NumericQ[g[1]]
(* ==>
False
False
*)

Note though that h/:NumericQ[h]=True; NumericQ[h] gives True as expected.

Furthermore, Definition gives different output when applied to f compared to g, h above:

Definition[f]
Definition[g]
Definition[h]
(* ==>
IntegerQ[f[_]]^=True
Null
Null
*)

This is very puzzling to me. Why is there this difference?

$\endgroup$
2
  • 5
    $\begingroup$ Consider using SetAttributes[g, NumericFunction] instead. $\endgroup$ Commented Aug 17, 2017 at 15:28
  • $\begingroup$ @J.M.: Thanks a lot! Although it doesn't answer the question, it does solve my underlying problem. That ought to be more important but it's hard to let go of a puzzle once you started wonder... :-) Note also that it makes both NumericQ[g] and NumericQ[g[1]] evaluate to True and does not offer the flexibility of leaving NumericQ[q] as False, should one ever want that... I don't but worth mentioning for sake of generality. :-) Thanks again! $\endgroup$ Commented Aug 17, 2017 at 16:00

1 Answer 1

7
$\begingroup$

...Set... functions are overridden for NumericQ. That's why your assignment g /: NumericQ[g[_]] = True does not work as expected.

I guess that the fact that above assignment doesn't complain with an error message, and just does nothing, might be considered a bug.


You could try to manually add necessary UpValues to your g:

g // ClearAll
g // UpValues = {HoldPattern@NumericQ@g@_ :> True};

This will work when NumericQ is called directly on g[...].

NumericQ@g       (* False *)
NumericQ@g[1]    (* True *)
NumericQ@g[1, 2] (* False *)

But it will not work when g[...] is deeper in some other expression:

NumericQ@Sin@g[1] (* False *)

For NumericQ to recognize g[...] with numeric arguments arbitrarily deep inside other numeric functions you could set NumericFunction attribute (as suggested in comment by J. M.), but this does not give you precise control on pattern for which g[...] will be considered numeric:

g // ClearAll
g // Attributes = NumericFunction;

NumericQ@g            (* False *)
NumericQ@g[a]         (* False *)
NumericQ@g[1]         (* True *)
NumericQ@g[1, 2]      (* True *)
NumericQ@Sin@g[1, Pi] (* True *)

Overridden assignments involving NumericQ allow defining custom symbols representing numerical constants like E, or Pi, in a way that Mathematica will recognize them as numerical. E.g:

NumericQ@Sin@myNumConst     (* False *)
NumericQ@myNumConst = True;
NumericQ@Sin@myNumConst     (* True *)
NumericQ@myNumConst = False;
NumericQ@Sin@myNumConst     (* False *)

You can also force Mathematica to forget that a built-in constant is numerical:

NumericQ@Sin@E      (* True *)
NumericQ@E = False;
NumericQ@Sin@E      (* False *)

Mathematica seems to store some internal collection of such numerical symbols since results of such assignments are not visible neither in Language`ExtendedDefinition@NumericQ nor in Language`ExtendedDefinition@myNumConst. Unfortunately I don't know how to access it.

$\endgroup$
4
  • $\begingroup$ Thank you for an illuminating and almost complete answer! Gotta love this forum! :-D The only remaining strange part is why h/: NumericQ[h]=True works fine (as expected) but yet doesn't show up in Definition[h]. $\endgroup$ Commented Aug 17, 2017 at 17:45
  • $\begingroup$ @Stalpotaten Effects of this assignment are neither in Language`ExtendedDefinition@h nor in Language`ExtendedDefinition@NumericQ, there must be some internal collection of symbols for which NumericQ gives True, like E, or Pi. Overridden assignments involving NumericQ probably add symbols directly to that collection. Unfortunately I don't know how to access it. $\endgroup$
    – jkuczm
    Commented Aug 17, 2017 at 18:38
  • $\begingroup$ Thank you! I guess that is as far as we get in this mystery, but it's far enough for me! $\endgroup$ Commented Aug 17, 2017 at 18:50
  • $\begingroup$ For constants, you can do SetAttributes[myNumConst, Constant] @Stalpotaten. $\endgroup$ Commented Aug 18, 2017 at 3:30

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.