Hi all: When testing the new PDL interface to plplot, we came across this
odd PDL behavior:
use PDL;
print "acos(-1.) = ", acos(-1.), "\n";
print "acos(-1 ) = ", acos(-1 ), "\n";
The acos(-1.) version incorrectly gives a single precision result, whereas
the acos(1) version gives the expected double precision result. This is
due to the fact that there is no integer version of acos and PP routines
default to 'double' instead of float in this case.
This stems from the fact that:
perldl> p PDL::get_datatype(-1.)
5 # $PDL_F
Which seems odd--most PDL operations default to double precision.
After a bit of digging with gdb, it turns out this is caused by:
From: pdlcore.c.PL
/* Check minimum, at least float, datatype required to represent number */
int pdl_whichdatatype_double (double nv) {
TESTTYPE(PDL_F,PDL_Float)
TESTTYPE(PDL_D,PDL_Double)
if( !finite(nv) ) { return PDL_D; }
croak("Something's gone wrong: %lf cannot be converted by
whichdatatype_double",
nv);
}
So, I would like to propose one of two remedies (attached).
The first (pdlcore.c.PL.diff) would be to get rid of
pdl_whichdatatype_double and just assume that scalars convert to doubles,
not floats. This would be a change to a long-standing rule, but I think
it would be sensible. It breaks one test in conv.t that was specifically
designed to verify this behavior--that test would have to be changed.
Another approach would be to leave the 'PDL::get_datatype(-1.) == $PDL_F'
problem alone and just fix 'acos' and the rest of the math functions that
can return either float or double values. The other attached patch
(math.pd.diff) just changes
GenericTypes => ['F', 'D']
to
GenericTypes => ['D', 'F']
in several pp_def calls. This has less impact, but solves the irksome
'acos(-1.) != acos(-1)' problem without changing the fact that '1.'
defaults to 'float' instead of 'double'.
I've tested both of these out and (with the exception of the conv.t test)
they both pass the test suite and solve the problem.
Any ideas on which approach to take?
Regards,
Doug
dh...@ucar.edu
Software Engineer IV
UCAR - COSMIC, Tel. (303) 497-2611
*** ./Basic/Core/pdlcore.c.PL.orig Wed Nov 12 21:13:53 2008
--- ./Basic/Core/pdlcore.c.PL Fri Dec 12 17:56:11 2008
***************
*** 175,192 ****
nv);
}
- /* Check minimum, at least float, datatype required to represent number */
-
- int pdl_whichdatatype_double (double nv) {
- TESTTYPE(PDL_F,PDL_Float)
- TESTTYPE(PDL_D,PDL_Double)
-
- if( !finite(nv) ) { return PDL_D; }
-
- croak("Something's gone wrong: %lf cannot be converted by
whichdatatype_double",
- nv);
- }
-
#ifdef _MSC_VER
#pragma optimize("", on)
#endif
--- 175,180 ----
***************
*** 258,293 ****
/* Figure datatype to use */
if ( !SvIOK(sv) && SvNOK(sv) && SvNIOK(sv) ) {/* Perl Double (e.g.
2.0) */
data = SvNV(sv);
!
! !NO!SUBS!
!
! # XXX HACK this may not be sensible (DJB 08/31/00)
! # - only relevant if BADVAL_USENAN is true in config file
! #
!
! if ( $bvalflag and $usenan ) {
! print OUT <<'!NO!SUBS!';
!
! /*
! * default NaN/Infs to double
! * XXX sensible ?
! */
! if ( finite(data) == 0 ) {
! datatype = PDL_D;
! } else {
! datatype = pdl_whichdatatype_double(data);
! }
!
! !NO!SUBS!
! } else {
!
! print OUT "\tdatatype = pdl_whichdatatype_double(data);\n";
!
! } # if: $bvalflag
!
! print OUT <<'!NO!SUBS!';
!
! }
else { /* Perl Int (e.g. 2) */
data = SvNV(sv);
datatype = pdl_whichdatatype(data);
--- 246,253 ----
/* Figure datatype to use */
if ( !SvIOK(sv) && SvNOK(sv) && SvNIOK(sv) ) {/* Perl Double (e.g.
2.0) */
data = SvNV(sv);
! datatype = PDL_D;
! }
else { /* Perl Int (e.g. 2) */
data = SvNV(sv);
datatype = pdl_whichdatatype(data);
*** ./Basic/Math/math.pd.orig Wed Nov 12 21:13:54 2008
--- ./Basic/Math/math.pd Fri Dec 12 17:49:11 2008
***************
*** 167,173 ****
pp_def($func,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['F','D'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $func ),
--- 167,173 ----
pp_def($func,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['D','F'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $func ),
***************
*** 205,211 ****
pp_def($func,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['F','D'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $func ),
--- 205,211 ----
pp_def($func,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['D', 'F'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $func ),
***************
*** 219,225 ****
pp_def($fname,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['F','D'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $fname ),
--- 219,225 ----
pp_def($fname,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['D', 'F'],
Pars => 'a(); [o]b();',
Inplace => 1,
Doc => inplace_doc( $fname ),
***************
*** 233,239 ****
pp_def($fname,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['F','D'],
Pars => 'a(); int n(); [o]b();',
Inplace => [ 'a' ],
Doc => inplace_doc( $fname ),
--- 233,239 ----
pp_def($fname,
HandleBad => 1,
NoBadifNaN => 1,
! GenericTypes => ['D', 'F'],
Pars => 'a(); int n(); [o]b();',
Inplace => [ 'a' ],
Doc => inplace_doc( $fname ),
------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you. Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel