Mathematica bug on Sun4

• To: mathgroup
• Subject: Mathematica bug on Sun4
• From: sdoyle at fed.frb.gov
• Date: Fri, 5 May 89 09:10:53 CDT

```[See the follow up note to this one regarding the fix of this problem
in 1.2 beta. - smc]

A tale of two Suns ( 3/60 and a 4/260)

It was the best of Suns, it was the worst of Suns.

I've been having some trouble with segmentation violations and/or bus errors
on a Sun4 that do not occur on a Sun3. Both machines are running version 1.1.

As is true of most memory type bugs, they are hard to program around if
one doesn't know the underlying algorithms. If I use On[] or Debug[]
to attempt to isolate the problem, usually it `goes away'. However, if
the Sun4 does return an answer, it is sometimes incorrect.

I can't replicate the segmentation violations with the test file (appended
below), but I can replicate the incorrect answers. Hopefully these problems
have a common root.

Before I get to the code, it might help to explain what its purpose is.
In economic models one often has variables that have a time subscript, such
as GNP[T], where T represents the current time. Lag operators are used to
increment (or decrement) the time index. If we represent the lag operator
as L, we have the following relationships:

L GNP[T]   = GNP[T-1]
L^2 GNP[T] = L GNP[T-1] = GNP[T-2]

One can even have polynomials in the lag operators:

(1 + L) GNP[T] =  GNP[T] + GNP[T-1]
(1 - L) GNP[T] =  GNP[T] - GNP[T-1]

The lag operator L has been implemented in Mathmatica as the operator
LagOperator[n]. Delta[n] expands to (Identity - LagOperator[n]). The code
treats Identity and LagOperator[n] as scalar expressions in polynomials
until they are applied to expressions that have time indexes. Then they
are converted to Function[]s and applied using Through[] and MapAt[].
This is done because Mathematica's built-in rules handle scalar value
polynomials much better than function-valued polynomials.

Now... the bottom line(s):
(1) Could someone see if this is a problem under 1.2? Or... is
there an obvious problem with the code (even though it works
on the 3/60?)

(2) Can I get 1.2 here (even in beta release?). Normally
I would try to be patient, but I'm leaving here June 1
for another job, and I'll only have limited Mathematica
access in the future (sigh...)

In return for getting 1.2, I promise to beat on it very
hard before I go. So far I've built a slot-and-filler
database for storing model files, tools for manipulating
models algebraically, and formatting out TeX and C versions...
and more!

The database is very general and is has nothing to do with
economic models. Once one has defined the attributes of
a `class', all of the database commands for storing or
retrieving information are defined.

I'll have something to post before I `retire'.

