30

How can I get Mathematica to simplify the following expression

n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b]

into

Log[ a^n b^m (a + b)^(-m - n)] ?

I've tried various methods without any luck including: -

FullSimplify[ n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b], { a + b > 0 } ]

Perhaps I'm not including enough assumptions or Mathematica doesn't consider this to be a simplification ? It would be nice to have a solution that doesn't require pattern matching.

Artes
  • 57,212
  • 12
  • 157
  • 245
Blair Azzopardi
  • 473
  • 1
  • 4
  • 10
  • 5
    In general Log[a^n] does not equal n*Log[a]. Take for instance Log[(-1)^2]. However, MMA knows that Assuming[{n > 0, m > 0, a > 0, b > 0}, FullSimplify[n Log[a] + m Log[b] == Log[a^n b^m]]] is True. So, these assumptions should be sufficient, but I cannot let it make the simplification itself. – Sjoerd C. de Vries Apr 04 '13 at 22:23
  • This Q&A seems to be a bit overlooked. The OP there wants to do things the other way around, i.e. go from a Log of a product to the sum of Logs. It is a subjective matter what a simplification is, so I like Artes answer here below. The OP in the link uses something similar. The answer in the link by wolfies just points to proprietary software, but can possibly provide some (professional) context. The answer in the link by Andre also seems great. – Jacob Akkerboom Apr 05 '13 at 09:39
  • Only for completeness: You can perform the reverse operation (expanding the Log[] function) via PowerExpand[]. – loki Dec 14 '17 at 13:40

4 Answers4

22

Let us introduce the function to transform the logarithm:

    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
   ];

This is your expression:

expr = (n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b]);

Let us first simplify it, and then apply to it the collectLog function:

    expr2 = Simplify[expr, {a > 0, b > 0}, 
   TransformationFunctions -> {Automatic, ComplexExpand}] // 
  collectLog

The result is

Log[a^n b^m] + Log[(a + b)^(-m - n)]

Let us apply the collectLog once more:

expr2 // collectLog

The result is:

Log[a^n b^m (a + b)^(-m - n)]

Done.

To answer the recent question of bszd: if a function with multiple Logs may be designed.

It can be done in a more simple way. If one has a lengthily expression with logarithms of the sort that might be simplified by collection, the function Nest may do the job:

 Nest[collectLog, expr, Length[expr]]

The answer is:

Log[a^n b^m (a + b)^(-m - n)]

If it is only a part of expression that, however, contains multiple logarithms to be collected, the function

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

may be mapped onto this part.

Finally, to complete this one may need to do the opposite operation: to expand the logarithmic expression. One way to do this would be to use the following function:

    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
   ];

and

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

For example,

expandAllLog[Log[a^n b^m (a + b)^(-m - n)]]

yields

n Log[a] + m Log[b] + (-m - n) Log[a + b]

as expected.

