Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

A common problem I have with Mathematica is needing to manipulate the arguments of logarithms. Typically, I need to take ratios of the log arguments Mathematica gives me by default.

That's to say I perform operations similar to

In[24]:= Log[x] - Log[y] /. Log[w_] - Log[v_] -> Log[w/v]

Out[24]= Log[x/y]

However, in a general situation, the logs may appear with complicated prefactors. By using Collect[], I can pull out any common symbolic factors, but Mathematica still keeps numbers with the logs. Trying to do a replace similar to the one above fails

In[25]:= 2 Log[mgl] - 2 Log[mi] /. a_ Log[w_] - a_ Log[v_] -> a Log[w/v]

Out[25]= 2 Log[mgl] - 2 Log[mi]

Going term by term, I was able to move the numerical log prefactor inside the log as an exponent, e.g.

In[27]:= 2 Log[mgl] /. {a_ Log[w_] -> Log[w^a]}

Out[27]= Log[mgl^2]

and can then combine logs pairwise to get the ratio I want.

In[29]:= Log[mgl^2] + Log[1/mi^2] /. Log[w_] + Log[v_] -> Log[w v]

Out[29]= Log[mgl^2/mi^2]

However, the ratio now contains an exponent that I would prefer to move out front. This step fails.

In[28]:= Log[mgl^2/mi^2] /. Log[x_^a_/y_^a_] -> a Log[x/y]

Out[28]= Log[mgl^2/mi^2]

Where I would have wanted 2*Log[mgl/mi].

Are there any suggestions for manipulating these log arguments to get ratios of single powers?

Thank you.

share|improve this question

When patterns start acting strange it often helps to look at the FullForm of the expression you are trying to match together with the pattern you are matching with:

2 Log[mgl] - 2 Log[mi]//FullForm
a_ Log[v_] - a_ Log[w_] // FullForm
(* Plus[
(* Plus[

Squinting at this I guess they wont match because -2 is its own thing and is in a sense distinct from Times[-1,2]:

-2 /. -a_ :> Pi
(* -2 *)

That seems to have been a decent guess.

To get around this we can match two different coefficients and see if they only differ by sign:

2 Log[mgl] - 2 Log[mi] /. a_ Log[w_] + b_ Log[v_] /; b == -a :> a Log[w/v]
(* 2 Log[mgl/mi] *)

This could just as well match the negative coefficient first, if you want to ensure positive coefficient for the final expression you can add an extra condition:

2 Log[y] - 2 Log[x] /. a_ Log[w_] + b_ Log[v_] /; b == -a :> a Log[w/v]
2 Log[x] - 2 Log[y] /. a_ Log[w_] + b_ Log[v_] /; b == -a :> a Log[w/v]
2 Log[y] - 2 Log[x] /. a_ Log[w_] + b_ Log[v_] /; b == -a && a>0 :> a Log[w/v]
(* -2 Log[x/y]
    2 Log[x/y]
    2 Log[y/x]
share|improve this answer

I'd go with Simplify:

Simplify[a Log[mgl] - a Log[mi], mi > 0]
(* a Log[mgl/mi] *)


It seems quite picky:

Simplify[2.1 Log[mgl] - 2.1 Log[mi], mi > 0]
(* 2.1 Log[mgl] - 2.1 Log[mi] *)
share|improve this answer


expandLog[expr_] := Module[{rule1, rule2, a, b, x},
   rule1 = Log[a_*b_] -> Log[a] + Log[b];
   rule2 = Log[a_^x_] -> x*Log[a];
   (expr /. rule1) /. rule2

expandAllLog[expr_] := Nest[expandLog, expr, Depth[expr]];

collectLog[expr_] := Module[{rule1, rule2, a, b, x},
   rule1 = Log[a_] + Log[b_] -> Log[a*b];
   rule2 = x_*Log[a_] -> Log[a^x];
   (expr /. rule1) /. rule2 /. rule1 /. rule2

collectAllLog[expr_] := Nest[collectLog, expr, Length[expr]];

might be useful. For example:

Log[mgl^2/mi^2] // expandLog // Factor
Map[collectLog, %]

(*  2 (Log[mgl] - Log[mi])  *)

(*   2 Log[mgl/mi]          *)
share|improve this answer
If you use RuleDelayed (:>) you will not need to add a, b, x to the Module declaration as :> localizes pattern names. – Mr.Wizard Sep 19 '13 at 7:29
@ Mr.Wizard Thank you, I will have it in mind – Alexei Boulbitch Sep 20 '13 at 7:54

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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