(a) Any hints on debugging 1.1 applications? There is
another nasty memory bug lurking in my code that I
can't seem to isolate. On[] and Debug[] both have
side effects on the environment... often I will get
a `segmentation violation' or `bus error' while
running a program which works fine when On[] or
Debug[] are used. I'm not doing anything weird
in the code (e.g., Raw[]).
(b) Is there any way of figuring out where I'm
straining Mathematica? I have about 4500 lines of
code (including comments!). I don't know anything
about how many rules Mathematica can handle, nor what
the tradeoffs are in how complex conditions are for
controlling the application of rules (I tend to build
a lot of predicate functions to make the code easier
(c) What should I avoid using in 1.1? (If I can't get
1.2 here, perhaps at least I can leave behind
robust code). Most of the problems I've had are
with assignment in programs that are deeply nested,
or with Match[]/Select[] on lists which are
nested within my database procedures... I'm sorry
I can't be more specific, but I'm having trouble
isolating the problems (small programs tend to work
fine).

The rest of this message is three parts:
(1) Sun4 segmentation violation
(3) A file for replicating the problem

Sean Doyle

*************** PART 1: Sun 4 segmentation violation ***********************

Sun4:
os4cs1(25)% math
SunMathematica (sun4) 1.1 (September 17, 1988) [With pre-loaded data]
by S. Wolfram, D. Grayson, R. Maeder, H. Cejtin,
S. Omohundro, D. Ballman and J. Keiper
-- Terminal graphics initialized --

In[1]:= <<EconoMod.m

In[2]:= Delta[1] Delta[100] Delta[3]
Segmentation fault
os4cs1(26)%

Now... output from my trusty (but slow) 3/60:
mqws2(155)% math
SunMathematica (sun3.68881) 1.1 (September 14, 1988) [With pre-loaded data]
by S. Wolfram, D. Grayson, R. Maeder, H. Cejtin,
S. Omohundro, D. Ballman and J. Keiper
-- SunView graphics initialized --

In[1]:= <<EconoMod.m

In[2]:=  Delta[1] Delta[100] Delta[3]
0.25 Second

3
Out[2]= ApplyLag[Identity  - LagOperator[1] - LagOperator[3] +

2
>        LagOperator[4] - Identity  LagOperator[100] + LagOperator[101] +

>        LagOperator[103] - LagOperator[104]]

We also see that the answer it correct, since it is just expanding a
polynomial. Delta[n] expands to to the polynomial (1-LagOperator[n]), and
LagOperator[n]^x becomes LagOperator[n*x], so we can simulate this below
using the scalar L:

In[3]:= (1-L)(1-L^100)(1-L^3)
0.

3        100
Out[3]= (1 - L) (1 - L ) (1 - L   )

In[4]:= ExpandAll[%]
0.166667 Second

3    4    100    101    103    104
Out[4]= 1 - L - L  + L  - L    + L    + L    - L

The `Identity^n' terms in Out[2] are simplified (in the rules for ApplyLag)
before they applied as operators to an expression.

*************** PART 2: Sun 4, wrong answer  ***********************

If I use On[] with the Sun 4, it will generate an incorrect answer instead
of a segmentation violation. Here is the last part of the trace:

ShowTime::trace:
ShowTime[Delta[1] Delta[100] Delta[3]] -->
3                            2
ApplyLag[Identity  - LagOperator[1] - Identity  LagOperator[1] +
LagOperator[2] - LagOperator[3] + 2 LagOperator[4] -
LagOperator[5]].

3                            2
Out[3]= ApplyLag[Identity  - LagOperator[1] - Identity  LagOperator[1] +

>        LagOperator[2] - LagOperator[3] + 2 LagOperator[4] - LagOperator[5]]

This is clearly the wrong polynomial. To try to isolate the problem I created
a file `lagbug.m' that had most of the lag-operator related code (it excludes
the Format[] rules). While I don't get a segmentation violation, I do
get the same (wrong) answer on the Sun 4 as when I used On[]:

os4cs1(55)% math
SunMathematica (sun4) 1.1 (September 17, 1988) [With pre-loaded data]
by S. Wolfram, D. Grayson, R. Maeder, H. Cejtin,
S. Omohundro, D. Ballman and J. Keiper
-- Terminal graphics initialized --

In[1]:= <<lagbug.m

In[2]:= Delta[1] Delta[100] Delta[3]

3                            2
Out[2]= ApplyLag[Identity  - LagOperator[1] - Identity  LagOperator[1] +

>        LagOperator[2] - LagOperator[3] + 2 LagOperator[4] - LagOperator[5]]

On the 3/60 the correct answer is returned.
*************** PART 3: lagbug.m file **********************

(* 		L a g O p e r a t o r

The LagOperator package contains several definitions and tools
for manipulating Lag operators in EconoMod objects and expressions.

[Note: some of these comments refer to other parts of the package. I
could have deleted them, but then I thought people might be interested
in what other users are up to...

One of the main excluded portions here are the objects that the lag
operators are applied to. When this all works [ :-) ] I'll post that
to the net.
]

*)
BeginPackage["LagOperator`"]

ApplyLag::usage=
"ApplyLag[lagpoly][expr] applies the lag polynomial to expr.
ApplyLag[lagpoly1]*ApplyLag[lagpoly2] will multiply the polynomial
expressions in the normal Mathematica fashion."

LagOperator::usage=
"LagOperator[n] is the internal representation of the Lag
operator \"L\". LagOperator[n][expr] applies the lag operator to expr."

Delta::usage=
"Delta[n][expr] applies the lag polynomial (1-L^n) to the
expression."

MovingAverage::usage=
"MovingAverage[n][expr] applies the lag polynomial\n
\t ((1/n) (1 + L + L^2 + ... + L^(n-1) )) \n
to the expression."

MovingTotal::usage=
"MovingTotal[n][expr] applies the lag polynomial\n
\t  (1 + L + L^2 + ... + L^(n-1) ) \n
to the expression."

LagPolynomial

Begin["`Private`"]
(* Initialize functions *)

(* ********************************************************************
LagOperator functions and utilities
******************************************************************** *)

