MathGroup Archive 1994

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

Search the Archive

REProblems with MeshRange in ListContourPlot3D

  • To: mathgroup at christensen.Cybernetics.NET
  • Subject: [mg287] RE[mg232] Problems with MeshRange in ListContourPlot3D
  • From: twj (Tom Wickham-Jones)
  • Date: Mon, 5 Dec 1994 11:00:09 -0600

David M. Wood writes

>   I've had no success in using the MeshRange option of  
ListContourPlot3D.
>The function browser (and inspection of the package ContourPlot3D.m  
itself) 

>shows MeshRange as an explicit option for ListContourPlot3D, and  
?MeshRange 

>alleges that

There is a bug in the Version 2.2 shipping version of the package 

Graphics`ContourPlot3D` affecting the use of the ContourPlot3D
command.  A fixed version of the package is available from
MathSource item# 0204-725.   With this new package

data = Table[x^2 + 2*y^2 + 3*z^2,
    {z, -1, 1, .25},
    {y, -1, 1, .25},
    {x, -1, 1, .25}]; 

ListContourPlot3D[data,
    MeshRange -> {{-1,1}, {-1,1}, {-1,1}},
    Contours -> {1.5},
    Axes -> True,
    PlotPoints -> {5,3}] 


generates a plot with axes that go from 0-1 in all dimensions.


Tom Wickham-Jones
WRI






From mathgroup-adm at christensen.cybernetics.net Mon Dec  5 13:14:57 1994
Received: from dragonfly.wri.com by lead.wri.com with SMTP id AA29493
  (5.67b/IDA-1.4.4 for <sw>); Thu, 8 Dec 1994 07:08:19 -0600
Received: from christensen.cybernetics.net. (christensen.cybernetics.net) by dragonfly.wri.com with SMTP id AA15160
  (5.67b/IDA-1.4.4 for <wri-mathgroup at wri.com>); Thu, 8 Dec 1994 07:06:39 -0600
Received: by christensen.cybernetics.net. (5.0/SMI-SVR4)
	id AA24334; Wed, 7 Dec 1994 02:35:18 +0500
Received: by christensen.cybernetics.net. (5.0/SMI-SVR4)
	id AA24329; Wed, 7 Dec 1994 02:35:17 +0500
Message-Id: <9412070735.AA24329 at christensen.cybernetics.net.>
Date: Mon, 5 Dec 1994 07:14:57 -0600
From: villegas (Robert Villegas)
Subject: [mg285] how to circumvent renaming of variables
To: mathgroup at christensen.cybernetics.net
Content-Length: 6916

Scott,

   After explaining why renaming of function variables happens, I should
have offered some ways to circumvent it, since sometimes it is useful to
do so.

First, let me elaborate a bit on one general principle I stated in
my previous email:

> When you nest function definitions, the local variables of the inner one
> will get renamed (by appending "$") any time the formula (i.e. the body)
> of the inner one contains occurrences of the local variables of the outer
> one.

This principle applies not just to function assignments (Set and
SetDelayed), but also to other programming constructs you are
familiar with:  Module, With, and Function, and also the rules Rule
and RuleDelayed.  All of these (can) involve local variables, and all
are called static scoping constructs (or lexical scoping constructs).
So a more encompassing statement of the principle is:


>>>>>
In nested lexical scoping constructs, if the body of the inner
one contains local variables of the outer one that are not also
local variables of the inner one, then the local variables of the
inner one will get renamed."
<<<<<


This principle applies to my example assign[c_] := (f[x_] := c x)
because a fuller form of this function definition is

SetDelayed[assign[c_],
  SetDelayed[f[x_], c x] ]

SetDelayed is one of those things that is recognized as a scoping
construct.  So when I use the 'assign' function (which is a SetDelayed
construct), it looks for other scoping constructs inside it to see
if any of them have c in the body.  It finds SetDelayed[f[x_], c x], which
does have c in the body, so it renames the x to x$.  This
all occurs as a preliminary to actually evaluating the body of
'assign', which is why by the time the f assignment is performed, the
variable has already been replaced.

This is even better illustrated by contrasting the effect on two
function assignments, one with c and the other without c:

In[1]:= Clear[assign, f]

In[2]:= assign[c_] := Hold[ f[x_] := c x, g[x_] := x^3 + 1 ]

In[3]:= assign[3]

                                        3
Out[3]= Hold[f[x$_] := 3 x$, g[x_] := x  + 1]

g was not going to get any interference from the variables of 'assign'.


   The key to circumventing the renaming is in that preliminary stage:
if you could prevent the outer SetDelayed construct from seeing the
inner one, there would be no renaming to do.  Here is a way to do that:

In[4]:= Clear[assign, f]

In[5]:= assign[c_] := Apply[SetDelayed, Hold[f[x_], c x] ]

In[6]:= assign[3]

