I'm looking for a utility that would take an expression and extract all variables in that expression. Following five examples cover pretty much all of my variable patterns
a,Subscript[a,....],Subscript[a,...][...],a[...],a[...][...]
Here are two test cases.
expr1 = -Log[Subscript[\[Mu], 2][]] Subscript[\[Mu], 2][] -
Log[Subscript[\[Mu], 2][2]] Subscript[\[Mu], 2][2] +
Log[Subscript[\[Beta], 1, 2][]] Subscript[\[Beta], 1, 2][] +
Log[2] Subscript[\[Beta], 1, 2][1] +
Log[Subscript[\[Beta], 1, 2][1]] Subscript[\[Beta], 1, 2][1] +
Log[2] Subscript[\[Beta], 1, 2][2] +
Log[Subscript[\[Beta], 1, 2][2]] Subscript[\[Beta], 1, 2][2] +
Log[Subscript[\[Beta], 2, 3][]] Subscript[\[Beta], 2, 3][] +
Log[Subscript[\[Beta], 2, 3][2]] Subscript[\[Beta], 2, 3][2] +
Log[2] Subscript[\[Beta], 2, 3][3] +
Log[Subscript[\[Beta], 2, 3][3]] Subscript[\[Beta], 2, 3][3];
expr2 = Log[\[Beta][{1, 2}][{}]] \[Beta][{1, 2}][{}] +
Log[2] \[Beta][{1, 2}][{1}] +
Log[\[Beta][{1, 2}][{1}]] \[Beta][{1, 2}][{1}] +
Log[2] \[Beta][{1, 2}][{2}] +
Log[\[Beta][{1, 2}][{2}]] \[Beta][{1, 2}][{2}] +
Log[\[Beta][{2, 3}][{}]] \[Beta][{2, 3}][{}] +
Log[\[Beta][{2, 3}][{2}]] \[Beta][{2, 3}][{2}] +
Log[2] \[Beta][{2, 3}][{3}] +
Log[\[Beta][{2, 3}][{3}]] \[Beta][{2, 3}][{3}] -
Log[\[Mu][{2}][{}]] \[Mu][{2}][{}] -
Log[\[Mu][{2}][{2}]] \[Mu][{2}][{2}]
On[Assert];
Assert[Union@extractVariables@expr1 === Union[Variables[expr1][[9 ;;]]]]
Assert[Union@extractVariables@expr2 === Union[Variables[expr2][[9 ;;]]]]
Here's MrWizard's solution
extractVariables[formula_] := (
pat = _Symbol[___][___] | Subscript[_Symbol, __][___] | Subscript[_Symbol, __] | _Symbol;
Union@Cases[formula, pat, -1]
);
Here is some code I use to get at "variables" in various types of expression (lists, equations, inequalities, and inside numeric functions).
headlist = {Or, And, Equal, Unequal, Less, LessEqual, Greater,
GreaterEqual, Inequality};
getAllVariables[f_?NumericQ] := Sequence[]
getAllVariables[{}] := Sequence[]
getAllVariables[t_] /; MemberQ[headlist, t] := Sequence[]
getAllVariables[ll_List] :=
Flatten[Union[Map[getAllVariables[#] &, ll]]]
getAllVariables[Derivative[n_Integer][f_][arg__]] :=
getAllVariables[{arg}]
getAllVariables[f_Symbol[arg__]] :=
Module[{fvars},
If[MemberQ[Attributes[f], NumericFunction] || MemberQ[headlist, f],
fvars = getAllVariables[{arg}],(*else*)fvars = f[arg]];
fvars]
getAllVariables[other_] := other
One example from provided tests:
In[36]:= getAllVariables[expr2]
Out[36]= {[Beta][{1, 2}][{}], [Beta][{1, 2}][{1}], [Beta][{1, 2}][{2}], [Beta][{2, 3}][{}], [Beta][{2, 3}][{2}], [Beta][{2, 3}][{3}], [Mu][{2}][{}], [Mu][{2}][{2}]}
This could be extended to handle a larger class of expressions, e.g. Boolean, math with dummy variables (e.g. Sum or Integrate), some programmatic constructs. Expect thorny issue to appear.
Anecdote: Way back in the last millenium someone in the Kernel Dept scheduled a meeting to discuss the issue of "What is a variable?" This was within the setting of Mathematica, not general math or CS. All the same, it is an elusive thing to pin down because different functions seem to have different requirements for such entities. My own take on it was to reply that I would be sick that day (of the intended meeting). I do not recall if I was asked how I knew that in advance...
Daniel Lichtblau
The obvious (but presumably incorrect) approach would be:
pat = _Symbol[___][___] | Subscript[_Symbol, __][___] | Subscript[_Symbol, __] | _Symbol;
Cases[expr1, pat, -1]
Cases[expr2, pat, -1]
But frankly I don't understand you question well enough to know where this goes wrong.
If that actually works for you, then I recommend:
extractVariables[formula_] :=
With[{pat = _Symbol[___][___] | Subscript[_Symbol, __][___] | Subscript[_Symbol, __] | _Symbol},
Union@Cases[formula, pat, -1]
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With