(* **** Evaluation ****
ApplyLag is a Mathematica object that performs two functions:
(1) It `holds' lag polynomials in an unevaluated form. These
polynomials can be further manipulated (i.e., raised to a
power, etc..)
(2) When ApplyLag is followed by an expression, a rule is
fired (LagFunction) that transforms the lag polynomial
to a Function[] and then uses Through to distribute the
lag operators through the expression.

Digression: These two steps are necessary. Once the lag polynomial
is in Function[] form, one can't use any of the Expand[] or other
polynomial manipulation tools on it. So, if we defer tranforming the
polynomial into a Function[] until we are ready to apply the lag
operators, we can keep some flexibility about nesting lag polynomials
such as
Delta[x] Delta[y] expr
Delta[x]^2 expr

*)

ApplyLag[lagopts_][expr_]:=Through[LagFunction[lagopts] [expr],Plus]

ApplyLag/: ApplyLag[x_] ApplyLag[y_]:= ApplyLag[ExpandAll[(x)(y)]]

ApplyLag/: Power[ApplyLag[x_],n_]:= ApplyLag[ExpandAll[Power[x,n]]]

(* LagFunction[] maps the lag polynomial into a Function[] object.

Note the slight kludge of mapping Identity^n to Identity. This
is necessary because Identity may have been raised to a power in some
polynomial transformation. While a rule could have been specified
elsewhere for this, Identity is a Mathematica entity and I didn't
want to mess it up with a rule.
*)
LagFunction[lagpoly_]:=
(lagpoly /. {
Identity^n_->Identity[#],
Identity->Identity[#],
LagOperator[lag_]->LagOperator[lag][#]
})&

(* ********** Algebra of lag operators ************ *)
(* Higher level lag operators *)
Delta/: Delta[lag_]:=
ApplyLag[(Identity - LagOperator[lag])]

MovingTotal/: MovingTotal[lag_]:=
ApplyLag[Sum[LagOperator[i],{i,0,lag-1}]]
MovingAverage/: MovingAverage[lag_]:=
ApplyLag[(1/lag)*Sum[LagOperator[i],{i,0,lag-1}]]

LagPolynomial[CoefPlaceHolder[name_,{}],degree_]:=
ApplyLag[Sum[CoefPlaceHolder[name,i] LagOperator[i],{i,0,degree-1}]]

(* ************ LagOperator algebra     *********** *)

(* Simplification rules *)
LagOperator/: LagOperator[n_]*Identity := LagOperator[n]

(* Product of two LagOperators *)
LagOperator/: LagOperator[n1_] * LagOperator[n2_]:= LagOperator[n1+n2]

(* Powers of LagOperators *)

LagOperator/: LagOperator[n_]^exp_ := LagOperator[n*exp]

(* L^0 is the Identity function *)
LagOperator[0]:= Identity

(* ****** Application of lag operators to objects ******* *)

(* Case #1: Application of LagOperator to ANY class containing a LagOffset.

If future class types (TimeVaryingCoef, for example) have the same
general form as DiscreteVariable/ContinuousVariable, this rule will work
for them as well. *)
LagOperator[lag_][class_[Name[x_],LagOffset[n_]]]:=
class[Name[x],LagOffset[n-lag]]

(* Case #2: Application of LagOperator to all other EconoMod classes *)
LagOperator[lag_][class_[Name[x_],contents_]]:=	class[Name[x],contents]

(* Case #3: Primitive Mathematica objects *)
LagOperator[lag_][x_Symbol]:= x
LagOperator[lag_][x_?NumberQ]:= x
LagOperator[lag_][x_String]:= x

(* Case #4: Application of LagOperator to an expression. The positions
of the time-varying objects are located using Position[], and then
only those objects have the lag applied.*)
LagOperator[lag_][x_]:=Block[{positions},
positions = Position[x,class_[name_,LagOffset[xxx___]]];
If[SameQ[positions,{}],
Return[x],
Return[MapAt[LagOperator[lag][#] &, x, positions]]
]]

End[]
EndPackage[]

********************* End of lagbug.m **********************

Sean Doyle
Board of Governors of the Federal Reserve System
20 and Constitution, NW  Mail Stop 76  Washington, DC 20551
(202) 452-2352  uucp: uunet!fed!m1swd00 , internet: sdoyle at fed.frb.gov

----- End Included Message -----

```

• Prev by Date: mathgroup email addresses
• Next by Date: lagbug.m