In[7]:= ? f
Global`f

f[x_] := 3*x

The right-hand side of 'assign' doesn't contain any actual uses of
SetDelayed, just the naked symbol SetDelayed, and its intended arguments
stored separately in a Hold (to prevent them from evaluating).
This method constructs the SetDelayed assignment from its parts
during the evaluation, so it doesn't exist until run-time.  You
can construct assignment statements just like any other expressions.

In your 'delay' function, this becomes (using prefix notation for Apply,
"@@", so we don't have to use as many brackets):

SetDelayed @@ Hold[ f[s_], Evaluate[(y /. Flatten[sol]) [s-T]] ]

Notice that the Evaluate should be wrapped around the whole right-hand
side, not just the (y /. Flatten[sol]) portion.


Another way, very similar, is to make a function that does
SetDelayed, but isn't called SetDelayed, so it won't be recognized
as special:

Attributes[DisguisedSetDelayed] = HoldAll

DisguisedSetDelayed[lhs_, rhs_] := (lhs := rhs)


In[10]:= Clear[assign, f]

In[11]:= assign[c_] := DisguisedSetDelayed[f[x_], c x]

In[12]:= assign[3]

In[13]:= ? f
Global`f

f[x_] := 3*x


Still another way is to disguise the assignment as a string, and
convert it to an expression during evaluation:

In[15]:= Clear[assign, f]

In[16]:= assign[c_] := ToExpression["f[x_] := c x"]

In[17]:= assign[3]

In[18]:= ? f
Global`f

f[x_] := c*x


These methods, and others you could cook up, have in common that the
assignment itself never appears in the code for the 'assign' function.
It materializes at run-time.


It should be mentioned that Block doesn't participate in any of this.
It is a dynamic scoping construct.  It should also be mentioned that
if Condition is inside one of those other constructs, it can undergo
variable-renaming.  I didn't mention it earlier since it isn't used as
a command, like the others are.



   A good quick tour of scoping in general, which really helped me form an
understanding of the issues, is an article in _The Mathematica Journal_,
Volume 1 Issue 3 (Version 2.0 Special from Winter of 1991).  The article
is "Scoping of Symbols and Values", by Roman Maeder.  Roman's book
_Programming in Mathematica_ (second edition) contains a discussion of
the issues in section 5.6.

The Mathematica book itself (version 2) has the most complete
description I know of, in sections 2.6.1 through 2.6.7.  The one
that addresses renaming is 2.6.4.  I strongly recommend working through
these sections.


   I'll end with some examples showing how to test for yourself when
renaming happens.  This is quite valuable to know.


(***** With on the outside, other things on the inside *****)

In[1]:= With[{a = 3, b = 4, c = 5},
          HoldForm[ f[x_] := a x^2 + b x + c ]
        ]

                      2
Out[1]= f[x$_] := 3 x$  + 4 x$ + 5

In[2]:= With[{a = 3, b = 4, c = 5},
          x_ -> a x^2 + b x + c
        ]

                              2
Out[2]= x$_ -> 5 + 4 x$ + 3 x$

In[3]:= With[{a = 3, b = 4, c = 5},
          Module[{x}, a x^2 + b x + c] //HoldForm
        ]

                         2
Out[3]= Module[{x$}, 3 x$  + 4 x$ + 5]


(***** Set on the outside, other things on the inside *****)

In[4]:= f[a_] = HoldForm[ With[{x = 0}, x^2 + a] ]                


                       2
Out[4]= With[{x = 0}, x  + a]

In[5]:= f[10]

                         2
Out[5]= With[{x$ = 0}, x$  + 10]

In[6]:= f[a_] = HoldForm[ x_ :> x^2 + a ] 


               2
Out[6]= x_ :> x  + a

In[7]:= f[10]

                 2
Out[7]= x$_ :> x$  + 10


(*****  An example with Condition, which you won't use by itself,
but inside of another thing:
*****)

In[14]:= With[{a = 2},
           Condition[x_, x + a > 5] //HoldForm
         ]

Out[14]= x$_ /; x$ + 2 > 5




(*****
If the outer construct is Module, With, or Function, then inner construct
protects (scopes) all its own variables.  This means that if all the
potential name conflicts are local variables of the inner construct,
renaming won't happen:
*****)

In[15]:= With[{a = 1, b = 2},          

           HoldForm[ f[a_, b_] := a^3 - b^3 ]
         ]

                       3    3
Out[15]= f[a_, b_] := a  - b



A template for these examples would be something like

OuterConstruct[vars,
  HoldForm[ InnerConstruct[vars, body] ]
]

where 'vars' can be either the local variable declaration or the pattern
in a function assignment or transformation rule.


Robby Villegas
Wolfram Research





  • Prev by Date: Mathematica as a Tool
  • Next by Date: Re: contour values with ContourPlot
  • Previous by thread: Mathematica as a Tool
  • Next by thread: Re: contour values with ContourPlot