WeBWorK Main Forum

Zero values with fprob( , , ) when using variables as inputs?

Re: Zero values with fprob( , , ) when using variables as inputs?

by Alex Jordan -
Number of replies: 2

If I replace:

$p1=fprob(7, $dfw, $fsam);

with either of:

$p1=fprob(7, "$dfw", "$fsam");
$p1=fprob(7, $dfw->value, $fsam->value);

then I see 0.000323115 instead of 0. Something in the fprob() subroutine is doing the wrong thing when the arguments are MathObjects. Wrapping them in quotes to get their string presentations (which will introduce rounding errors) or passing the actual values makes things come out as expected.

It looks like fprob() is imported from outside of PG. I'm not sure where to go look into its inner workings.

In reply to Alex Jordan

Re: Zero values with fprob( , , ) when using variables as inputs?

by Glenn Rice -

Note that fprob is defined in lib/Distributions.pm.

Also note that the code in lib/Distributions.pm is not designed to be MathObject aware.  It was written before MathObjects existed.

MathObjects override many of the basic perl operators particularly comparison operators.  As such, when a perl comparison is done with a MathObject, the overridden operators are used instead of the pure perl operators.  This means that a fuzzy comparison will be used, and that takes into account the tolerance setting.

In this case the return value of fprob(7, $dfw, $fsam) would be 0.000323115.  

Now to trace the code, when you call fprob, that then calls _subfprob in lib/Distributions.pm.  This happens to use the last case in that method, and the last thing that method does with the return value is takes the maximum of 0 and the return value.  The value it computes before the maximum is taken is 0.000323115 as expected, but then the maximum of 0 and 0.000323115 is taken.  With an absolute tolerance of 0.001 and fuzzy comparison in effect, 0.000323115 is not greater than 0.  So the max method (also defined in lib/Distributions.pm) starts with 0, tests if 0.000323115 > 0 and with fuzzy comparison in effect that gives a false result, and so max sticks with and returns 0 for the maximum value.

I recommend that you do as Alex suggested and use fprob(7, $dfw->value, $fsam->value) which will pass the pure perl numeric values instead of the MathObjects, and thus avoid the issue of MathObject operator overloads being used.  This is the correct thing to do considering that the code in lib/Distributions.pm is not MathObject aware and expects pure perl numeric values to begin with.  This should be done for any call to a method in lib/Distributions.pm (exposed by PGstatisticsmacros.pl) or any of the methods defined directly in PGstatisticsmacros.pl as well.

In reply to Glenn Rice

Re: Zero values with fprob( , , ) when using variables as inputs?

by Tim Payer -

Wow, Thank you all.

I never realized the extent of fprob and that it was not MathObject aware,

I will adopt the changes soon.

Glenn, thank you and for the detailed description! I enjoyed learning about this.

Best, Tim