The problem is how to avoid data type size
by having a byte image be converted to a
double image by adding the value 2 to it.
Making an image frame 8x bigger would
be surprising and annoying in that case.

As for how perl does it, I think that perl
uses IVs to long (except when it is a
long long) and NVs to double (except
when it is long double).  Not so simple
in reality...

I don't know that the current PDL-2.x API
can do this in a clean way.

I suggest we make perl scalar float values
(NVs) always convert to double piddles but
we keep the current and long standing
IV conversions to a size appropriate type
(especially since that works with 64bit
integers which is broken by conversion
to double/long).

Seems like the least bad option and something
we could fix for PDL-2.015.  Further "fixing"
would be "breaking" for other cases.  That
addresses the atan() anomaly and preserves
the ability to work with image data and
control the data types involved (with care).

--Chris




On 11/18/2015 18:20, Craig DeForest wrote:
I like the idea of autopromoting all IVs to long and all NVs to double. After all, that’s how Perl stores and treats them.

I don’t like the idea of setting this parameter anywhere other than at compile time. Action at a distance is madness at a distance…



On Nov 18, 2015, at 3:47 PM, Chris Marshall <devel.chm...@gmail.com <mailto:devel.chm...@gmail.com>> wrote:

I agree that the this is a surprising result---even
if correct by our current implementation.  Maybe
the default for NV perl scalars should be type
PDL_Double.  Maybe a perl scalar promotion
setting that could set a default value, double
or other specific type, smallest size, or ...

--Chris

On Wed, Nov 18, 2015 at 4:58 PM, Craig DeForest <defor...@boulder.swri.edu <mailto:defor...@boulder.swri.edu>> wrote:

    Yes, I believe this is a Bug in the conversion code logic.
    Currently we use the smallest possible type that can contain a
    value.  Values that fit in a float get promoted to float and
    those that require a double get promoted to double.  Here’s a
    four-atan trial, showing the autopromotion using a Perl scalar
    constructed to be similar to 2479/1024, that cannot fit in a float.


        sub try {
         my $val = shift;
         printf(“\nval: %.15f\nfloat:   %.15f\ndefault:
    %.15f\ndouble:  %.15f\n”,
                 $val, atan(float($val)), atan($val), atan(double($val))
                );
        }
        foreach( float(2379.0)/1024.0, double(2379.0)/1024.0,
    2379.0/1024.0, 2479.00000001/1024.0 ) { try($_) }


    yields

        val: 2.323242187500000
        float: 1.164332985877990
        default: 1.164332985877990
        double:  1.164332932171300
        val: 2.323242187500000
        float: 1.164332985877990
        default: 1.164332932171300
        double:  1.164332932171300
        val: 2.323242187500000
        float: 1.164332985877990
        default: 1.164332985877990
        double:  1.164332932171300

        val: 2.420898437509766
        float: 1.179073929786680
        default: 1.179073913765370
        double:  1.179073913765370

    where the top is the floating-point value, second is the double
    value (and both work as desired), third is the “bug” value (perl
    scalar is promoted to floating point), and fourth is the
    “antibug” value (perl scalar is promoted to double).
    Because a float can represent 2379/1024 exactly (after all, it’s
    just the integer 2379, shifted 10 bits to the right), you get a
float. But 1024 is a pretty special number, and highly unusual. Changing the ratio even slightly yields promotion to double by
    default.

        pdl> try(2479/1025)
        val: 2.418536585365854
        float: 1.178729414939880
        default: 1.178729370918130
        double:  1.178729370918130

    Since the vast majority of numeric Perl scalars cannot be
    represented exactly in a float, it’s easy to get into the mindset
    that Perl scalars are autopromoted to double PDLs.  By the
    Principle of Least Surprise, we should therefore always
    autopromote to the most common case (double), and require
    explicit cast to get to floating-point values.

    Sorry for the wall of text here, this is a pretty cool bug.


    On Nov 18, 2015, at 1:42 PM, Chris Marshall
    <devel.chm...@gmail.com <mailto:devel.chm...@gmail.com>> wrote:

    I think we may need something like
    an option to enable/disable forced
    conversion of perl scalars to double
    piddles.

    --Chris

    On Wed, Nov 18, 2015 at 3:03 PM, Chris Marshall
    <devel.chm...@gmail.com <mailto:devel.chm...@gmail.com>> wrote:

        Hi Doug-

        I think the problem is only when
        a perl scalar is the input to atan().
        The top two cases are the expected
        result.  Maybe the logic in the type
        conversion is off.  You don't say
        what version of PDL but I see the
        same output from PDL-2.014_02.

        --Chris



        On Wed, Nov 18, 2015 at 1:29 PM, Douglas Hunt
        <dh...@ucar.edu <mailto:dh...@ucar.edu>> wrote:

            Hi all:  I just noticed a thing which caused me some
            trouble.

            The PDL 'atan' function defaults to 'float' precision
            instead of the
            more natural 'double':

            use PDL;

            my $a1 = atan(double(2379.0)/double(1024.0));
            my $a2 = atan(float(2379.0)/float(1024.0));
            my $a3 = atan(2379.0/1024.0);

            print "$a1, $a2, $a3\n";

            This prints:
            1.1643329321713, 1.1643328666687, 1.1643328666687

            This feature causes a problem when porting to/from C as
            the C atan
            function operates on doubles.

            I think this traces down to Basic::Math in the math.pd file:

            my (@ufuncs1) = qw(acos asin atan cosh sinh tan tanh); #
            F,D only
            ...
            my $func;
            foreach $func (@ufuncs1) {
             pp_def($func,
            HandleBad => 1,
            NoBadifNaN => 1,
            GenericTypes => ['F','D'],
            Pars => 'a(); [o]b();',
            Inplace => 1,
            Doc => inplace_doc( $func ),
            Code => code_ufunc($func),
            BadCode => badcode_ufunc($func),
                        );
            }

            Note that GenericTypes isF, D instead of D, F.

            I would go so far to say that this is a bug, as the
            default pdl type is
            double as in:

            my $pdl = pdl(4,5,6);
            p $pdl->info
            PDL: Double D [3]

            Regards,

               Doug Hunt



            
------------------------------------------------------------------------------
            _______________________________________________
            pdl-devel mailing list
            pdl-devel@lists.sourceforge.net
            <mailto:pdl-devel@lists.sourceforge.net>
            https://lists.sourceforge.net/lists/listinfo/pdl-devel



    
------------------------------------------------------------------------------
    _______________________________________________
    pdl-devel mailing list
    pdl-devel@lists.sourceforge.net
    <mailto:pdl-devel@lists.sourceforge.net>
    https://lists.sourceforge.net/lists/listinfo/pdl-devel





------------------------------------------------------------------------------
_______________________________________________
pdl-devel mailing list
pdl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-devel

Reply via email to