7

========== 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?

Steve
  • 1,153
  • 7
  • 17
  • 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. – Mr.Wizard Jul 02 '14 at 06:55

4 Answers4

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

(*{x, y}*)
Basheer Algohi
  • 19,917
  • 1
  • 31
  • 78
5

"...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]

eldo
  • 67,911
  • 5
  • 60
  • 168
  • Great! Even m /. Function[{sym},MapThread[Rule, {sym,Symbol["x" <> ToString[#]] & /@ Range[Length@sym]}]][sym] – acl Jul 01 '14 at 19:16
  • 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. – Myridium Dec 21 '17 at 04:50
  • @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 – userrandrand Mar 30 '23 at 05:45
4
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]

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
1
m = (3 - I) x + 4 (x  y)/Cos[y];
lev = Level[m, {-1}]
Union@Cases[lev, _Symbol]

(* {x, y} *)
Nasser
  • 143,286
  • 11
  • 154
  • 359
  • .. 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 :) – Nasser Jul 01 '14 at 19:10