6
$\begingroup$

This question already has an answer here:

The command

Variables[poly]

gives me a list of all variables that appear in the expression poly, which involved sums, products, and rational powers. Sadly, it doesn't work for more complicated expressions, such as trigonometric functions. I was wondering if there is another command that can handle expressions such as $\sin(x)+\cos(y)$.

$\endgroup$

marked as duplicate by J. M. is away Apr 19 '17 at 0:28

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

4
$\begingroup$
ClearAll[x, y, z, d, h, p, m, f, g, a, w];

expr = Sin[x] + Cos[y] + z^3 + Exp[d] + h + 3 h^2 + 4 h^3 + 
   Integrate[Exp[p], p] + 
   D[Sin[m]^Exp[f], m]*Series[Sin[g], {g, 0, 3}] + 
   2 (E^a BesselK[0, 2 Sqrt[E^a]]) C[2]/D[Gamma[w], {w, 2}];

Cases[Variables[Level[expr, -1]], x_ /; AtomQ[x] :> x]

(* {a, d, f, g, h, m, p, w, x, y, z} *)
$\endgroup$
  • $\begingroup$ Nice - but you could use Level[expr, {-1}], right? $\endgroup$ – Jens Aug 7 '13 at 22:06
  • $\begingroup$ @Jens That's what I did in my answer. Nasser, forgive me but your current form doesn't make sense; you're effectively testing for indivisibility twice now: once with {-1} and once with AtomQ. You should either just subsume/supplant my answer or go back to the original form. (You're the one who encouraged me to post an answer; I'd have been glad to simply edit yours.) $\endgroup$ – Mr.Wizard Aug 7 '13 at 22:26
  • $\begingroup$ Yes, both -1 and {-1} will work in your code; that's my point. With {-1} the AtomQ becomes redundant; that's why it's not in my answer. $\endgroup$ – Mr.Wizard Aug 7 '13 at 22:29
5
$\begingroup$

Using Nasser's expression code as an example:

expr = Sin[x] + Cos[y] + z^3 + Exp[d] + h + 3 h^2 + 4 h^3 + 
   Integrate[Exp[p], p] + 
   D[Sin[m]^Exp[f], m]*Series[Sin[g], {g, 0, 3}] + 
   2 (E^a BesselK[0, 2 Sqrt[E^a]]) C[2]/D[Gamma[w], {w, 2}];

You might use:

Variables @ Level[expr, {-1}]
{a, d, f, g, h, m, p, w, x, y, z}

To extract indexed variables such as C[2] you could use:

Cases[expr, _[_Integer], {-2}]
{C[2]}
$\endgroup$
  • $\begingroup$ I almost overlooked your answer because it's so short... but it's obviously the easiest way! $\endgroup$ – Jens Aug 7 '13 at 22:28
  • $\begingroup$ @Jens I used the method here as well, but there I used -1 rather than {-1} because I wanted to allow for indexed variables like x[1]. Do you think I should try to extend my answer to handle both in Sin[z] + x[1], that is include z and x[1] in the output list? $\endgroup$ – Mr.Wizard Aug 7 '13 at 22:38
  • $\begingroup$ The OP was looking for an analogue of Variables for polynomials, and that limits what he means by variables. But indeed, that would also include things like x[1]! $\endgroup$ – Jens Aug 7 '13 at 22:49
  • $\begingroup$ +1 But what about something a term like Integrate[Sqrt[1 + Exp[p^2]], {p, 0, 1}], which doesn't evaluate but is a constant? Just live with it? $\endgroup$ – Michael E2 Aug 7 '13 at 22:52
  • $\begingroup$ @MichaelE2 I guess it all depends on what you need; this is intended as the "simple" answer to complement more involved ones such as what Daniel linked to. Most of the time I think it works OK. $\endgroup$ – Mr.Wizard Aug 7 '13 at 22:55
4
$\begingroup$
Clear[GetVariables]
SetAttributes[GetVariables, HoldFirst];
GetVariables[expr_, f_:Identity,  excludedContexts:{__String}:{"System`"}]:=
Cases[Unevaluated[expr], 
  a_Symbol/;!Or[
       MemberQ[excludedContexts, Context[a]],
       MemberQ[Attributes[a], Locked | ReadProtected]
    ] :> f[a], 
  {0, Infinity}
]//DeleteDuplicates

It is used like

GetVariables @ {Exp[f[x]], Sin[x y^2]}
(* {x, y} *)

or, if you need to

GetVariables[{Exp[f[x]], Sin[x y^2]}, Hold]
(* {Hold[x], Hold[y]} *)

By default, it excludes the System` context, but other contexts can be specified, too.

$\endgroup$
3
$\begingroup$
sr = {Exp[v_] :> v, v1_^v2_ :> {v1, v2}};
variables[expr_] := FixedPoint[Replace[Variables[# /. sr], _[x_] :> x, {1}] &, expr]

variables[Sin[Subscript[x, 1]] + Cos[Subscript[x, 2]]]
(*  {Subscript[x, 1], Subscript[x, 2]} *)

variables[Sin[x] + Cos[y] + z^3 + Exp[d] + h + 3 h^2 + 4 h^3 + 
Integrate[Exp[p], p] + D[Sin[m]^Exp[f], m]]
(* {d, f, h, m, p, x, y, z} *)
$\endgroup$
  • $\begingroup$ Looking at the other answers I realize that Exp gives the slip with this approach. So I have updated it accordingly. I hope there are not that many cases! $\endgroup$ – Suba Thomas Aug 7 '13 at 20:46
  • $\begingroup$ Added the rule to handle your case. Probably the OP does not need this level of complexity. $\endgroup$ – Suba Thomas Aug 7 '13 at 21:21
1
$\begingroup$

Perhaps what you are looking for is as simple as

vars[expr_] := DeleteDuplicates@Cases[expr, _Symbol, \[Infinity]]

vars[1 + y^2 + Sin[x] + Cos[x]]

{y, x}

Probably there are expressions on which this will fail, but it might handle those you are interested in.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.