Mathematica thinks (-1)^n is non-real
Machine floating point arithmetic can produce strange results when the numbers get very small. Here are same ways to deal with it.
Suppress insignificant imaginary parts.
NSum[((-1)^n)/n, {n, 1, 100}] // Chop
-0.688172
Work with exact numbers until the very end (slower).
Sum[((-1)^n)/n, {n, 1, 100}] // N
-0.688172
Use Mathematica's arbitrary precision arithmetic rather than machine arithmetic.
NSum[((-1)^n)/n, {n, 1, 100}, WorkingPrecision -> 16]
-0.688172179310
Use the special method that NSum
has for maintaining precision with series that have terms with alternating signs. This is likely to be the best solution for this particular sum.
NSum[((-1)^n)/n, {n, 1, 100}, Method -> "AlternatingSigns"]
-0.688172
NSum
uses a combination of analytic and numeric methods. For instance, it computes
(-1)^102.
(* 1. - 1.95968*10^-14 I *)
with a real exponent instead of an exact integer. It's the same as Exp[102. Log[-1]]
, which is the same as Exp[I * 102. * Pi]
, for that is how Power
is computed when the exponent is Real
. Rounding error in 102. * Pi
introduces a small, complex part in the final result.
For more, see the output of
Trace[NSum[((-1)^n)/n, {n, 1, 100}]]
As @kglr pointed out, the way to make Mathematica handle the -1
power appropriately is with
NSum[((-1)^n)/n, {n, 1, 100}, Method -> "AlternatingSigns"]
The fact that Power
with a negative base is going to be a complex-valued function when the exponent is an approximate Real
can be countered, given the terms are real, by using Re
:
NSum[Re[((-1)^n)/n], {n, 1, 100}]
(* -0.688172 *)
A different approach that uses exact exponents and Real
base:
Total[(-1.)^#/# &@Range[100]]
(* -0.688172 *)
Integer powers are treated differently than floating-point powers. Total
tends to be a better way to approach small finite sums.
I want to mention that this sum has a closed form in terms of Mathematica functions
(-1)^n*LerchPhi[-1, 1, 1 + n] - Log[2]
As already carefully pointed out by Michael, the (-1)^n
part introduces the small imaginary parts when you apply it to real values. If you are interested in a approximate result, the easiest way is to calculate the above term for integers and then taking N
.
f[n_Integer] := N[(-1)^n*LerchPhi[-1, 1, 1 + n] - Log[2]]
f[100]
(* -0.688172 *)
However, calculating LerchPhi
should be faster when calculated with approximate numbers in the first place. So the other solution is to put the N
inside LerchPhi
. Therefore, the better alternative if you want to calculate this for large n
might be this
f2[n_Integer] := (-1)^n*LerchPhi[-1, 1, 1 + N[n]] - Log[2]
A quick comparison shows, that I can easily calculate 2^20
in half a second
f2[2^20] // AbsoluteTiming
(* {0.508786, -0.693147} *)
while the exact computation of f
needs about 300x the time of this
f[2^20] // AbsoluteTiming
(* {147.191, -0.693147} *)
Runtime-wise, nothing will beat NSum
if it implicitly contains a more expensive function. Therefore, my last point is to mention that you can easily split your sum into to parts: All positive terms and all negative terms. With this, you get completely rid of the (-1)^n
term and no Chop
is necessary
nn = 100;
NSum[1/n, {n, 2, nn, 2}] - NSum[1/n, {n, 1, nn - 1, 2}]
(* -0.688172 *)