MathGroup Archive 1989

[Date Index] [Thread Index] [Author Index]

Search the Archive

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
  • Reply-to: steve at ncsa.uiuc.edu

[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'.

	(3) FOR WRI (!!!) (Please)
		(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
		    to read)... 
		(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
	(2) Sun4 incorrect answer
	(3) A file for replicating the problem


Thanks in advance!

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
   Copyright 1988 Wolfram Research Inc.
   -- Terminal graphics initialized --

   In[1]:= <<EconoMod.m
   Loading in EconoMod application packages
   Finished loading in EconoMod package 

   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
   Copyright 1988 Wolfram Research Inc.
   -- SunView graphics initialized --

   In[1]:= <<EconoMod.m
   Loading in EconoMod application packages
   Finished loading in EconoMod package 

   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
   Copyright 1988 Wolfram Research Inc.
   -- 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
  • Previous by thread: mathgroup email addresses
  • Next by thread: Re: Mathematica bug on Sun4