# 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:= Log[x] - Log[y] /. Log[w_] - Log[v_] -> Log[w/v]

Out= 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:= 2 Log[mgl] - 2 Log[mi] /. a_ Log[w_] - a_ Log[v_] -> a Log[w/v]

Out= 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:= 2 Log[mgl] /. {a_ Log[w_] -> Log[w^a]}

Out= Log[mgl^2]


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

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

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


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

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

Out= 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