ans = 
How can I get the correct answer for int(1/x) with symbolic integration?
Show older comments
I am trying to solve some ODEs using DSOLVE, and while doing this I realised that matlab is consistently losing half the solutions because it is integrating 1/x wrongly. I'll illustrate this here with the simplest possible example:
syms x
fun = 1/x;
int(fun)
which is correct, but only for x>0. The correct answer for all values of x (with the exception of 0) should be log(abs(x)). How can I force matlab to use the full solution?
I also tried
syms x real
fun = 1/x;
int(fun)
and
syms x
fun = 1/x;
int(fun,IgnoreAnalyticConstraints=true)
7 Comments
It is true that
syms x real
%% function
f = log(abs(x))
%% derivative of the function w.r.t. x
df = diff(f)
%% simplification done
df = simplify(df, 'steps', 100)
However, when the absolute value operator is performed on the input x, there is information loss. Specifically, the sign of the value is lost, meaning you can no longer determine whether the original value was positive or negative.
OP thinks that log(abs(x)) is a more general answer as antiderivative to 1/x because it's valid for all x~=0, not only x > 0. But as said: log(x) is also defined for x < 0 (in the complex plane) with derivative 1/x. So log(abs(x)) as antiderivative to 1/x is not more general than log(x) if we allow complex results.
Try
C1val = -20:20;
C1val = C1val - 2*pi*1i;
Georg
on 28 Jul 2025
When you take int(1/x, x, -b, -a) assuming a>0, b>0, then if you get out log(-a)-log(-b) then that is (log(a)+2pi*i) - (log(b)+2*pi*i) which is log(a) - log(b) because the 2*pi*i cancel out.
When you take int(1/x, x, -b, -a) assuming a>0, b>0, then if you get out log(abs(-a))-log(abs(-b)) then that is log(a)) - log(b)
When you take int(1/x, b, a) assuming a>0, b>0 then if you might get out log(a)-log(b) . When you take int(1/x, b, a) then you might get out log(abs(a)) - log(abs(b)) but because a > 0 and b > 0 then that is log(a)-log(b) which is the same.
So whether you get log(x) or log(abs(x)) over b to a, then you get the same result provided that a and b are both less than 0 or a and b are both greater than 0.
You only get a different result between log(x) and log(abs(x)) in the case where one of the values is less than zero and the other value is greater than 0. In which case you end up with either a +2pi*i or -2pi*i for the log(x) form and with no +/-2pi*i for the log(abs(x)) form.
Now consider int(1/x, x, -a, a) then if the integral is log(x) you get log(a) - log(-a) which is log(a) - (log(a) + 2pi*i) which is 2pi*i . If the integral is log(abs(x)) then you get log(abs(a)) - log(abs(-a)) which is log(a)-log(a) which is 0.
syms x real
syms a b real
int(1/x, -a, b)
limit(ans, b, a)
integral(@(x)1./x, -1, 1)
fplot(1/x, [-1 1])
for every -x, x>0, there is a corresponding +x such that 1/(-x) = -1/x cancels out the 1/x . However that still leaves x = 0, for which there is no corresponding match, so the exact integral of 1/x over -a to +a has to be inf or nan -- which is not 0 as would be predicted from log(abs(x))
Hmm, yes, that works, but what is the argument for adding a complex constant to the integration constant of a real indefinite integral? And why exactly -2pi i?
I already answered this:
log(x) = log(-x) + 1i*pi (x < 0)
Here:
-2*log(2*x+y(x)-2) = -2*log(-(2*x+y(x)-2)) - 2*pi*1i
Thus if you subtract 2*pi*1i from C1, you consider the case that 2*x+y(x)-2 is negative in your implicit plot.
To illustrate this, the following example shows how MATLAB treats cases "left to the line y = -2*x + 2" (e.g. if you impose the condition y(0) = 0). As you can see from the output, MATLAB replaces 2*log(-(2*x+y(x)-2)) by 2*log(2*x+y(x)-2) - 2*pi*i. This circumvents the necessity to work with 2*log(abs(2*x+y(x)-2)).
clear all
syms y(x)
eqn = diff(y,x) == (2*x+y(x)+2)/(2*x+y(x)-4);
cond = y(0)==0;
solution = dsolve(eqn,cond,Implicit=true)
syms u
impl = subs(lhs(solution)-rhs(solution),y,u);
impl = matlabFunction(impl,'Vars',[x,u])
hold on
fimplicit(impl)
fimplicit(@(x,u)2*x+u-2)
hold off
grid on
Accepted Answer
More Answers (2)
If you accept complex constants of integration, log(x) as antiderivative to 1/x is correct also for x < 0 since log(x) = log(-x) + 1i*pi.
Seems like the OP might be missing a sign(x), though I'm not really sure how to intrepret this result.
syms x real
d = diff(log(abs(x)))
int(d)
2 Comments
x > 0: sign(x)/abs(x) = +1/x = 1/x
x < 0: sign(x)/abs(x) = -1/(-x) = 1/x
syms x real
d = simplify(diff(log(abs(x))),'Steps',40)
David Goodmanson
on 28 Jul 2025
Edited: David Goodmanson
on 29 Jul 2025
Georg has a good point. For
w = Int{a to b} (1/x) dx,
if neither a or b are zero and the principal value is taken when integrating across the origin, then for a<b<0 and the five other possible ways of ordering a,b,0
w = log(|b|) -log(|a|)
works for all of them. Books on integration list the indefinite integral as log(|x|) and leave any complex constants of integration such as i*pi as just that, constants of integration.
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!








