We are also closer to the values of Clisp, Gambit, Guile, SBCL for complex square roots...
And... It seems faster!
(time
(let ((x 2000-3000i))
(dotimes (i 3000000)
(when (= (modulo i 100)) (set! x 2000-3000i))
(set! x (sqrt x)))
x))
Old code: 3623.08 ms
New code: 3002.49 ms
Hello @egallesio !
Currently, STklos crashes on this input:
(sqrt 1-0.0i)
.Looking at the algorithm used, it seems that we can both fix this crash and also make it a bit more precise.
With this PR, we calculate the square root of coplexes as this (same algorithm that Clisp uses):
So we don't use
ex2inex
,angle
(and consequentlyatan
) anymore, only two square roots and one inversion (and it seems to be more precise - see below).A tricky part is to test "a < 0" for negative zero (because -0.0 < 0 won't work, we need to get the
REAL_PART
and usesignbit()
to test it)Looking at the limiting process, we see that
Then,
(sqrt -1 + tiny*i)
should get be very close to i.Current algorithm:
With this patch:
So we go from
6e-17
to0.0
(great!)We are also closer to the values of Clisp, Gambit, Guile, SBCL for complex square roots...
And... It seems faster!