2
$\begingroup$

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.

$\endgroup$

3 Answers 3

4
$\begingroup$

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]
*)
$\endgroup$
2
$\begingroup$

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] *)
$\endgroup$
1
$\begingroup$

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]          *)
$\endgroup$
2
  • 2
    $\begingroup$ If you use RuleDelayed (:>) you will not need to add a, b, x to the Module declaration as :> localizes pattern names. $\endgroup$
    – Mr.Wizard
    Commented Sep 19, 2013 at 7:29
  • $\begingroup$ @ Mr.Wizard Thank you, I will have it in mind $\endgroup$ Commented Sep 20, 2013 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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