MathGroup Archive 1995

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

Search the Archive

Re: What's this Mathematica function called?

  • To: mathgroup at
  • Subject: [mg952] Re: What's this Mathematica function called?
  • From: villegas (Robert Villegas)
  • Date: Thu, 4 May 1995 02:04:01 -0400
  • Organization: Wolfram Research, Inc.

In article <3npos0$od2 at> martind at  
(D<martind at>M) writes:

> First let me apologize for what I'm pretty certain is a question
> that I could find if only I searched through the big black book
> long enough.  However, I am unable to find an answer anywhere in
> the index, so I'll ask it here.
> What is Mathematica function that determines if one expression
> depends on another?  i.e. if this function were called Depends, it
> would give output something like this:
> Depends[x + 3, x]
> ==> True
> Depends[y, x]
> ==> False
> y := x^2
> Depends[y, x]
> ==> True
> Depends[f[g[x]], x]
> ==> True
> Depends[f[g[y]], x]
> ==> True
> Clear[y]; Depends[f[g[y]], x]
> ==> False

   If the variable x (or whatever expression) that you want to find
occurs as an operand in a sum, product, or the like, or is an argument of
a function, then MemberQ will detect it.  At its default, MemberQ checks
only the main elements (level 1), so in (x + y^2 + ArcSinh[z]) it will  
x, but it will miss y and z because they are deeper than level 1.

In[1]:= MemberQ[x + y^2 + ArcSinh[z], x]

Out[1]= True

In[2]:= MemberQ[x + y^2 + ArcSinh[z], y]

Out[2]= False

In[3]:= MemberQ[x + y^2 + ArcSinh[z], z]

Out[3]= False

However, we can tell MemberQ to sweep through every level of the
expression looking for x, from the whole down to the atoms,
by giving an extra argument of {0, -1} (called the _level specification_).
Here are some examples of finding symbols, or more complex objects, in
some expressions.

In[4]:= MemberQ[x, x, {0, -1}]

Out[4]= True

In[5]:= MemberQ[x + 3, x, {0, -1}]  

Out[5]= True

In[6]:= MemberQ[x + y^2 + ArcSinh[z], z, {0, -1}]

Out[6]= True

Let's try a case where the item we want is submerged pretty far:

In[7]:= cont = Nest[1 + (1 + 1/#^2)^-1 &, x, 4]

Out[7]= 1 + -------------------------------------------
                                      1                -2
              1 + (1 + -------------------------------)
                                         1          -2
                       1 + (1 + -------------------)
                                            1    -2
                                1 + (1 + -------)
                                         1 + x

In[8]:= MemberQ[cont, 1 + x^-2, {0, -1}]

Out[8]= True

Position tells us how many coordinates it takes to pinpoint the
object, and hence how deep it is:

In[9]:= Position[cont, 1 + x^-2]

Out[9]= {{2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1}}

In[10]:= Length @ First[%]

Out[10]= 14

See pp. 197-199 of the second edition of the Mathematica book for a
discussion of levels.  Section 2.3 talks about MemberQ and related

MemberQ, like its cousins Cases, Position, et al, can deal with a pattern,
too.  Examples of more generic searches:

In[11]:= MemberQ[cont, 1 + x^_, {0, -1}]

Out[11]= True

In[12]:= MemberQ[cont, 1 + _^-2, {0, -1}]

Out[12]= True

What I gave won't detect the p in T[p][x, y], though.  Here, the p
is inside the head T[p] of the expression, but MemberQ ignores heads.
You can tell it not to with the option Heads->True.

In[13]:= MemberQ[T[p][x, y], p, {0, -1}]

Out[13]= False

In[14]:= MemberQ[T[p][x, y], p, {0, -1}, Heads->True]

Out[14]= True

A possibly undesirable side-effect is that it also finds T, which
is likely thought of as the function, of which p is a parameter
that could just as easily have been an argument along with x, say
T[p, x, y].  If the spirit of your question was to find x when it
occurs as a "variable" but not as a "function", then I think you
could put a test on the position of a match.  Here's one possibility
(I haven't even defined the problem to my satisfaction, yet, so I
don't know if it will do what you want):

ElementButNotHeadQ[expr_, patt_] := 
  Not[ Or @@ Map[MatchQ[#, {___, 0}]&, Position[expr, patt]] ]

Here's how it behaves on something that has functions in the head and

In[20]:= expr = T[x[a, b], y[c, d]] [ u[p, q], v[r, s] ]

Out[20]= T[x[a, b], y[c, d]][u[p, q], v[r, s]]

(* variables = True: *)

In[21]:= ElementButNotHeadQ[expr, p]   

Out[21]= True

In[22]:= ElementButNotHeadQ[expr, c]

Out[22]= True

(* functions = False: *)

In[23]:= ElementButNotHeadQ[expr, T]

Out[23]= False

In[24]:= ElementButNotHeadQ[expr, v]

Out[24]= False

(* Possibly silly, possibly not: *)

In[26]:= ElementButNotHeadQ[expr, y[c, d]]

Out[26]= True

If you can give a precise definition of "depends on" for your purposes,
then something in this direction ought to work.

Robby Villegas

P.S.  If you really want to play around with it some more, here is
a function I used to help myself see whether my ElementButNotHeadQ
was really doing what I wanted on all the different parts of the
expression, heads and all.  You could use something like it when
you are trying your own tests.  It's scary-looking, but all it does
is go through and test every subexpression, and print the outcome
of the test, with indentation to make the results easier to read
(if you don't want the indentation, throw out MapIndexed and use
MapAll, but the output might be a bit harder to read).

result[part_, position_] := 
 ( Print[""];
   Print[Indent[2 Length[position]], part, " ===> ",
     ElementButNotHeadQ[expr, part]];

In[31]:= MapIndexed[result, expr, {0, -1}, Heads->True]

    T ===> False

      x ===> False

      a ===> True

      b ===> True

    x[a, b] ===> True

[... lines deleted ...]

Out[31]= T[x[a, b], y[c, d]][u[p, q], v[r, s]]

  • Prev by Date: Re: How to slow down plotting of curves?
  • Next by Date: Re: how can I do this functionally?
  • Previous by thread: What's this Mathematica function called?
  • Next by thread: Re: What's this Mathematica function called?