Mathematica : Log Handling/Simplification

• Mathematica
Gold Member
I'm having a simple problem with simplifying of logs. Given the input :

FullSimplify[8 Log[m1] - 8 Log[m2] + 4, m1 > 0 && m2 > 0]
FullSimplify[8 Log[m1] - 8 Log[m2], m1 > 0 && m2 > 0]

I get out:

8 log(m1)-8 log(m2)+4

8 log(m1/m2)

So for the second command it combines the logs using the division rule, but in the first, where there is an extra addition, it does not. Is there an option that I can turn on to always force MM to simplify that log?

Ah, finally, a somewhat interesting problem.

Simplify is driven by a measure of the complexity of the function, usually LeafCount. Google it.

In[3]:= LeafCount[4+8 Log[m1]-8 Log[m2]]
Out[3]= 10
In[4]:= LeafCount[4+8*Log[m1/m2]]
Out[4]= 10

So the "complexity" of those two are equal and Simplify isn't driven one direction or the other.

The mechanism for you to control this is the ComplexityFunction option. Google it.

In[5]:= logExpensive[e_]:=10*Count[e,_Log,{0,Infinity}]+LeafCount[e];
FullSimplify[8 Log[m1]-8 Log[m2]+4,m1>0&&m2>0,ComplexityFunction->logExpensive]
Out[6]= (4 + Log[m1^8/m2^8]

which is odd.

In[7]:= LeafCount[4 + Log[m1^8/m2^8]]
Out[7]= 10
In[8]:= LeafCount[4 + 8*Log[m1/m2]]
Out[17]= 10

So making Log really expensive drove those togther. But for some reason it drove the 8 inside too.

Getting Mathematica to do things the way you want and it doesn't can be very challenging. Some days it just isn't worth the fight.

Either write some manual replacement rules, e.g.
Code:
a_ Log[x_] + b_ Log[y_] :> a Log[x/y] /; a == -b
which can include checks on positivity of x and y if need be.

Or use a custom ComplexityFunction to tune FullSimplify.
The default ComplexityFunction is given in the documentation as
Code:
SimplifyCount[p_] :=
IntegerQ[p],
If[p == 0, 1, Floor[N[Log[2, Abs[p]]/Log[2, 10]]] + If[p > 0, 1, 2]],
SimplifyCount[Numerator[p]] + SimplifyCount[Denominator[p]] + 1,
SimplifyCount[Re[p]] + SimplifyCount[Im[p]] + 1, NumberQ[p], 2,
If[Length[p] == 0, 0, Plus @@ (SimplifyCount /@ (List @@ p))]]
which is just a LeafCount modified to prefer small numbers.

If you define something like (which says it doesn't like logs)
Code:
LogSimplifyCount =  SimplifyCount[#]
+ Count[#, Log, Infinity, Heads -> True] &;
then things simplify like you want:

Code:
In[88]:= FullSimplify[8 Log[m1]-8 Log[m2]+8,m1>0&&m2>0,ComplexityFunction->LogSimplifyCount]
FullSimplify[8 Log[m1]-8 Log[m2],m1>0&&m2>0,ComplexityFunction->LogSimplifyCount]
Out[88]= 8 (1+Log[m1/m2])
Out[89]= 8 Log[m1/m2]

Hi Bill, you beat me too it!

I also forgot that I had changed
8 Log[m1]-8 Log[m2]+4
into
8 Log[m1]-8 Log[m2]+8
since I was having the same problems as you.

A simple fix would be to use something like
Code:
LogSimplifyCount=SimplifyCount[#]
-.5Count[#,Log[_?(!FreeQ[#,Power]&)],Infinity]&

Then everything works properly. Although, it would probably be more efficient to modify SimplifyCount[] directly...

Gold Member
Thanks guys! I love learning new things about Mathematica. I'll play around with it!

I said long ago that Mathematica and computer algebra software in general needs to implement a "mash that result into a form that looks kind of like this" command which behaves in a fairly predictable fashion. So for this problem it might be as simple as

Mash[%, _ Log[ _ ]+_ ]

to get the result he wanted.

That might be far easier for a user. If it didn't work then the user could make the pattern a little more specific, instead of trying to craft some incomprehensible function on LeafCount.

I believe there was a paper published in the Mathematica Journal once that could be interpreted to be related to this idea, but I can't locate that now.