1
$\begingroup$

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.

enter image description here

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
$\endgroup$
1
  • $\begingroup$ It seems to me that the Level command could be the initial step. $\endgroup$ Commented Jan 23, 2022 at 6:11

1 Answer 1

3
$\begingroup$
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 *)
$\endgroup$
3
  • $\begingroup$ 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 $\endgroup$ Commented Jan 23, 2022 at 8:20
  • 1
    $\begingroup$ I think the edit does what you want; however, it is best to provide the desired output in addition to the input. $\endgroup$ Commented Jan 23, 2022 at 16:28
  • $\begingroup$ 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}] $\endgroup$ Commented Jan 23, 2022 at 16:43

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.