Hi, Tom,
The PP engine will automatically cast all PDL arguments to the "highest" type
of any of them, so if your user passes in any argument that is a float, the
operation will be done with F or D as the GenericType.
If you want to force the issue, I suggest using the GenericTypes flag, which
will force the type to be cast to one of the floating types. For example:
GenericTypes=>['F','D']
will force all integer types to be cast to float or double on entry to the
routine.
I suggest *not* including an autoround under any circumstances, because that
violates the principle of least surprise -- since everything else on the planet
truncates, it would introduce an inconsistency.
If I remember right, the reason there isn't an unsigned long is that longs were
considered "large enough" to waste the extra sign bit.
All the best,
Craig
On Jun 7, 2012, at 2:31 PM, Tom Nishimura wrote:
> Dear Piddlers,
>
> I'm in the process of binding the GSL random distribution functions
> (since currently only the samplers are implemented, in PDL::GSL::RNG,
> not the pdf/cdf functions).
>
> I'm trying to bind a function whose prototype has a mix of types, like
> so:
>
> double gsl_ran_poisson_pdf (unsigned int k, double mu)
>
> I want to bind it so that it is threadable on both parameters, like:
>
> PDL::gsl_ran_poisson_pdf(long(20), 10.5);
> PDL::gsl_ran_poisson_pdf(long(10), pdl(8,9,10,11,12));
> PDL::gsl_ran_poisson_pdf(long(8,9,10,11,12), pdl(8,9,10,11,12));
>
> My first attempt is the obvious:
>
> pp_def('gsl_ran_poisson_pdf',
> Pars => 'int numdraws(); double lambda(); double [o] out()',
> Code => q{
> $out() = gsl_ran_poisson_pdf( $numdraws(), $lambda() );
> },
> );
>
> This works, but then I started wondering how cognizant people will be
> about passing an integer type as the first parameter, since in Perl
> most people don't worry about types too much. I'd prefer automatically
> rounding floating point values correctly, so the following three lines
> produce the same value. The above will truncate 9.9 to 9. (I'm not
> sure if 10.0 is guaranteed to cast down to the 'properly' to 10,
> or could it possibly to be cast to 9?)
>
> PDL::gsl_ran_poisson_pdf(double(9.9), pdl(8,9,10,11,12));
> PDL::gsl_ran_poisson_pdf(double(10.0), pdl(8,9,10,11,12));
> PDL::gsl_ran_poisson_pdf(double(10.1), pdl(8,9,10,11,12));
>
> Maybe I should drop the type spec from numdraws() in Pars and use the
> type of the loop to decide whether or not to round?:
>
> pp_def('gsl_ran_poisson_pdf2',
> Pars => 'numdraws(); double lambda(); double [o] out()',
> Code => q{
> /* the generic loop type is the type of numdraws, right? */
> types(BSUL) %{
> $out() = gsl_ran_poisson_pdf( $numdraws(), $lambda() );
> %}
> types(FD) %{
> $out() = gsl_ran_poisson_pdf(
> /* need to round numdraws to nearest int */
> ($numdraws() > 0.0) ?
> floor($numdraws() + 0.5) :
> ceil($numdraws() - 0.5),
> $lambda()
> );
> %}
> },
> );
>
> This achieves automatic rounding but seems hackish. Any advice? Should
> I just go with the first version and leave it to the user to be aware of
> the types? Or is there a smarter way of properly rounding floating
> points down to integers? Maybe keep the first one, but write a wrapper
> in Perl?
>
> Also, side question: how come there is no 'unsigned int' type in PDL?
> ushort is the only unsigned int type.
>
> thanks,
> Tom
>
> _______________________________________________
> Perldl mailing list
> [email protected]
> http://mailman.jach.hawaii.edu/mailman/listinfo/perldl
>
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl