Re: Apply and up/down value questions
- To: mathgroup at smc.vnet.net
- Subject: [mg61641] Re: Apply and up/down value questions
- From: dh <dh at metrohm.ch>
- Date: Mon, 24 Oct 2005 21:06:58 -0400 (EDT)
- References: <djcfvq$6a8$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Hi Matt,
see below.
sincerely, Daniel
Matt wrote:
> Hello,
> Again, I'm working my way through some of the programming examples
> in Michael Trott's Programming Guidebook, and there's behaviour that I
> cannot figure out. I've been over and over section A.5.2 and 2.5.10 in
> the Mathematica Book, but I still don't understand up values when
> applied to functions with more than one argument. Also, I had a
> question about level specification, which I couldn't figure out even
> after looking at section A.3.6. Any help is appreciated. First the
> upvalue questions:
>
> I don't understand the point of using TagSet as opposed to UpSet:
> e.g. in Michael Trott's Programming Guidebook on page 318 he states:
> "For functions with several arguments, the information can be
> associated with a certain prescribed argument rather than with all
> arguments at the first level." However, I don't see any difference in
> functionality between this:
>
consider the following:
Clear[a1, a2];
f[a1, a2] ^:= 3;
??a1
Global`a1
a1 /: f[a1, a2] := 3
??a2
Global`a2
a2 /: f[a1, a2] := 3
Clear[a1, a2];
a1 /: f[a1, a2] := 3;
??a1
Global`a1
a1 /: f[a1, a2] := 3
??a2
Global`a2
here the assignment is only done to the explicitely specified a1.
Clear[a1, a2];
f[a1, a2_] ^:= 3;
??a1
Global`a1
a1 /: f[a1, a2_] := 3
??a2
Global`a2
here a2 is is not a variable, but the name of a pattern. That is why
nothing is assigned to a2.
>
> Also, I'm stumped on this particular wording in the TagSet
> documentation:
>
> "If f appears several times in lhs, then f/: lhs = rhs associates the
> assignment with each occurrence"
>
In my oppinion, this is missleading and confusing. I think it only means
: assignment to f
> What does this really mean?
>
>
> As regards Apply:
>
> Is it true that Apply[newHead, expr, 1] and Apply[newHead, expr, {1}]
> will always be the same result given that the other two arguments are
> identical?
>
> By definition, a level specification of n applies to levels 1 through
> n. I have found that if I do something like Apply[newHead, expr, -2],
> that what I actually end up with seems to be equivalent to newExpr =
> Apply[newHead, expr, {1}] followed by Apply[newHead, newExpr, {-2}].
> Here is an example:
>
> Cell[BoxData[{
> RowBox[{
> RowBox[{"a1", " ", "=", " ",
> RowBox[{"Array", "[",
> RowBox[{"\[DoubleStruckR]", ",",
> RowBox[{"{",
> RowBox[{"2", ",", "2"}], "}"}], ",",
> RowBox[{"{",
> RowBox[{"2", ",", "4"}], "}"}]}], "]"}]}],
> ";"}], "\[IndentingNewLine]",
> RowBox[{"MatrixForm", "[", "a1", "]"}], "\[IndentingNewLine]",
> RowBox[{
> RowBox[{"a11", " ", "=", " ",
> RowBox[{"Apply", "[",
> RowBox[{"newHead", ",", "a1", ",",
> RowBox[{"{", "1", "}"}]}], "]"}]}],
> ";"}], "\[IndentingNewLine]",
> RowBox[{"MatrixForm", "[", "a11", "]"}], "\[IndentingNewLine]",
> RowBox[{
> RowBox[{"a12", " ", "=", " ",
> RowBox[{"Apply", "[",
> RowBox[{"newHead", ",", "a11", ",",
> RowBox[{"{",
> RowBox[{"-", "2"}], "}"}]}], "]"}]}],
> ";"}], "\[IndentingNewLine]",
> RowBox[{"MatrixForm", "[", "a12", "]"}], "\[IndentingNewLine]",
> RowBox[{
> RowBox[{"a13", " ", "=", " ",
> RowBox[{"Apply", "[",
> RowBox[{"newHead", ",", " ", "a1", ",", " ",
> RowBox[{"-", "2"}]}], "]"}]}],
> ";"}], "\[IndentingNewLine]",
> RowBox[{"MatrixForm", "[", "a13", "]"}]}], "Input"]
>
> What is the general rule, or am I just misusing the level specification
> in Apply?
from the Help:
" A negative level number -n represents all parts of an expression that
have depth n. The depth of an expression, Depth[expr], is the maximum
number of indices needed to specify any part, plus one. Levels do not
include heads of expressions, except with the option setting Heads ->
True. Level 0 is the whole expression. Level -1 contains all symbols and
other objects that have no subparts. "
This is a bit confusing. If you consider an expression as a tree, -n
counts from the leaves. -1 means all atoms at the leafs. -2 all
expression starting 1 level below(or above, depending on how your tree
grows, up or down) the leaves. e.t.c. The Help specifies the same a bit
more confusing. It means "all expressions ending in a leaf that has
depth n". -1 means depth 1, that is expressions that can take at most 0
indices, the atoms.
-2 means depth 2, that is expressions that can take at most 1 indices,
e.t.c.
Examples:
Clear[a1, a2, a3, a4];
t = {a1, {a2, {a3, {a4}}}};
Level[t, {-1}]
{a1, a2, a3, a4}
this are the atoms at the leaves.
Clear[a1, a2, a3, a4];
t = {a1, {a2, {a3, {a4}}}};
Level[t, {-2}]
{{a4}}
{a4} is the only subexpression that can take at most 1 index
Clear[a1, a2, a3, a4];
t = {a1, {a2, {a3, {a4}}}};
Level[t, {-3}]
{{a3, {a4}}}
expression {a3, {a4}} can take at most 2 indices
Clear[a1, a2, a3, a4];
t = {a1, {a2, {a3, {a4}}}};
Level[t, -1]
{a1, a2, a3, a4, {a4}, {a3, {a4}}, {a2, {a3, {a4}}}}
these are all possible subexpressions
Clear[a1, a2, a3, a4];
t = {a1, {a2, {a3, {a4}}}};
Level[t, -2]
{{a4}, {a3, {a4}}, {a2, {a3, {a4}}}}
here the atoms with level -1 are missing
With other functions like: Apply, Cases, Count, FreeQ, Map, MapIndexed,
Position, Replace and Scan it should work the same, but the effect is
not as clearly seen as with Level
>
> And finally, a question on modified built in functions:
>
> In Michael Trott's Programming Guidebook, on page 311, he uses the
> following construct to remove a downvalue that had been specified for
> the Cos and Sin functions:
>
> Unprotect[Cos];
> Clear[Cos];
> Protect[Cos];
> {Cos}
>
> I've noticed that if I omit the last line (i.e. {Cos}), that it still
> works. What is the point of the last line?
>
I agree there is not point.
> Thanks very much,
>
> Matt
>