MathGroup Archive 2003

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

Search the Archive

Re: What Happens to Garbage in Mathematica?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg44071] Re: What Happens to Garbage in Mathematica?
  • From: Olaf Rogalsky <olaf.rogalsky at theorie1.physik.uni-erlangen.de>
  • Date: Tue, 21 Oct 2003 02:07:44 -0400 (EDT)
  • References: <bm84s2$fug$1@smc.vnet.net> <bmg0nf$e9t$1@smc.vnet.net> <bmj2j5$pqs$1@smc.vnet.net> <bmqqao$rjs$1@smc.vnet.net> <bmt7tc$857$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

"Steven T. Hatton" wrote:
> There are times when strange things happen after changing the internals of a
> function which seem to indicate a variable other than the intended one is
> being accessed.  If I kill the kernel and reevaluate the function, it then
> works.  I don't have a specific example, but it is not all that uncommon,
> especially if I fail to clear all variable in use.  The goes beyond simply
> reading a variable I expect to be in scope, but neglected to clear.

This is a bit too unspecific to comment on it.


> This has an interesting consequence which, if I'm understanding things
> correctly, is relevant to my current situation.  I am trying to create a
> generic way of producing graphical representations of coordinate mapping
> wherein the coordinate curve frequencies are lower than the point density
> along the curves.  IOW, I'm trying to smoothe out the curves.
> 
> I originally thought it would be a good idea to share the points between
> curves where they intersect.  There may still be advantages to doing so,
> but they don't include memory conservation. If I have the following:
> 
> p1={0,0,0};
> p2={1,1,1};
> p3={2,2,2};
> p4={2,0,0};
> p5={0,2,2};
> 
> Show[Graphics3D[
>     Join[{Red,PointSize[0.02],Line[{p1,p2,p3}],Line[{p4,p2,p5}]},
>       Point/@{p1,p2,p3,p4,p5}]]]
> 
> There will be memory allocated for each usage of the coordinate values. For
> example, mathematically, p2 is shared by both lines, but the values are
> reproduced for each primitive. Is this the way you understand the
> situation?


Yes, you are constructing a new Graphics3D object with 3 copies of "p2", 
which are not memory shared. In the following example things are 
apparently different:

In[1]:=  imax = 10000;
         b = Table[Null, {i, imax}];
         MemoryInUse[]
         a = Range[10000000];
         MemoryInUse[]
         Do[b[[i]] = a, {i, 1, imax}];
Out[3]=  2360528
Out[5]=  42362096
Out[7]=  42403104

Here, "a" roughly takes 40MB, whereas "b" only eats up 40kB, though "b"
consists of 10000 copies of "a". Actually "b" has not 10000 copies of "a",
but 10000 references to the value of "a", which is much cheaper. To achieve 
the same effect in your example, one has to do something like this:

g = Graphics3D[
      Join[{Red,PointSize[0.02],Line[{p1,dummy,p3}],Line[{p4,dummy,p5}]},
        Point/@{p1,dummy,p3,p4,p5}]]
g[[1, 3, 1, 2]] = p2;
g[[1, 4, 1, 2]] = p2;
g[[1, 6, 1]] = p2;
Show[g]


> This seems to mean shape could be a list of different primitives, and all
> would be transformed by the appropreate rule.  Is this correct?

Short answer: yes, longer answer:
The first rule matches any subexpression, where the head of the subexpression
is "Polygon", and the body of the subexpression is a single element sequence.
"shape" could be any expression, where all subexpressions, which match any of
the given rules, will be replaced. If "shape" had a "Rectangle" subexpression,
it would not be rotated, since no rule is defined for this shape.


> "a" is an identifier, which has a location in memory containing the
> character code for 'a', as well as either the value assigned to it, or the
> address of a memory location holding the value.  From what you said, I have
> conclude that if I have the following:
> 
> reallyLongVariableName=1;
> a=reallyLongVariableName;
> reallyLongVariableName=2;
> b=reallyLongVariableName;
> reallyLongVariableName=3;
> c=reallyLongVariableName;,
> 
> a,b and c will reference a place in memory holding the string
> "reallyLongVariableName", as well as the values 1,2 and 3 respectively.  Is
> this correct?

