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 ___________________________________________________________________________________