WeBWorK Main Forum

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

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

by Tim Payer -
Number of replies: 9

I am running into an issue with the Anova F-distribution probability command of fprob( , ,)
Would you mind taking a look at it?

When using variables for the degrees of freedom within and the f-sample the resulting p-value is zero. But if I use the numeric values for this particular seed, then the correct p-value is returned p = 0.000323115

I have tried using "Real" and "Compute" commands to enable these variables to be read as numbers but I clearly am missing something.

Thanks so much for any input you can share.

Best, tim

A.)  This code block produces p-values = 0
$p1=fprob(7,$dfw, $fsam);
$pv = Compute("$p1")->with(
  tolType => 'absolute',
  tolerance => .0001,
);

B.) This code block that uses numeric inputs produces the correct p-value of 
p = 0.000323115
$p3=fprob(7, 29, 5.707);
$p4 = Compute("$p3")->with(
  tolType => 'absolute',
  tolerance => .0001,
);

In reply to Tim Payer

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

by Andrew Parker -
Tim, would you share how $dfw and $fsam are defined in your problem?
In reply to Andrew Parker

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

by Tim Payer -

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.

In reply to Tim Payer

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

by Andrew Parker -
So far, I am not able to replicate the behavior you describe -- do you mind sending the full pg file to me by email? 400 lines is quite a lot to post here in plaintext!
In reply to Andrew Parker

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

by Tim Payer -

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

In reply to Andrew Parker

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

by Tim Payer -
Hi Andrew,

i think I found the issue with my fprob( , , ) rounding to zero.
It is one of tolerance.
I had set the individual tolerance for the p-value from fprob( , , ) to be at the 4th decimal with the following code:
$p1=fprob(7,$dfw, $fsam);
$pv = Compute("$p1")->with(
tolType => 'absolute',
tolerance => .0001,
);

Given a seed of 2977, the resulting p-value is p = 0.000323115
However this will only display if I make the tolerance for the entire problem at the 4th decimal with this code:

Context("Numeric");
Context()->flags->set(
tolerance => 0.0001,
tolType => "absolute",
);

I thought that the tolerance for the individual variable "$pv" would be enough for these small p-values to display, but apparently the value will only fully display as p = 0.000323115 if the same tolerance of 4th decimal accuracy is given to the entire problem set.

Am I wrong in the the individual tolerance setting should be enough?
WeBWoRK wont display these small p-values unless the tolerance is set to the 4th decimal for the entire problem set?

Please let me know what you think.

Best, Tim
In reply to Tim Payer

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

by Andrew Parker -

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?

In reply to Tim Payer

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

by Alex Jordan -

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