# How to extract logarithmic terms in an expression?

I have some expressions of the type

$$f(x) \,+\, g(x) \,\log(x) \,+\, h(x) \,\log(1-x^2)$$

where $$f$$, $$g$$, and $$h$$ can be any rational functions of $$x$$. I am trying to use Mathematica to extract each function separately, given the expression.

I cannot simply use

Coefficient[expr, Log[x]] (* g *)
Coefficient[expr, Log[1-x^2]] (* h *)


because the expression is not necessarily written in the nice form I gave above. Sometimes Mathematica prefers to write it using Log[x^2], or to decompose Log[1-x^2] into Log[1-x] + Log[1+x] and then separate the logs... For some expressions I have even seen ArcTanh[x].

I have tried to use FullSimplify with a custom ComplexityFunction to force Mathematica to write the expression in the form I want, but it does not always work, and some of my expression are so long that I can't use FullSimplify on them.

I don't see how I could use anything related to the asymptotics or series expansions either, because the functions $$f, g$$ or $$h$$ can have poles or zeros at $$x=0$$ or $$1$$.

Is there a way to do what I want ? I should say that what I really care about is to obtain equations equivalent to g[x] == 0 and h[x] == 0. If there is a way to do that without getting $$g$$ and $$h$$ that is fine as well.

Thanks.

• Can you supply an expression where using Coefficient doesn't work? That way, we can actually test out various solutions. Feb 23, 2022 at 18:50
• Any example involving the sum of Logs would work, really. Take for example: 1 + (3+n) Log[1-x] + (3+n) Log[1-x]. Mathematica will not rewrite it in the form I want, even after FullSimplify. In this case I simply need the equation n = -3. I did not provide the example because I have a lot of different forms, sometimes involving ArcTanh as I said, and I don't want to make separate cases for each. Feb 23, 2022 at 19:35
• Sorry, I meant 1 + (3+n) Log[1-x] + (3+n) Log[1+x] (with a +). I can no longer edit my previous comment. See also my comment on the answer below for another kind of example, for which Coefficient would actually work. Feb 23, 2022 at 19:48

Cases[expr, HoldPattern[Times[___, _Log, ___]]]
(*returns {g[x] Log[x], h[x] Log[1 - x^2]}*)


Or to strip the Logs:

Cases[expr, HoldPattern[Times[a___, _Log, b___]] :> Times[a, b]]
(*returns {g[x], h[x]}*)


Following is edit based on feedback in comments

Okay, you want to group the terms based on matching log subexpressions. First, for convenience, define a function that extracts the Log expression(s) from a term (this may need to be modified if multiple Log expressions can exist in a single term):

LogSubexpression[expr_] := Cases[expr, _Log, Infinity]


Now use this function to group the terms:

GroupBy[List @@ expr, LogSubexpression]
(*this returns <|{Log[x]} -> {6 Log[x]}, {Log[1 - x^2]} -> {2 x Log[1 - x^2], 3 x^2 Log[1 - x^2]}|>*)


At this point, I think you have everything you need. You can formulate replacements for the Log subexpressions (which can be found as the Keys in this Association). You can further process the Values of the Association. Since we had to replace the outer Plus in the expression to get the GroupBy to work, maybe you want to re-introduce the Plus to the Values, and maybe you want to do this just on the "coefficients" of each Log-containing term.

Apply[Plus] /@ DeleteCases[GroupBy[List @@ expr, LogSubexpression], _Log, Infinity]
(*<|{Log[x]} -> 6, {Log[1 - x^2]} -> 2 x + 3 x^2|>*)


So, to get the expression you provided as an example in your comment, just extract the Values:

Apply[Plus] /@ DeleteCases[GroupBy[List @@ expr, LogSubexpression], _Log, Infinity] // Values
(*{6, 2 x + 3 x^2}*)

• Thank you, but I don't think this would work if the terms involving the logs are scattered. For example, with 2 x Log[1 - x^2] + 3 x^2 Log[1 - x^2] + 6 Log[x], your solution gives {6, 2 x, 3 x^2} whereas I would rather have {6, 2 x + 3 x^2}. Feb 23, 2022 at 19:42
• Thank you for your update. It does not solve completely my problem, but it is a step in the right direction. Stupid example, but if 2 Log[1-x^2] is written in the form Log[1-x] + Log[1+x] + Log[1-x^2], I would get {1,1,1} instead of {2}. Your method is still better than simply using Coefficient, because I can detect all the different Log patterns, and generate a warning if/when a new one appears in an expression. I will accept your answer, since there does not seem to be better way to do it, but I will gladly take other ideas that you may have. Feb 24, 2022 at 9:56

You could try to replace the logs by 1, taking care of sums of two logs:

ex = f[x] + g[x] Log[x] + h[x] Log[1 \[Minus] x2];
ex = ex /. Log[__] + Log[__] -> 1 /. Log[__] -> 1

(* f[x] + g[x] + h[x] *)


To further change this into a list of equations we write:

Thread[(List @@ ex) == 0]

(* {f[x] == 0, g[x] == 0, h[x] == 0} *)