[SciPy-Dev] ANN: SciPy 0.11.0 release candidate 1
Rüdiger Kessel
ruediger.kessel at gmail.com
Tue Jul 24 09:43:56 EDT 2012
Andreas Hilboll <lists <at> hilboll.de> writes:
>
> > 20.07.2012 11:34, Andreas Hilboll kirjoitti:
> > [clip]
> >> ======================================================================
> >> FAIL: test_basic.TestNorm.test_stable
> >> ----------------------------------------------------------------------
> > [clip]
> >
> > Broken BLAS or something? Try this fortran program:
> >
> >
> > !!! test.f90
> > program main
> > implicit none
> > real a(10001)
> > real b, snrm2
> > external snrm2
> >
> > a(1) = 1e4
> > a(2:10001) = 1.0
> >
> > b = snrm2(10001, a, 1)
> > write(*,*) b ! should give 10000.5
> > end program main
> >
> >
>
> % gfortran -lblas test_blas.f90
> % ./a.out
> 10000.0000
>
> So apparently, something's wrong. But what?
>
> Cheers, A.
>
Hi,
I think BLAS is right.
I implemented the core of the original BLAS routine
(http://www.netlib.org/blas/snrm2.f) in python:
def snrm2(X,INCX=1):
import math
from numpy import float32
N=len(X)
SCALE = float32(0.0)
SSQ = float32(0.0)
for ix in range(0,N,INCX):
if X[ix]!=0.0:
ABSXI = float32(abs(X[ix]))
if SCALE < ABSXI:
SSQ = float32(1.0) + SSQ * float32(float32(SCALE/ABSXI)**2)
SCALE = ABSXI
else:
SSQ = SSQ + float32(float32(ABSXI/SCALE)**2)
NORM = SCALE*float32(math.sqrt(SSQ))
return NORM
It shows the same behavior.
The reason is that the ratio between 10000**2 / 1**2 is 1e8. So the loop is
adding a small value to a large value in single precision.
float32(1e8+1) = 1e8
This can only be improved if snrm2 would internally use double precision. But
this was obviously not the intention.
Greetings
Rüdiger
More information about the SciPy-Dev
mailing list