# How to manipulate log arguments?

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.

-

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[
Times[2,Log[mgl]],
Times[-2,Log[mi]]
]*)
(* Plus[
Times[Log[Pattern[v,Blank[]]],Pattern[a,Blank[]]],
Times[-1,Log[Pattern[w,Blank[]]],Pattern[a,Blank[]]]
]*)


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]
*)

-

I'd go with Simplify:

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


EDIT:

It seems quite picky:

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

-

This

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]          *)

-
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