$pv = Compute("$p1")->with(
tolType => 'absolute',
tolerance => .0001,
);
B.) This code block that uses numeric inputs produces the correct p-value of
$p3=fprob(7, 29, 5.707);
$p4 = Compute("$p3")->with(
tolType => 'absolute',
tolerance => .0001,
);
Sure Andrew,
Here you go: I was using the sprint command to limit the decimal display
$dfwt = random(20, 30, 1);
$dfw =Compute("$dfwt"); ## Using Compute to convert to math objects.
$ssw = random(200, 600, 0.1);
$msw2 = Compute("$ssw/$dfw");
$msw1 = sprintf("%0.2f",$msw2);
$msw = Compute("$msw1");
$fsam2 = Compute("$msb/$msw");
$fsam1 = sprintf("%0.3f",$fsam2);
$fsam = Compute("$fsam1");
### Is this enough to see my glitch?
## I can send the whole problem but it is over 400 lines of code...
Thanks for a taking a look at it.
Here you go for this file.
I really appreciate you taking a look at it.
There are some redundant lines of code here as I was converting from F-tables to the Bognar app.
Tim
Thanks for the seed, that will certainly aid in the process.
I'm skeptical about tolerance being the real source of the issue here, as that should only come into play for comparison purpose -- and should be agnostic about display of values.
I can confirm that using seed 2977, I am seeing $p1 displayed as 0 (using context flag tolerance 0.001); and then $p1 displayed as 0.000323115 (using context flag tolerance 0.0001).
Perhaps there is some comparison being made in the calculation of fprob that is using the Context tolerance?
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.
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.
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