joshuaulrich / TTR

Technical analysis and other functions to construct technical trading rules with R
GNU General Public License v2.0
330 stars 103 forks source link

Some unit tests fail when run under valgrind #14

Closed joshuaulrich closed 9 years ago

joshuaulrich commented 9 years ago

The MFI unit test in TTR fails when R is run under valgrind because the result of rowMeans is slightly different when R is run under valgrind. Specifically:

> # R --vanilla
> library(TTR)
> data(ttrc)
> x <- rowMeans(ttrc[,c("High","Low","Close")])
> sprintf("%21.20f %21.20f", x[62], x[63])
[1] "3.38333333333333330373 3.38333333333333330373"
> sprintf("%21.20f %21.20f %21.20f", ttrc[62,"High"], ttrc[62,"Low"], ttrc[62,"Close"])
[1] "3.41000000000000014211 3.35999999999999987566 3.37999999999999989342"
> # R --vanilla -d "valgrind"
> library(TTR)
> data(ttrc)
> x <- rowMeans(ttrc[,c("High","Low","Close")])
> sprintf("%21.20f %21.20f", x[62], x[63])
[1] "3.38333333333333285964 3.38333333333333330373"
> sprintf("%21.20f %21.20f %21.20f", ttrc[62,"High"], ttrc[62,"Low"], ttrc[62,"Close"])
[1] "3.41000000000000014211 3.35999999999999987566 3.37999999999999989342"

This causes x[63] > x[62] to be TRUE under valgrind when it's FALSE when running R without valgrind.

Prof Ripley explains the differences as,

One possible reason is that there will be more stores to memory and so the extended precision of x86_64 CPUs will be used less. I can confirm that via the use of flag -ffloat-store in gcc/gfortran...

A couple members of the CRAN team suggest having a tolerance for the logical comparison. While that would solve this specific issue, it wouldn't prevent a similar issue from occurring via a different logical comparison in another function. That would require adding a tolerance to all logical comparisons, which would be onerous.

The MFI unit test that fails under valgrind will succeed if the call to rowMeans(HLC) is replaced by a call to apply(HLC, 1, mean). rowMeans is also used in bollingerBands and CCI.