MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: unexpected behaviour of Sum


> I do not want to say that this is a bug, however I did
> not find, in the Sum documentation, an explanation of this
> behaviour (v8.0.4)
> I defined an innocent function like
> sod[n_]:=Plus@@IntegerDigits[n]
> that compute the sum of the digits of a number.
> (I tried with other functions, so the culprit is not IntegerDigits)
> Then I compute two sums:
> Sum[sod[k],{k,10^6}] which gives 27000001 (ok)
> then
> Sum[sod[k],{k,1+10^6}] which gives 500001500001 (nonsense).
> then
> Sum[sod[k],{k,2,1+10^6}] which gives 27000002 (ok)
> so, it seems to me that Sum has a problem when the iterator
> works in a range greater than 10^6.
> Indeed, I made an experiment:
> I set L={}; and defined
> sod[n_]:=(AppendTo[L,n];Plus@@IntegerDigits[n])
> Then Sum[sod[k],{k,1+10^6}] still gives 500001500001
> and at the end L is equal to {k}, so it seems that
> Sum tried to do something symbolic (??).

yes, Sum will try to something symbolic, and the default threshold is 
indeed 1000000, as SystemOptions["SymbolicSumThreshold"] will show you.
> Is this a bug or a feature whose documentation I was not
> able to find? Say, is there an option to fix things ?

You could in fact increase SymbolicSumThreshold, but I think there are 
much better ways to achieve what you want. First you should understand 
what happens: when switching to a symbolic algorithm, Sum will evaluate 
the summand symbolically, if you do that you will find the following:

Clear[k];sod[k]  will return k

What happend? IntegerDigits[k] will not evaluate, applying Plus will 
replace the Head with Plus and the end result is k. Sum[k,{1,n}] will 
return the well known Gauss formula and insert 10^6+1 and that's the 
wrong result you see.

One way to solve your problem would be to define sod so it only is 
evaluated for input that it actually does handle, e.g.:

sod[n_Integer] := Plus @@ IntegerDigits[n]

Another, probably even better approach is to use functions that will not 
even try to do anything symbolic. Actually Sum to some extend can be 
seen as a function made to return symbolic sums and it will do explicit 
summations just as an additional feature. A simple approach like this:

Total[Table[sod[k], {k, 10^6 + 1}]]

will immediately yield the correct result, independent on how you define 
sod. Presumably because the table will create a large list which will 
consume a lot of memory the last is slower than Sum in this case, but if 
you are after performance, you could change the definition of sod to this:

sod = Plus @@ IntegerDigits[#] &

Total[Table[sod[k], {k, 10^6 + 1}]] // Timing

which is now very fast since it now sees what sod actually is and will 
compile it. If you also want to be more memory efficient you can compile 

    Module[{sum = 0}, Do[sum += sod[k], {k, 10^6 + 1}]; sum],
    CompilationOptions -> "InlineExternalDefinitions" -> True][]

> Btw, using ParallelSum instead of Sum works fine (and faster).

which probably is because it does not try to do the sum symbolically 
(but probably not nearly as fast as the compiled versions)...



  • Prev by Date: Re: unexpected behaviour of Sum
  • Next by Date: Re: Phase Plot of Simple Harmonic Motion using Mathematica ??
  • Previous by thread: Re: unexpected behaviour of Sum
  • Next by thread: Re: unexpected behaviour of Sum