# Separating terms in an expression with many variables by their "nature"

I have an expression like this:

$$f=t_1(\sin(\alpha),\cos(\beta),\cos(\gamma)^2) \cdot r_1(x,y,z)+t_n(\sin(\alpha),\cos(\beta),\cos(\gamma)^2) \cdot r_n(x,y,z)$$

Where $$t_i$$ and $$r_i$$ - functions of trigonometric functions $$\sin(\cdot),\cos(\cdot)...$$ and variables $$x,y,z$$, respectively.

I need to split these variables into two vectors by their "nature" i.e. into a vector containing trigonometric terms $$t_i$$ and a vector containing terms $$r_i$$ from variables $$x,y,z$$, i.e.

Let's take the expression as an example:

$$f=\sin(\alpha)\cos(\beta)\sin(\gamma)^3x^2y+\sin(\beta)\cos(\alpha)\sin(\gamma)^4x^2y+\sin(\alpha)^2\cos(\beta)xyz+(\sin(\alpha)\cos(\beta)+1)x^3y^2z^5$$

Naturally, everything should be with a minimum of code corrections made "manually". And even better if everything is automatic. I will be happy and grateful for help.

 f=Sin[\[Alpha]] Cos[\[Beta]] Sin[\[Gamma]] x^2 y + Sin[\[Beta]] Cos[\[Alpha]] Sin[\[Gamma]]^4 x^2 y + Sin[\[Alpha]]^2 Cos[\[Beta]] x y z + (Sin[\[Alpha]] Cos[\[Beta]] + 1) x^3 y^2 z^5

• It seems to me that the Level command could be the initial step.
– dtn
Jan 23 at 6:11

Clear["Global*"]

f = Sin[α] Cos[β] Sin[γ] x^2 y +
Sin[α]^2 Cos[β] x y z + (Sin[α] Cos[β] +
1) x^3 y^2 z^5

(* x y z Cos[β] Sin[α]^2 +
x^3 y^2 z^5 (1 + Cos[β] Sin[α]) +
x^2 y Cos[β] Sin[α] Sin[γ] *)


Note that the order of the terms change on input.

var = Variables[Level[f, {-2}]] /. {_Sin | _Cos :> Nothing}

(* {x, y, z} *)


To obtain v1, set all of the variables in var to 1

v1 = (List @@ f) /. Thread[var -> 1]

(* {Cos[β] Sin[α]^2, 1 + Cos[β] Sin[α],
Cos[β] Sin[α] Sin[γ]} *)


Divide the list by v1 to remove the trig factors

v2 = (List @@ f)/v1

(* {x y z, x^3 y^2 z^5, x^2 y} *)

f == v1 . v2

(* True *)


Defining a function

split[f_] := Module[
{var = Variables[Level[f, {-2}]] /. {_Sin | _Cos :> Nothing},
list = List @@ f, v1},
{v1 = list /. Thread[var -> 1],
list/v1}]

{v1, v2} = split[f]

(* {{Cos[β] Sin[α]^2, 1 + Cos[β] Sin[α],
Cos[β] Sin[α] Sin[γ]}, {x y z, x^3 y^2 z^5, x^2 y}} *)

f == Dot @@ %

(* True *)


EDIT: Modifying the definition of split to handle additional forms of input.

split[f_] := Module[
{var = Variables[Level[f, {-2}]] /. {_Sin | _Cos :> Nothing},
list = List @@ f, v1, v2, v2m},
{v1 = list /. Thread[var -> 1],
v2 = list/v1};
If[v2 == (v2m = DeleteDuplicates[v2]),
{v1, v2},
split[Collect[f2, v2m]]]]

f2 = Sin[α] Cos[β] Sin[γ] x^2 y +
Sin[β] Cos[α] Sin[γ]^4 x^2 y +
Sin[α]^2 Cos[β] x y z + (Sin[α] Cos[β] +
1) x^3 y^2 z^5;

{v1, v2} = split[f2]

(* {{Cos[β] Sin[α]^2, 1 + Cos[β] Sin[α],
Cos[β] Sin[α] Sin[γ] +
Cos[α] Sin[β] Sin[γ]^4}, {x y z, x^3 y^2 z^5, x^2 y}} *)

f2 == Dot @@ % // Simplify

(* True *)

• A very good and clear example. Thank you! But this code didn't work for this expression. f=Sin[\[Alpha]] Cos[\[Beta]] Sin[\[Gamma]] x^2 y + Sin[\[Beta]] Cos[\[Alpha]] Sin[\[Gamma]]^4 x^2 y + Sin[\[Alpha]]^2 Cos[\[Beta]] x y z + (Sin[\[Alpha]] Cos[\[Beta]] + 1) x^3 y^2 z^5. Terms with x^2 y not merged, although first we need to take this term out of the bracket
– dtn
Jan 23 at 8:20
• I think the edit does what you want; however, it is best to provide the desired output in addition to the input. Jan 23 at 16:28
• Bob, assembly (bracketing) can be done with a simpler command. Other than that, your vectorization code is perfectly functional. I accept it as an answer. Total@MonomialList[f, {x, y, z}]`
– dtn
Jan 23 at 16:43