Is there an analogue of the Variables command for general expressions?

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)$.

-
Check this for some methods. –  Daniel Lichtblau Aug 7 at 20:20

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} *)

-
Nice - but you could use Level[expr, {-1}], right? –  Jens Aug 7 at 22:06
@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.) –  Mr.Wizard Aug 7 at 22:26
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. –  Mr.Wizard Aug 7 at 22:29

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]}

-
I almost overlooked your answer because it's so short... but it's obviously the easiest way! –  Jens Aug 7 at 22:28
@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? –  Mr.Wizard Aug 7 at 22:38
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]! –  Jens Aug 7 at 22:49
+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? –  Michael E2 Aug 7 at 22:52
@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. –  Mr.Wizard Aug 7 at 22:55
Clear[GetVariables]
SetAttributes[GetVariables, HoldFirst];
GetVariables[expr_, f_:Identity,  excludedContexts:{__String}:{"System"}]:=
Cases[Unevaluated[expr],
a_Symbol/;!Or[
MemberQ[excludedContexts, Context[a]],
] :> 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.

-
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} *)

-
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! –  Suba Thomas Aug 7 at 20:46
Added the rule to handle your case. Probably the OP does not need this level of complexity. –  Suba Thomas Aug 7 at 21:21

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.

-