Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rule-based programming: declare variables to be a number

39 views
Skip to first unread message

Hendrik van Hees

unread,
Aug 30, 2007, 11:58:39 PM8/30/07
to
I still work with Mathematica 4.0. I hope, somebody can answer my
question despite this.

I have written a simple rule-based program to evaluate traces of
SU(2)-Lie algebra (Pauli matrices) to help me to obtain the Lagrangian
of a chiral model, but that's not so important for my question.

My problem is the following: To get the usual rules with algebraic
expressions containing numbers and Lie-algebra variables, one needs to
define what happens when a Lie-algebra variable is multiplied by a
number. This works fine as long as I use really constant numbers like
1, 2, 1/2, etc.

However, of course, one needs this feature also for variable numbers,
say a coupling constant g. So I wrote Unprotect[NumberQ] and then said

NumberQ[g]:=True,

but then NumberQ[g^2] evaluates to False. So I have written a whole
bunch of rules to make powers of g also numbers. It works already quite
well, but is there a possibility to just declare a variable (like g) to
be a number, and then make Mathematica know, that expressions like g^2,
Sqrt[g], 1+g, etc. are also numbers?

--
Hendrik van Hees Texas A&M University
Phone: +1 979/845-1411 Cyclotron Institute, MS-3366
Fax: +1 979/845-1899 College Station, TX 77843-3366
http://theory.gsi.de/~vanhees/faq mailto:he...@comp.tamu.edu

Carl Woll

unread,
Sep 1, 2007, 12:26:21 AM9/1/07
to
Hendrik van Hees wrote:

>I still work with Mathematica 4.0. I hope, somebody can answer my
>question despite this.
>
>I have written a simple rule-based program to evaluate traces of
>SU(2)-Lie algebra (Pauli matrices) to help me to obtain the Lagrangian
>of a chiral model, but that's not so important for my question.
>
>My problem is the following: To get the usual rules with algebraic
>expressions containing numbers and Lie-algebra variables, one needs to
>define what happens when a Lie-algebra variable is multiplied by a
>number. This works fine as long as I use really constant numbers like
>1, 2, 1/2, etc.
>
>However, of course, one needs this feature also for variable numbers,
>say a coupling constant g. So I wrote Unprotect[NumberQ] and then said
>
>NumberQ[g]:=True,
>
>but then NumberQ[g^2] evaluates to False. So I have written a whole
>bunch of rules to make powers of g also numbers. It works already quite
>well, but is there a possibility to just declare a variable (like g) to
>be a number, and then make Mathematica know, that expressions like g^2,
>Sqrt[g], 1+g, etc. are also numbers?
>
>
>

Try using NumericQ instead:

g /: NumericQ[g] = True;

Then:

In[26]:= NumericQ /@ {g^2, Sqrt[g], 1 + g}
Out[26]= {True,True,True}

Carl Woll
Wolfram Research

Andrzej Kozlowski

unread,
Sep 1, 2007, 12:39:33 AM9/1/07
to

On 31 Aug 2007, at 05:48, Hendrik van Hees wrote:

> I still work with Mathematica 4.0. I hope, somebody can answer my
> question despite this.
>
> I have written a simple rule-based program to evaluate traces of
> SU(2)-Lie algebra (Pauli matrices) to help me to obtain the Lagrangian
> of a chiral model, but that's not so important for my question.
>
> My problem is the following: To get the usual rules with algebraic
> expressions containing numbers and Lie-algebra variables, one needs to
> define what happens when a Lie-algebra variable is multiplied by a
> number. This works fine as long as I use really constant numbers like
> 1, 2, 1/2, etc.
>
> However, of course, one needs this feature also for variable numbers,
> say a coupling constant g. So I wrote Unprotect[NumberQ] and then said
>
> NumberQ[g]:=True,
>
> but then NumberQ[g^2] evaluates to False. So I have written a whole
> bunch of rules to make powers of g also numbers. It works already
> quite
> well, but is there a possibility to just declare a variable (like
> g) to
> be a number, and then make Mathematica know, that expressions like
> g^2,
> Sqrt[g], 1+g, etc. are also numbers?
>

