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 -----