Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
    
Check this for some methods. –  Daniel Lichtblau Aug 7 '13 at 20:20
add comment

5 Answers

up vote 4 down vote accepted
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} *)
share|improve this answer
    
Nice - but you could use Level[expr, {-1}], right? –  Jens Aug 7 '13 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 '13 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 '13 at 22:29
add comment

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]}
share|improve this answer
    
I almost overlooked your answer because it's so short... but it's obviously the easiest way! –  Jens Aug 7 '13 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 '13 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 '13 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 '13 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 '13 at 22:55
show 4 more comments
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.

share|improve this answer
add comment
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} *)
share|improve this answer
    
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 '13 at 20:46
    
Added the rule to handle your case. Probably the OP does not need this level of complexity. –  Suba Thomas Aug 7 '13 at 21:21
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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