> --
> Hendrik van Hees Texas A&M University
> Phone: +1 979/845-1411 Cyclotron Institute, MS-3366
> Fax: +1 979/845-1899 College Station, TX 77843-3366
> http://theory.gsi.de/~vanhees/faq mailto:he...@comp.tamu.edu
>

Use NumericQ instead of NumberQ. Then:
NumericQ[a] = True;
NumericQ[b] = True;

(Note that you do not need to unprotect NumericQ !). Then you get for
free:

NumericQ[a*b]
True
NumericQ[b^a]
True

and so on, just as you wanted.

Andrzej Kozlowski

PS. I am sure NumericQ has worked like this at lest since version 5
but I no longer remember about version 4.

dh

unread,
Sep 1, 2007, 12:55:45 AM9/1/07
to

Hi Hendrick,

simpliy replace g by 1. before calling NumberQ.

Further, I think it is a bad thing to change definitions of built in

function. Better create your own. Then:

myNumberQ[expr_] := NumberQ[expr /. g -> 1.]

By the way, I noted ,that NumberQ returns True for Exp[1.] but False for

Exp[1]

hope this helps, Daniel

David Bailey

unread,
Sep 2, 2007, 2:54:01 AM9/2/07
to
Hendrik van Hees wrote:
> I still work with Mathematica 4.0. I hope, somebody can answer my
> question despite this.
>
> I have written a simple rule-based program to evaluate traces of
> SU(2)-Lie algebra (Pauli matrices) to help me to obtain the Lagrangian
> of a chiral model, but that's not so important for my question.
>
> My problem is the following: To get the usual rules with algebraic
> expressions containing numbers and Lie-algebra variables, one needs to
> define what happens when a Lie-algebra variable is multiplied by a
> number. This works fine as long as I use really constant numbers like
> 1, 2, 1/2, etc.
>
> However, of course, one needs this feature also for variable numbers,
> say a coupling constant g. So I wrote Unprotect[NumberQ] and then said
>
> NumberQ[g]:=True,
>
> but then NumberQ[g^2] evaluates to False. So I have written a whole
> bunch of rules to make powers of g also numbers. It works already quite
> well, but is there a possibility to just declare a variable (like g) to
> be a number, and then make Mathematica know, that expressions like g^2,
> Sqrt[g], 1+g, etc. are also numbers?
>
Unless you have too much code to change, I would tackle this slightly
differently. I would represent your lie algebra variables in some way
you can recognise, and use non-commutative multiply (not Times) to
create your expressions. That way, everything that is not a lie algebra
variable is an ordinary number and it is fairly easy to define rules
that will combine these and apply the appropriate commutation rules to
the lie algebra variables.

As others have commented, it is not a good idea to write code like
NumericQ[g]=True because this changes the basic operation of
Mathematica. For example, such code might work OK until you try to
combine it with some more code that needs NumericQ for something else!

David Bailey
http://www.dbaileyconsultancy.co.uk

Andrzej Kozlowski

unread,
Sep 3, 2007, 6:16:58 AM9/3/07
to

On 2 Sep 2007, at 08:51, David Bailey wrote:

> As others have commented, it is not a good idea to write code like
> NumericQ[g]=True because this changes the basic operation of
> Mathematica. For example, such code might work OK until you try to
> combine it with some more code that needs NumericQ for something else!
>
> David Bailey
> http://www.dbaileyconsultancy.co.uk


Who are the "others"?
Anyway, I completely disagree with this statement in this particular
context.

NumericQ has clearly been designed with this in mind. Note, for
example, that althou NumericQ is Protected, a definition like

NumericQ[a]=True

does not require unprotecting NumericQ. Moreover, it does not add a
DownValue to NumericQ.

NumericQ[g] = True;
DownValues[NumericQ]
{}


There are plenty of other reasons to believe that all all
theseproperties of NumericQ are designed precisely for this type of
use. Besides, I have another reason to think that no probems of the
kind you are imagining would happen in this case: I have been using
NumericQ inprecisly this way for about 10 years in numerous notebooks
without any problems.

Note alo the post from Carl Woll which, I think, can be regarded as
an "offcial" WRI authorization for this kind of usage ;-)

