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$
    – dtn
    Jan 23 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$
    – dtn
    Jan 23 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$
    – Bob Hanlon
    Jan 23 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$
    – dtn
    Jan 23 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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