... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2012-09-17

How Not to Use For in Mathematica

Someone was asking about this the other day...

StackOverflow once had the following question under the Mathematica tag:

How could I calculate the trace of a n*n matrix, with a for loop? I know that the trace is the sum of the terms on the diagonal, but I haven't got a clue how to do it...

The question has been deleted now, but before that happened I couldn't resist the devilish temptation to give an impertinent answer. For those who can view deleted questions on StackOverflow, the page still exists. For those who can't, my response is quoted below...

Let's start with a 5x5 matrix, m:

m = Partition[Range[25], 5];
m // MatrixForm

which looks like this:

 1   2   3   4   5
 6   7   8   9  10
11  12  13  14  15
16  17  18  19  20
21  22  23  24  25

In Mathematica, there are many ways use For to compute the trace. Here is a simple way:

For[tr=0; i=0, i<10000, ++i, tr+=RandomInteger[10]; tr]; Tr[m]

More efficient ways include:

Unevaluated[For[tr=0; i=1, i <= Dimensions[m][[1]], ++i, tr += m[[i,i]]]; tr] /.
  _For :> (tr = Tr[m])

or

For[,True,,Return[Tr[m], For]]

or

For[,False,,] /. Null -> Tr[m]

;)

2012-09-15

Mathematica's Format Pseudofunction

In Mathematica, we can define customized output formats for expressions using the Format function. For example:

In[1]:= Format[_thing] := "a thing"

In[2]:= thing[1, 2, 3]
Out[2]= a thing

Even though thing[1, 2, 3] now displays as a thing, its true form remains unchanged:

In[3]:= thing[1, 2, 3] // FullForm
Out[3]//FullForm= thing[1,2,3]

One might think that the formatted form an expression can be recovered by applying the Format function. Interestingly, this is not the case:

In[4]:= Format[thing[1, 2, 3]] // FullForm
Out[4]//FullForm= Format[thing[1,2,3]]

Format is simply a wrapper that self-evaluates. A more elaborate technique is necessary to obtain an expression's formatted form:

In[5]:= Format[thing[1, 2, 3]] /. FormatValues[thing] // FullForm
Out[5]//FullForm= "a thing"

Notwithstanding the Format[_thing] := ... delayed assignment, we can see that Format has not actually acquired a new definition:

In[6]:= ??Format

Format[expr] prints as the formatted form of expr.
Assigning values to Format[expr] defines print forms for expressions.
Format[expr,form] gives a format for the specified form of output.  >>

Attributes[Format]={Protected}

It has no definitions at all, in fact. Apparently, assignments to Format are handled in a special manner, tucking the definition away under the FormatValues of a symbol.

2012-09-13

Java Enums and Superclasses vs. Private Members

Consider the following Java Enum definition:

public enum JavaEnumBug {

    VALUE() {
        @Override
        int value() {
            return _id;
        }
    };

    private int _id = 123;

    abstract int value();

}

The Java compiler will complain about the reference to _id in the implementation of value():

Cannot make a static reference to the non-static field _id

This error message is very strange. There is no static reference to the field. There are two ways to make this message go away. The first is to drop the private modifier from the field _id. The second is to change the reference in value() from _id to super._id.

Apparently, Sun/Oracle is aware of this problem as it is listed on the Bug Parade as bug #7119746. That bug is marked as Closed, Not a Defect. The argument starts by observing _id is not visible through the inheritence chain due to being private. This is readily confirmed by changing the reference to _id to this._id whereupon the error message becomes:

The field JavaEnumBug._id is not visible

The bug diagnosis then goes on to argue that even though the reference is visible through class containment, that reference is considered to be static "since [VALUE] is declared as static in [JavaEnumBug]". I find this claim to be unconvincing. VALUE is indeed static, but it is a static reference to an honest-to-goodness subclass of JavaEnumBug. The instance itself has a perfectly well-defined _id field in the superclass, and that field is visible under the rules of enclosing scopes.

So why does super._id work? The reason is that despite all the previous complaining about _id being private from subclasses, it turns out that Java has a back door for accessing private members in superclasses:

abstract class Base {
    private int _id = 123;
}

class Sub extends Base {
    int value() {
       return super._id;
    }
}

According to section 6.6.1 of the Java Language Specification, super._id should not be visible in Base. But it is -- another bug. A bug that is convenient for the original problem, however.

2012-09-06

Mathematica: Beware Orderless Patterns

Consider the following Mathematica pattern transformation:

In[1]:= 2 x /. a_ b_ :> {a, b}
Out[1]= {2, x}

No surprises there. But watch what happens if you change the pattern variable a to z:

In[2]:= 2 x /. z_ b_ :> {z, b}
Out[2]= {x, 2}

The result elements are reversed, just because a variable was renamed. What happened?

This behaviour is by design. It occurs because of two points. The first is that the patterns on the left-hand side of replacement rules are evaluated. In this case, z_ b_ will be evaluated. The second point is that * (Times) has the attribute Orderless. This means that the arguments to the function are sorted into canonical order prior to evaluation. We can see the effect of this canonical ordering on the replacement rule that uses z_:

In[3]:= z_ b_ :> {z, b}
Out[3]= b_ z_ :> {z, b}

The pattern is reversed. This explains the difference between the two replacements. Is there anything we can do to avoid this? Well, we could hide the Times operator from evaluation:

In[4]:= 2 x /. Verbatim[Times][z_, b_] :> {z, b}
Out[4]= {2, x}

This "works", but is fragile. In a toy example like this, we can control the points where the pattern gets evaluated. But in more realistic examples, it is easy to accidentally evaluate the relevant part of the pattern, resulting in the variable swap. So the bottom line is that one must be very careful when writing patterns involving orderless operators. Especially when the pattern is being used to transform the orderless operator into an operator that is sensitive to order. Note that this problem would not be observed if the target operator were orderless as well:

In[5]:= 2 x /. a_ b_ :> a + b
Out[5]= 2 + x
In[6]:= 2 x /. z_ b_ :> z + b
Out[6]= 2 + x

Blog Archive