4
$\begingroup$

My goal is to have NumericQ[h[j]]=True for any j regardless of whether j may be symbolic with no defined value.

Setting NumericQ[h[j_]]=True does not work and as I understand the NumericFunction attribute only works when the input is also numeric.

One solution might be to unprotect NumericQ and then set NumericQ[h[j_]]=True but I have not tried this as I am afraid of using Unprotect. Another solution might be to define my own NumericQ function, that I can call numericq for example, and set numericq[h[j_]]=True but I would have to replace all previous NumericQ with numericq in my code and test that everything works.

  • edit *

I want to do this because I want my code to ignore certain symbols. My solution was to treat these symbols as numeric but this does not work for symbols like h[j] when j is a generic symbol. Any other function that works like NumericQ could work although I would have to change my code a bit.

$\endgroup$
4
  • 5
    $\begingroup$ This gives off the impression of an XY problem. Surely there is a way to solve your actual problem that does not involve doing fragile things like redefining NumericQ[]. $\endgroup$ Jul 25, 2022 at 17:02
  • $\begingroup$ @J.M. I agree that my question is on my current solution rather than the problem. I added an edit under * edit * to explain what the problem is. $\endgroup$ Jul 25, 2022 at 17:17
  • 1
    $\begingroup$ Instead of unprotecting NumericQ, you could use an upvalue as in h/:HoldPattern[NumericQ[h[_]]]=True. I am not saying that it is a good idea. Btw: Somewhat surprisingly to me, even something like NumericQ[undefinedsymbol]=True gives no error. I do not understand why it gives no error, NumericQ is protected, not sure what I am missing. $\endgroup$
    – user293787
    Jul 25, 2022 at 17:33
  • $\begingroup$ @user293787, that is a slick solution. I did not think of using an upvalue. I am quite inexperienced with upvalues. If you want to copy-paste your comment into a solution I will accept it. $\endgroup$ Jul 25, 2022 at 17:41

2 Answers 2

7
$\begingroup$

Instead of unprotecting NumericQ, one can define an upvalue for h:

h/:HoldPattern[NumericQ[h[_]]]=True;

This means that the definition is stored with h rather than with NumericQ:

UpValues[h]
(* {HoldPattern[HoldPattern[NumericQ[h[_]]]]:>True} *)

When an expression such as NumericQ[h[4]] is evaluated, then upvalue definitions for h are tried before downvalue definitions for NumericQ, hence we get True. See this tutorial.

Warning. Though I have used upvalues before with NumericQ, I do not know if it can break something.

$\endgroup$
1
$\begingroup$

This is an extended comment and not strictly an answer. But I thought I put this here, since people that end up here for whatever reason might find it useful. For reference, I am currently using Version 12.3.

While writing the other answer, I was surprised to find that the assignment

NumericQ[undefinedsymbol] = True

gives no warning, despite NumericQ having the attribute Protected. And it works, meaning now

NumericQ[undefinedsymbol]
(* gives True *)

By contrast

NumericQ[undefinedsymbol2] = "seriously"

gives the error message

Cannot set NumericQ[undefinedsymbol2] to seriously; the lhs argument must be a symbol and the rhs must be True or False

This error would suggest that

NumericQ[undefinedsymbol3[789]] = True

would fail since undefinedsymbol3[789] is not a symbol, but it gives no error or warning. However,

NumericQ[undefinedsymbol3[789]]
(* gives False *)

I find this a bit misleading. Probably NumericQ[undefinedsymbol3[789]] = True should give an error, since without error, one assumes that the definition was recorded, when in fact it was not.

I do not know if people use this feature of NumericQ. I do not see it mentioned in the documentation.

Comment. I can understand how NumericQ[undefinedsymbol] = True can work despite the protection. For example, NumericQ could be using something similar to the following code to circumvent the protection:

myNumericQ/:Set[myNumericQ[x_Symbol],tf:(True|False)]:=(
   Unprotect[myNumericQ];
   AppendTo[DownValues[myNumericQ],HoldPattern[myNumericQ[x]]:>tf];
   Protect[myNumericQ];
   tf);
Protect[myNumericQ];
$\endgroup$
3
  • 1
    $\begingroup$ As far as I know NumericQ[symbol]=True is a well-known way to attach the numeric property to a symbol and as far as I know, it is a mystery how it works. Szabolcs discusses his guess here where he also discusses why ClearAll[symbol] does not remove the numeric property from symbol. $\endgroup$ Jul 26, 2022 at 19:25
  • $\begingroup$ @userrandrand Thank you very much, I had not seen that post! I see that Scabolcs' guess for how it works is similar to mine (but maybe mine has some obvious flaw, not sure). I think I will leave the post here for now, if only to point out the questionable behavior for NumericQ[undefinedsymbol3[789]] = True. $\endgroup$
    – user293787
    Jul 26, 2022 at 19:36
  • $\begingroup$ For a better alternative to the AppendTo used above, see this answer. $\endgroup$
    – user293787
    Jul 29, 2022 at 5:06

Your Answer

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

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