Alexei Boulbitch
  • 39,397
  • 2
  • 47
  • 96
  • This looks very good. Is there any easy way I can allow multiple arguments for rule1, i.e. rule1 = Log[a_] + Log[b_] + Log[]... -> Log[a*b*...]? – Blair Azzopardi Apr 06 '13 at 14:27
  • @bsdz, Please have a look at the part I added to the answer. – Alexei Boulbitch Apr 08 '13 at 07:38
  • Perfect - that's exactly what I was looking for with the added benefit it can be applied in other situations too. Thanks! – Blair Azzopardi Apr 08 '13 at 21:42
  • I am wondering how can I do the same replacement rules with functions sitting in front ? $e^{-i x}\log(a) + e^{ -i x} \log(b) \rightarrow e^{-i x}\log(a*b)$ – Jaswin May 06 '19 at 13:56
  • @ Jaswin There are several ways. 1) You may introduce a rule: rule = u_*Log[v_] + u_*Log[w_] :> u*Log[v*w] and apply it to your expression; expr = E^(-I*x)*Log[a] + E^(-I*x)*Log[b] as follows: expr /. rule. 2) Otherwise, you may first factor the expression and then apply to its part the collectLog function: MapAt[collectLog, expr // Factor, 2]. – Alexei Boulbitch May 06 '19 at 14:31
  • I tried the first method, it fails when $e^{-ix} \log(a) - e^{-i x} \log(b)\rightarrow e^{-i x} \log(a/b)$. Actually I have lot of these functions in my expression, and I want to replace everywhere to simplify. – Jaswin May 06 '19 at 14:47
  • @ Jaswin You have to create a rule such that it covers all cases that you can meet. This is not difficult. – Alexei Boulbitch May 06 '19 at 15:25
  • OK will do that – Jaswin May 06 '19 at 17:16
  • @AlexeiBoulbitch : I made two rules - rule1 = u_Log[v_] + u_Log[w_] :> uLog[vw]; rule2 = -u_Log[v_] + u_Log[w_] :> u*Log[w/v]; it is not working for some reason, am I missing something trivial ? – Jaswin May 06 '19 at 17:29
  • @Jaswin Let expr = E^(-I*x)*Log[a] - E^(-I*x)*Log[b]. Try this: rule = {Log[u_] - Log[v_] :> Log[u/v], -Log[u_] + Log[v_] :> Log[v/u]} and then MapAt[ReplaceAll[rule], expr // Factor, 2]. – Alexei Boulbitch May 06 '19 at 19:37
  • Actually it works in simple case but in a complicated expression this fails. I have lot of logs with different u's and V's but same prefactor function. – Jaswin May 06 '19 at 19:39
  • In fact I have asked a separate question with typical expressions i encounter. – Jaswin May 06 '19 at 19:42
  • @Jaswin 1. In general, logarithms are a difficult place in Mma. It never simplifies expressions containing them. I do not know the reason. Maybe, because it is not really clear, what expression the user will consider being better, with collected or with expanded logarithms. For this reason, it is typically impossible to automatically simplify all parts of the expression containing the logarithms, especially if there are plenty of such. One has to invent suitable approaches. – Alexei Boulbitch May 07 '19 at 08:36
  • @Jaswin 2. Solutions I proposed always work for me, but they sometimes require slight modifications depending on the form of the expression in question. To do this, one needs to understand the code. Are you sure that you understand it? – Alexei Boulbitch May 07 '19 at 08:37
  • @Jasmin 3. The solution of your problem cannot work this way. Please formulate your problem as a separate question and give your example that will include all typical subexpressions you have there. Probably it will enable one to find a more general function suitable for all your subexpressions. – Alexei Boulbitch May 07 '19 at 08:39
  • @AlexeiBoulbitch : I had asked a separate question, and it was answered satisfactorily. Yes I realised at times one needs to expand or collect and simplify or refine to get things done. I understand little coding in mathematica, the basic functions. Alteast now I am managing to do some simplifications. – Jaswin May 07 '19 at 09:45
21

I know, I know: Now someone will ask why. Anyway:

FullSimplify@Log@Exp[n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b]]

(* Log[a^n b^m (a + b)^(-m - n)] *)
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
10

Well, although late, here's an answer using ReplaceRepeated (//.).

Let's define two replacement rules to take us back and forth.

logrule = {Log[x_] + Log[y_] :> Log[x y], n_ Log[x_] :> Log[x^n]}

revlogrule = {Log[x_ y_] :> Log[x] + Log[y], Log[x_^n_] :> n Log[x]}

Now here's your problem

expr = n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b]

using the logrule we can simplify your expression:

expr //. logrule

Which gives:

Log[a^n b^m (a + b)^(-m - n)]

Now let's go back to the original expression using revlogrule

Log[a^n b^m (a + b)^(-m - n)] //. revlogrule // Expand

n Log[a] + m Log[b] - m Log[a + b] - n Log[a + b]

EDIT

You can also use FullSimplify with TransformationFunctions as follows. First define the transformation you desire to be applied:

tfunc[x_] := x /. logrule

Then:

FullSimplify[expr, TransformationFunctions -> {Automatic, tfunc}]

Which gives as before:

Log[a^n b^m (a + b)^(-m - n)]

RunnyKine
  • 33,088
  • 3
  • 109
  • 176
1

How about this one.

logList = n Log[a] + m Log[b] - m Log[a + b] - n m Log[a + b] 
         - n Log[a + b] - Log[ArcSin[a + b n]] + z Log[z];

mahmoh = Log[Times @@ (logList /. Times[x___, Log[y___]] :>
            Power[y,Times[x]] /. Log[x__] :> Power[x, 1])]

Out[376]=Log[(a^n b^m (a + b)^(-m - n - m n) z^z)/ArcSin[a + b n]]

All is fine as long as you dont use products of Log and here is a little Test

logList /. {a -> 2.3, b -> 4.3, n -> .4, m -> .7, z -> 3}
Out[377]= 1.09137 + 0.921334 I
mahmoh /. {a -> 2.3, b -> 4.3, n -> .4, m -> .7, z -> 3}
Out[378]= 1.09137 + 0.921334 I

The same answer at least.

And using the nice package MaTeX you get this little nice picture.

MaTeX[mahmoh, Magnification -> GoldenRatio]

enter image description here

I did not give it a very carefull thought so maybe you can find situation when it will not work. any suggestion would be more than welcome.

As for the original question the answer is

Log[a^n b^m (a + b)^(-m - n)]

enter image description here

mahmoh
  • 141
  • 5