Re: Crossreference, code documentation
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg1682] Re: Crossreference, code documentation
- From: Count Dracula <lk3a at kelvin.seas.virginia.edu>
- Date: Mon, 17 Jul 1995 00:34:17 -0400
- Organization: University of Virginia
In Message-ID: <3tl7ro$8od at news0.cybernetics.net>
wagner at bullwinkle.cs.Colorado.EDU (Dave Wagner) wrote:
> Speaking of rule-based solutions to the problem, Jason Harris suggested
> this to me:
> goodSymb @ a_Symbol := True /; "System`" != Context @ a
> goodSymb @ other___ := False
> FindSymbols3[expr_]:=
> Block[{ symbs = {} },
> MapAll[findAux,expr,Heads -> True]//.
> {findAux @ a_?goodSymb @ args___ :> addIt /; AppendTo[symbs, HoldForm @ a],
> findAux @ a_?goodSymb :> addIt /; AppendTo[symbs, HoldForm @ a],
> findAux @ other___ :> other};
> Union @ Flatten @ symbs]
> Jason's solution is a bit slower than mine, but it illustrates an
> interesting technique, namely, building up a list of results as a
> *side-effect* of applying a rule. In retrospect, I think that I like
> the idea of building up the result in-place and then using Cases to
> extract the relevant parts much better.
There are some things missing in the function definition here,
probably some Attribute settings, so the definition was not
quoted in its entirety. But given what we can see in the
quoted definition, and its purpose of printing the symbols
in a given Mathematica expression after filtering out System
symbols, I think it is fair to say that an unnecessarily
complicated, roundabout method is being suggested.
Instead of lengthy discussions, I will offer two
alternatives, both of which show a more Mathematica-like
approach:
SetAttributes[{NonSystemQ, findsym4, findsym5}, HoldAll]
NonSystemQ[x_Symbol] := "System`" != Context[x]
findsym4[expr_] :=
Cases[Union[Level[ Unevaluated[expr], {-1}, Hold, Heads->True] ], (x_Symbol)?NonSystemQ :> HoldForm[x]]
findsym5[expr_] :=
Union[ Cases[ Unevaluated[expr], (x_Symbol)?NonSystemQ -> HoldForm[x], {-1}, Heads->True ] ]
One of these takes slightly longer to execute than the other
as seen by the test below:
{a,b,c, f, g, h, j} = {1, 2, 3, func1, func2, "a string", I + Pi};
test2 := findsym4[P[{x, f[f[g[a], b], b, h[c], f]}] + Sin[j x] Log[c] Exp[I x + u]/(9 Integrate[x Pi, {x, 0, 2}])]
test3 := findsym5[P[{x, f[f[g[a], b], b, h[c], f]}] + Sin[j x] Log[c] Exp[I x + u]/(9 Integrate[x Pi, {x, 0, 2}])]
ttest := {First[Timing[Array[test2 &, {30}]]], First[Timing[Array[test3 &, {30}]]]}
Test run on an RS6000:
In[3]:= test2 ==test3
Out[3]= True
In[4]:= ttest
Out[4]= {0.16 Second, 0.22 Second}
In[5]:= test2
Out[5]= {a, b, c, f, g, h, j, P, u, x}
I did not try a test with FindSymbols3, but my guess is its
execution time will be longer.
--
___________________________________________________________________________________
Levent Kitis lk3a at cars.mech.virginia.edu lk3a at kelvin.seas.virginia.edu
University of Virginia Department of Mechanical, Aerospace, and Nuclear Engineering
___________________________________________________________________________________