(However, note also that using Carl's definition:

In[19]:= g /: NumericQ[g] = True;

Dos not actually add an UpValue to g:

UpValues[g]
{}

and I don't think it has any advantage over the more straightforward

NumericQ[g] = True;


I am sure all this is deliberate design, and even though it may not
be easy to explain, it is very convenient.

Andrzej Kozlowski

Simons, F.H.

unread,
Sep 4, 2007, 3:34:57 AM9/4/07
to
I have very mixed feelings about NumericQ. I agree with Andrzej that it
is a very useful function.

But for quite another reason I also agree with David Bailey. The
function NumericQ has attribute Protected, so I did not even get the
idea to try the command NumericQ[a]= True. This command should not =
work,
it violates basic principles of Mathematica.

As David states, unprotecting a Mathematica function and adding some
extra definitions is usually not a good idea. Instead, it is much better
to use TagSet, as Carl Woll did.

The other thing I do not like is that I have no idea where the
definition of NumericQ[a]= True is stored. It is not in the downvalues
of NumericQ, nor in the upvalues of a. So undoing this definition cannot
be done with Clear[NumericQ] or with UpValues[a]={}, both very natural
commands.

Finally, due to the mysterious implementation, Dynamic does not work as
expected:

Consider Dynamic[NumericQ[a]]

It shows False. Assigning a numeric value to a changes it to True, and
unassigning a changes it back to False. That is correct. The command
NumericQ[a] returns True, but the display of Dynamic incorrectly remains
False. Then do a=3, followed by a=., and Dynamic shows True. Now =
give
the command NumericQ[a]=.. Then the Dynamic object still shows True.

One of the very, very strong points of Mathematica is its uniform
structure. NumericQ seems to be a very regrettable and, as far as I can
see, unnecessary exception, despite the fact that the function works
fine.

Fred Simons
Eindhoven University of Technology

Szabolcs

unread,
Sep 4, 2007, 3:35:58 AM9/4/07
to

Thanks for the explanation!

But this is very curious. If neither the UpValues or Attributes of g,
or the DownValues of NumericQ are changed, then where is this
information about g stored? Is this something that is implemented at a
lower level than the Mathematica language? Is it possible to create
other custom properties, that can be set with a command as simple as
someProperty[g] = True (without using g /: someProperty[g] = True)?

Perhaps NumericQ itself behaves similarly to DownValues, OwnValues,
etc., where it is also possible to write OwnValues[a]={a->3} directly,
but when 'a' is removed, its OwnValues are gone too.

(When 'g' is Removed, the information that NumericQ[g] === True is gone
too.)

Szabolcs

Andrzej Kozlowski

unread,
Sep 4, 2007, 3:36:58 AM9/4/07
to
At the risk of beating a dead horse: the reason why it dos not make
sense to use UpValues or DownValues for NumericQ is precisely that
only two possible values are allowed, True or False. At least to me
it seems quite obvious that the mechanism of UpValues or Downvalues
is inappropriate in this situation, although I do not want to make a
drawn out argument out of this, which in the end is just a matter of
taste.

There are two other "matters of taste" involved here. First, it would
seem to me excessively pedantic to use:

g /: NumericQ[g] = True;

when we know that the shorter and simpler

NumericQ[g]=True

has exactly the same effect. The argument about Unprotecting
functions has no relevance here since nothing has to be unprotected
in this case.

The other issue is philosophical. Presumably Fred likes general rules
that hold without any exceptions. I, on the other hand, think
exceptions are what makes life, science, Mathematics and Mathematica
interesting. Just as, for example, exceptional Lie groups are the
most interesting lie groups so NumericQ is a beautiful function
because it has so many exceptional properties (which include the
fact, that, for example, NumericQ[a]=True and NumericQ[b]=True
automatically make NumericQ[a+Pi^Sin[b]] also True. That seems to me
to be also entirely against "the basic principles of Mathematica".

Andrzej Kozlowski

On 3 Sep 2007, at 17:07, Andrzej Kozlowski wrote:

> I understand these arguments since quite a long time ago I thought
> about them myself (I even sent a "puzzle" to the list asking where
> the "DownValue" of the definition NumericQ[a]=True is stored but
> the only "answer" I got referred to a story by Stanislaw Lem) but
> since I have long since convinced myself that this behaviour is
> intentional and extremely useful I believe them to be mistaken.
> First of all a practical remark: of course is no problem at all
> with "undoing" since one can easily undo
>
> NumericQ[a] = True
>
> with
>
> NumericQ[a] = False
> False
>
>
> Not only that but this is the logical and sensible thing to do.
> Having considered this matter quite carefully (and quite a long
> time ago) I do not agree with any of Fred's points about the
> "basic principles of Mathematica" in this particular case. NumericQ
> is simply special and there is no reason why some functions should
> not be special. To start with, without any user definitions, we have:
>
> NumericQ[a]
> False
>
> and yet False is not a DownValue of NumericQ. It seems quite
> natural for me therefor that
> NumericQ[a]=True simply changes the above "built-in" behaviour and
> does not create any DownValue either. Therefore it does not make
> any sense to me to try Clear[NumericQ]. Note also another very
> important fact. NumericQ is Protected yet you can define NumericQ[a]
> =True, which seems to contradict a "basic principle of
> Mathematica". But, and this is the key point, you can't make
> NumericQ[a] to be anything you like. Just try:
>
> NumericQ[a] = 3
> NumericQ::set:Cannot set NumericQ[a] to 3; the lhs argument must be
> a symbol and the rhs must be True or False. >>
>
> In fact, I consider this message the key to the whole issue and in
> my opinion it refutes all of David's and Fred's objections to this
> use of NumericQ. This "error message" is precisely the missing part
> of the documentation. In fact, not having this message in the
> documentation is the only thing that I find "regrettable" about
> NumericQ. Not only is the function itself not regrettable but I
> would go as far as to say that (after GroebnerBasis) it is my
> second favourite function in Mathematica, which I have used without
> problems for many years (and in quite many of my past post to the
> MathGroup ) and would find it almost irreplaceable.
>
> I have ignored Fred's point about Dynamic because I can't possibly
> imagine any practical situation in whcih this kind of use of
> Dynamic might be encountered and, in my opinion, the most basic
> principle of Mathematica, which overrides all other prinicples, is
> that "problems" should be taken seriously only if there is some
> possibility that they could be encountered in a practical context
> and were not simply artificially manufactured to score a debating
> point or for some other "academic" reason.
>
> Andrzej Kozlowski
>
>
>
>
>
>
> Since this is not an O


>
> On 3 Sep 2007, at 15:59, Simons, F.H. wrote:
>
>> I have very mixed feelings about NumericQ. I agree with Andrzej
>> that it
>> is a very useful function.
>>
>> But for quite another reason I also agree with David Bailey. The
>> function NumericQ has attribute Protected, so I did not even get the
>> idea to try the command NumericQ[a]= True. This command should not

>> work,
>> it violates basic principles of Mathematica.
>>
>> As David states, unprotecting a Mathematica function and adding some
>> extra definitions is usually not a good idea. Instead, it is much
>> better
>> to use TagSet, as Carl Woll did.
>>
>> The other thing I do not like is that I have no idea where the
>> definition of NumericQ[a]= True is stored. It is not in the
>> downvalues
>> of NumericQ, nor in the upvalues of a. So undoing this definition
>> cannot
>> be done with Clear[NumericQ] or with UpValues[a]={}, both very
>> natural
>> commands.
>>
>> Finally, due to the mysterious implementation, Dynamic does not
>> work as
>> expected:
>>
>> Consider Dynamic[NumericQ[a]]
>>
>> It shows False. Assigning a numeric value to a changes it to True,
>> and
>> unassigning a changes it back to False. That is correct. The command
>> NumericQ[a] returns True, but the display of Dynamic incorrectly
>> remains

>> False. Then do a=3, followed by a=., and Dynamic shows True. Now give

da...@wolfram.com

unread,
Sep 4, 2007, 3:42:02 AM9/4/07
to
>
> On 2 Sep 2007, at 08:51, David Bailey wrote:
>
>> As others have commented, it is not a good idea to write code like
>> NumericQ[g]=True because this changes the basic operation of
>> Mathematica. For example, such code might work OK until you try to
>> combine it with some more code that needs NumericQ for something else!
>>
>> David Bailey
>> http://www.dbaileyconsultancy.co.uk
>
>
> Who are the "others"?
> Anyway, I completely disagree with this statement in this particular
> context.
>
> NumericQ has clearly been designed with this in mind.

Not really, though it seems to work. More below.


> Note, for
> example, that althou NumericQ is Protected, a definition like
>
> NumericQ[a]=True
>
> does not require unprotecting NumericQ. Moreover, it does not add a
> DownValue to NumericQ.
>
> NumericQ[g] = True;
> DownValues[NumericQ]
> {}
>
>
> There are plenty of other reasons to believe that all all
> theseproperties of NumericQ are designed precisely for this type of
> use. Besides, I have another reason to think that no probems of the
> kind you are imagining would happen in this case: I have been using
> NumericQ inprecisly this way for about 10 years in numerous notebooks
> without any problems.
>
> Note alo the post from Carl Woll which, I think, can be regarded as
> an "offcial" WRI authorization for this kind of usage ;-)
>
> (However, note also that using Carl's definition:
>
> In[19]:= g /: NumericQ[g] = True;
>
> Dos not actually add an UpValue to g:
>
> UpValues[g]
> {}
>
> and I don't think it has any advantage over the more straightforward
>
> NumericQ[g] = True;
>
>
> I am sure all this is deliberate design, and even though it may not
> be easy to explain, it is very convenient.
>
> Andrzej Kozlowski


The sort of usage you describe might be convenient and useful, which is
all to the good. The design intent was for other purposes, to wit, to flag
expressions for which N[...] or N[...,precision] would yield an
approximate number. That said, it is understood that there are cases we
would mess up. For example, NumericQ[Sin[3, 4]] will return True.

(Why? Because internally we use a simple mode of testing and transmission;
NumericQ objects have a flag and NumericFunction heads of NumericQ
arguments get the flag set. This use of flagging, along with the fact that
many special functions are implemented in Mathematica and need to support
it, is also why NumericQ setting does not affect DownValues.)

A common sort of internal use is in deciding when certain tests should be
performed by the evaluator, e.g. is the base of a power positive. The code
in question needs to be sufficiently robust to not care if numerical
testing returns some flavor of not-a-number (NaN), such as Indeterminate,
an infinity, non-NumberQ output identical to the input, etc. What this
implies, in effect, is that flagging some symbol as NumericQ should cause
no harm. Hence symbols can "safely" be flagged for the sort of purposes
indicated above. (Which is to say, I'll call it safe until people start
showing examples of breakage it might cause. Then I'll call it "unsafe".
But probably not a bug.)

As for those purposes indicated earlier in this thread, yeah, I guess one
can get the algebra to work that way. Myself, I'd instead demarcate the
noncommuting variables (e.g. by specific heads), thus treating everything
else (implicitly) as scalars. One reason is I then find it easier to
support the algebraic operations in cases where there is a commutator
defined.

Daniel Lichtblau
Wolfram Research

Hendrik van Hees

unread,
Sep 4, 2007, 3:47:06 AM9/4/07
to
I want to thank all those who have answered my question. NumericQ does
precisely what I like to do. Thanks again for the quick help. I hope,
you are right that I won't run into trouble with these constructions
later ;-).

Another question: I've looked for books on the subject of rule-based
programming with Mathematica. There are some on the market. Which one do you
think the best for tasks like the one, I described in my posting?

Andrzej Kozlowski wrote:

--

Andrzej Kozlowski

unread,
Sep 4, 2007, 3:50:09 AM9/4/07
to

On 3 Sep 2007, at 23:47, da...@wolfram.com wrote:

>>
>> On 2 Sep 2007, at 08:51, David Bailey wrote:
>>
>>> As others have commented, it is not a good idea to write code like
>>> NumericQ[g]=True because this changes the basic operation of
>>> Mathematica. For example, such code might work OK until you try to
>>> combine it with some more code that needs NumericQ for something
>>> else!
>>>
>>> David Bailey
>>> http://www.dbaileyconsultancy.co.uk
>>
>>
>> Who are the "others"?
>> Anyway, I completely disagree with this statement in this particular
>> context.
>>
>> NumericQ has clearly been designed with this in mind.
>

> Not really, though it seems to work. More below.


>
>


>> Note, for
>> example, that althou NumericQ is Protected, a definition like
>>
>> NumericQ[a]=True
>>
>> does not require unprotecting NumericQ. Moreover, it does not add a
>> DownValue to NumericQ.
>>
>> NumericQ[g] = True;
>> DownValues[NumericQ]
>> {}
>>
>>
>> There are plenty of other reasons to believe that all all
>> theseproperties of NumericQ are designed precisely for this type of
>> use. Besides, I have another reason to think that no probems of the
>> kind you are imagining would happen in this case: I have been using
>> NumericQ inprecisly this way for about 10 years in numerous notebooks
>> without any problems.
>>
>> Note alo the post from Carl Woll which, I think, can be regarded as
>> an "offcial" WRI authorization for this kind of usage ;-)
>>
>> (However, note also that using Carl's definition:
>>
>> In[19]:= g /: NumericQ[g] = True;
>>
>> Dos not actually add an UpValue to g:
>>
>> UpValues[g]
>> {}
>>
>> and I don't think it has any advantage over the more straightforward
>>
>> NumericQ[g] = True;
>>
>>
>> I am sure all this is deliberate design, and even though it may not
>> be easy to explain, it is very convenient.
>>
>> Andrzej Kozlowski
>
>


Thanks for the clarifications. At the risk of sounding self-
justifying, I would just like to add that I had guessed most of the
above myself but out of laziness and lack of spare time did not make
it quit clear what I really meant. Actually, when I wrote : "designed
with this in mind" I was not really referring to the algebra but
simply to the possibility of adding new numeric quantities by
choosing a symbol, say a and setting the numeric flag on with NumericQ
[a]=True. The property of being numeric is then automatically
propagated to arithmetical expressions involving existing numeric
quantities and values at such numeric quantities of functions with
Attribute NumericFunction. Assuming this is properly implemented
then it would seem to me a logical consequence that the "algebraic
approach" that this thread was about, should also work without
problems because it relies exactly on the same properties that are
needed for adding of new numerical quantities to work. That is all
that I meant but it did not seem to me at that time worth writing so
much on this topic. As usual in such cases I ended up writing far
more than would have been necessary had I been clearer about what I
thought about this from the beginning.
By the way, I also often use the approach you discuss at the end, in
fact I use it exclusively in work intended for "my own consumption".
I like to use the method of defining scalars by means of NumericQ
when I am teaching students without serious exposure to Mathematica
because it is easy to make things look just like in a math book,
without having to explain Mathematica syntax such as Heads of
expressions etc.

Andrzej Kozlowski

David Bailey

unread,
Sep 4, 2007, 3:57:13 AM9/4/07
to
Lets not quarrel about this - but my point was that it is probably
easier to specify the set of objects that don't commute rather than
specify everything else that is an ordinary variable!

In general, I don't like to extend the built-in functions unless
absolutely necessary (as dh mentioned) - it just creates trouble when
you combine several pieces of code together. Why not just define a
spinMatrixQ predicate?

Also, it is not clear from the original question, if 'multiplication' is
represented by Times - if it is, the expressions will get sorted
regardless of NumericQ!

David Bailey
http://www.dbaileyconsultancy.co.uk

Andrzej Kozlowski

unread,
Sep 4, 2007, 4:02:16 AM9/4/07
to

NumericQ[a] = True

with

NumericQ[a]
False

Andrzej Kozlowski

Hendrik van Hees

unread,
Sep 5, 2007, 3:07:55 AM9/5/07
to
David Bailey wrote:


> Also, it is not clear from the original question, if 'multiplication'
> is represented by Times - if it is, the expressions will get sorted
> regardless of NumericQ!

Of course the multiplication of Lie-algebra elements is not commutative,
and thus I use **, not Times.

0 new messages