0
$\begingroup$

I input in mathematica

a*b*c*h

and get the output as

a b c h

Now if I want to factor out 'b' and 'c' at the same time and then put them at the beginning and at the end of a term as follow, what should I do?

b a h c
$\endgroup$
2
$\begingroup$
expr = a b c h;

You need to inactivate Times to keep the factors from automatically being put in canonical order.

expr2 = Inactive[Times] @@ 
  Flatten[Reverse /@ Partition[List @@ expr, 2]]

enter image description here

expr == (expr2 // Activate)

(* True *)

EDIT: For an arbitrarily specified order

expr2 = Inactive[Times] @@ (List @@ expr)[[{2, 1, 4, 3}]]

For the example given in your comment,

expr3 = a*b*c*h + d*f*g*h;

expr4 = Inactive[Times] @@ (List @@ #)[[{2, 1, 4, 3}]] & /@ expr3

enter image description here

$\endgroup$
  • $\begingroup$ Could you please explain a little bit more about your method? If the expression is a*b*c*h + d*f*g*h and I would like to factor 'b' , 'c', 'f' and 'g', how can we do it? @Bob $\endgroup$ – Jeff May 3 at 1:27
  • $\begingroup$ You essentially asked for the first two factors to be reversed and for the last two factors to be reversed. The code structurally does that. Look in the documentation for any function with which you aren't familiar. $\endgroup$ – Bob Hanlon May 3 at 1:33
  • $\begingroup$ Sorry, what I really want to do is factor two common factors which are randomly located in a polynomial. @Bob Hanlon $\endgroup$ – Jeff May 3 at 1:43
1
$\begingroup$

This is a bit complicated, but if we start simple and take one step at a time, we can find a solution. First we start with a test expression and Bob Hanlon's answer

expr = a*b*c*h  +  c*f*h*m ;
expr /. Times[x___, c, y___] :> Inactive[Times] @@ {c, x, y}

(*   c*a*b*h  +  c*f*h*m   *)

In the above we are replacing the Times with an Inactive[Times] and we are rearranging the arguments. If the symbol $c$ appears in the product, we factor it out. Otherwise, no changes are made. Note that we are using three underscores in x___ and y___ in the above. Now we create a (prototype) function that does that same thing:

Clear[q]
q[s_Symbol, z_] := z /. Times[x___, s, y___] :> Inactive[Times] @@ {s, x, y}

The function takes our symbol (it could $c$ or $h$ or whatever) and factors it out of the second argument. We try out the function like this

q[c, expr]

(*   c*a*b*h + c*f*h*m  *)

That is okay for factoring out a single symbol. What about 2 or more? We will want to give the function a list of symbols. If there is only one symbol on the list on the list, we use our prototype. If there is more than one symbol, we will use recursion. But one step at a time. Here is how we handle a list with one symbol:

q[ {s_Symbol}, z_] := q[s, z]

For a list with more than one symbol, we want to pull out the first symbol and call our prototype recursively with the rest of the list, like this

q[{s_Symbol, rest__}, z_] := q[s, q[rest, z]]

Note that we are using two underscores on the rest__. So, let's try it, but this does not work right, yet:

q[ {c,h}, expr] 

(*   h*a*b*c  + h*c*f*m   *)

The $h$ came out, but the $c$ did not. That's because after the recursion the $c$ is no longer an argument of Times, it's an argument of Inactive[Times]. So, it's a little more complicated. But, it's not difficult to take care of both cases. We simply use another Replace, this time on the Inactive[Times], like this

Clear[q]
q[s_Symbol, z_] := (z /. Inactive[Times][x___, s, y___] :> 
                         Inactive[Times] @@ {s, x, y}) /. 
                   Times[x___, s, y___] :> Inactive[Times] @@ {s, x, y}
q[{s_Symbol}, z_] := q[s, z]
q[{s_Symbol, rest__}, z_] := q[s, q[rest, z]]

That looks complicated, but all we did was change the part in parenthesis. That is, what had been just z in the function definition is now (z /. Inactive ...). We were redefining our prototype so we used Clear[q]. Now the prototype is the final version. Does it work? Here is how we test it.

q[{c, h}, expr]

(*   c*h*a*b  +  c*h*f*m   *)

So, that's it. We can factor out $c$ and the $h$. But, we have to use Activate if we want Mathematica to do arithmetic with the expression. It's a little complicated, but the steps are not difficult.

$\endgroup$
  • $\begingroup$ Can you put 'h' at the end of each term automatically? For example, get the final result as ``` cabh + c *f *mh ```. Please don't use Bob's answer. Because his method is not flexible. For example, if each term includes 10 variables, then his method needs to be adjusted manually. That's not good. Thanks. @LouisB $\endgroup$ – Jeff May 3 at 15:14
  • $\begingroup$ Yes, you can write a separate function that moves symbols to the right. You can start with the 3-part definition of q[s, z], which contains {s, x, y} in two places. Write your new function with a 3-part definition that uses { x, y , s} instead. That's all there is to it. $\endgroup$ – LouisB May 3 at 19:20

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.