No, a, b and c directly refernce the memory locations, which were bound to
reallyLongVariableName, when the assignment was made. I drawe a picture for 
you (rectangles denote memory locations, adjacent rectangles dentote adjacent 
memory locations, the content of a rectangle denotes the content of that memory
location, an arrow denotes the addresses of the memory location of the object the 
arrow is pointing to):

reallyLongVariableName=1;

+------------------------+
I"reallyLongVariableName"I
+------------------------+        +---+
|          --------------+------> I 1 I
+------------------------+        +---+

a=reallyLongVariableName;

+------------------------+                     +---+
I"reallyLongVariableName"I                     I"a"I
+------------------------+        +---+        +---+
|          o-------------+------> I 1 I <------+-o I
+------------------------+        +---+        +---+

reallyLongVariableName=2;

+------------------------+                     +---+
I"reallyLongVariableName"I                     I"a"I
+------------------------+        +---+        +---+
|          o-------------+--+     I 1 I <------+-o I
+------------------------+  I     +---+        +---+
                            I
                            +     +---+
                            +---> I 2 I
                                  +---+
b=reallyLongVariableName;


+------------------------+                     +---+   +---+
I"reallyLongVariableName"I                     I"a"I   I"b"I
+------------------------+        +---+        +---+   +---+
|          o-------------+--+     I 1 I <------+-o I   I o I
+------------------------+  I     +---+        +---+   I-+-I
                            I                            I
                            +     +---+                  I
                            +---> I 2 I <----------------+
                                  +---+

and so on.


> >> It would seem that if I were to assign the return value of RotateShape[]
> >> to lna like this: lna = RotateShape[ln, 2, 2, 2], I would create a dirty
> >> chunk of memory which will require housekeeping before it can be reused.
> >
> > I don't understand you here.
> 
> If I have a complex shape which is transformed by the above rotation
> function, the location of the original coordinate values will not be
> available until garbage collection is run.  Correct?

Double no :-). No, "ln" still refernces the orignal shape, so its memory
can't be reused. And no, Mathematica doesn't garbage collect at all. If
the unrotated shape eventually becomes unreferenced by all live objects,
Mathematica automatically detects this, and the memory immediately will be
given back to you:

a=0;                              +---+    
                                  I 0 I <--+    
+------------------------+        +---+    I   +---+   +---+
I"reallyLongVariableName"I                 I   I"a"I   I"b"I
+------------------------+        +---+    I   +---+   +---+
|          o-------------+--+     I 1 I    +---+-o I   I o I
+------------------------+  I     +---+        +---+   I-+-I
                            I                            I
                            +     +---+                  I
                            +---> I 2 I <----------------+
                                  +---+

The memory location for "1" now is unreferenced, and will be given back to
you immediately.

> > There is an overhead to this, but don't worry too much. Mathematica is
> > an interpreted language, which does a lot of symbolic manipulations.
> > E.g. in your problem, the pattern matching propably is much more expensive
> > than the memory management.
> 
> I had an interesting experience while working with my own transformation
> functions.  I noticed that each frame of my animation took progressively
> longer than the previous one, but the operations in each frame were
> identical.  What I discovered was the values of the rotation matrices were
> remaning symbolic expression which grew more complex with each iteration
> since they resulted from an application of the transfromations to the
> previous frame's results.  Once I put in //Ns in the apropriate places, the
> frames all processed in equal (and _much_ shorter times.

Yes, thats reasonable. Those large symbolic expressions not only
take memory away, but computing power as well.

Olaf

-- 
+-------------------------------------------------------------------+
I Dr. rer. nat. Olaf Rogalsky     Institut fuer Theoretische Physik I
I                                 Universitaet Erlangen-Nuernberg   I
I Tel.: 09131 8528440             Staudtstr. 7 B3                   I
I Fax.: 09131 8528444             D-91058 Erlangen                  I
| rogalsky at theorie1.physik.uni-erlangen.de                          I
+-------------------------------------------------------------------+


  • Prev by Date: Re: Mystery: NIntegrate'ing indeterminate-length integrand!
  • Next by Date: Multiple sum excluding some terms
  • Previous by thread: Re: What Happens to Garbage in Mathematica?
  • Next by thread: Re: What Happens to Garbage in Mathematica?