7
$\begingroup$

========== motivation ===========

Suppose, for example, I have an incoming expression like

 m = (3-I)x + 4(x y)/(Cos[y])

I want to find all the symbols in the expression ("x" and "y" in this case) without a priori knowledge of what symbols may appear in m.
Perhaps then I want to do something to the symbols, for example, transform each symbol #:

# -> u*#  

i.e. I want to obtain from m:

(3-I)u x + 4(u^2 x y)/(Cos[u y])  

In this case, I can take this result, expand in u and unitize to get:

Series[(3-I)u x + 4(u^2 x y)/(Cos[u y]), {u,0,1}]/.u->1  

a series expansion to first order in both x and y, where terms x^2, y^2, and x y are dropped.

==============================================================

This is just one example though, in general, I want to know how to find the symbols in an expression and do something to them.

I've tried things similar to

 test = Expand[# /. Not@NumericQ :> ReplaceAll[#, z -> u z]] &;  

 (5-3 I)x + 2 y^2 //test  

But this just returns the input unchanged, I would like it to return

 (5-3 I)u x + 2 u^2 y^2  

Any help?

$\endgroup$
1
  • $\begingroup$ I feel that this question should be closed as a duplicate of (30038) but there is just enough wiggle room that I don't wish to act alone. If anyone agrees or disagrees please comment. $\endgroup$
    – Mr.Wizard
    Jul 2, 2014 at 6:55

4 Answers 4

12
$\begingroup$
m = (3 - I) x + 4 (x y)/(Cos[y]);
Variables@Level[m, {-1}]

(*{x, y}*)
$\endgroup$
2
  • $\begingroup$ nice use of Variables $\endgroup$
    – Nasser
    Jul 1, 2014 at 19:43
  • $\begingroup$ @Nasser it should look rather familiar. $\endgroup$
    – Mr.Wizard
    Jul 2, 2014 at 6:49
5
$\begingroup$

"...in general, I want to know how to find the symbols in an expression..."

m = (3 - I) x + 4 (x y)/(Cos[y]);

sym = DeleteDuplicates@Cases[m, _Symbol, Infinity]

{x, y}

"... and do something to them"

m /. MapThread[Rule, {sym, {u, v}}]

(3 - I) u + 4 u v Sec[v]

$\endgroup$
3
  • $\begingroup$ Great! Even m /. Function[{sym},MapThread[Rule, {sym,Symbol["x" <> ToString[#]] & /@ Range[Length@sym]}]][sym] $\endgroup$
    – acl
    Jul 1, 2014 at 19:16
  • $\begingroup$ This does not work. Cases[m, _Symbol, Infinity] will output an empty list, instead of {m} as it should. Using Cases[m, _Symbol, {-1}] seems to do the trick. $\endgroup$
    – Myridium
    Dec 21, 2017 at 4:50
  • $\begingroup$ @Myridium Cases[m,_Symbol, All] also works but maybe it's slower I do not know. It's maybe also important to mention that Cases[Pi,_Symbol,All] outputs {Pi} as Pi has head Symbol. However using Variables from the other answer with Level[Pi, {-1}] // Variables leads to an empty list. Thus, the two methods are not equivalent $\endgroup$ Mar 30 at 5:45
4
$\begingroup$
m = (3 - I) x + 4 (x y)/(Cos[y Pi]);

Since

Head /@ {Pi, E, GoldenRatio}  (* and others *)

{Symbol, Symbol, Symbol}

Cases must test for more than just Symbol

m /. Thread[(var = Cases[m, _Symbol?(! NumericQ[#] &), Infinity] // Union) -> 
   u*var]

(3 - I)*u*x + 4*u^2*x*y* Sec[Pi*u*y]

$\endgroup$
3
  • $\begingroup$ +1, I think it safe to assume this is what the OP intended for symbol capture. $\endgroup$
    – ciao
    Jul 2, 2014 at 1:44
  • 1
    $\begingroup$ I agree, you can separate them also by context since built in symbols have System` while x is Global` $\endgroup$
    – Kuba
    Jul 2, 2014 at 5:58
  • $\begingroup$ @BobHanlon Using Variables (like Algohi did) eliminates NumericQ $\endgroup$
    – eldo
    Jul 2, 2014 at 9:03
1
$\begingroup$
m = (3 - I) x + 4 (x  y)/Cos[y];
lev = Level[m, {-1}]
Union@Cases[lev, _Symbol]

(* {x, y} *)
$\endgroup$
1
  • $\begingroup$ .. just saw eldo post after hitting post.... This is a little different may be. In Mathematica, we should always try to come up with 10 different ways to solve something :) $\endgroup$
    – Nasser
    Jul 1, 2014 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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