## WeBWorK Main Forum

### num_cmp Mystery ### num_cmp Mystery

by Andrew Dabrowski -
Number of replies: 7

I'm puzzled by the behavior of num_cmp in a certain context.  Here's a MWE:

DOCUMENT();        # This should be the first executable line in the problem.

"PGbasicmacros.pl",
"PGcombinatorics.pl",
"MathObjects.pl",
);

Context() -> variables -> are(t => 'Real');

TEXT(beginproblem());
$df= Formula("500 *pi/6*cos((pi/6)*t)") -> reduce; BEGIN_TEXT When $$t=3$$,$BR$BR $$\{df->TeX\}=$$ \{ans_rule(20)\} END_TEXT ANS(num_cmp($df->eval(t=> 3)));

ENDDOCUMENT();

The correct answer is pi/6*500*cos(pi/2) = 0, and webwork accepts either as correct.

However 500*cos(pi/2) is marked incorrect, although it is also equal to 0.

I thought at first this might be due to WW evaluating cos(pi/2) numerically and not getting exactly 0.

However that doesn't fly because because 500*cos(pi/2) would be closer to pi/6*500*cos(pi/2) than is 0, but only 0 is accepted as correct.

What's going on here? ### Re: num_cmp Mystery

by Alex Jordan -
It could be due to rounding error. Neither thing is really 0, since pi is not really pi.

If I do:

TEXT(
Real("pi/6*500*cos(pi/2)")->value,
$BR, Real("500*cos(pi/2)")->value, ); Then I see: 1.60305891143483e-14 3.06161699786838e-14 It does seem strange that the zero level would be in between those numbers, with the first counting as equivalent to 0 and the second one not. But I'm not familiar with how num_cmp works. In reply to Alex Jordan ### Re: num_cmp Mystery by Andrew Dabrowski - That's what I meant by "evaluating numerically", rather than symbolically. I don't see why it is, if the "correct" answer is 1.60305891143483e-14, that 0 is considered within the tolerance, but 3.06161699786838e-14 not. Does anyone know exactly how num_cmp works? In reply to Andrew Dabrowski ### Re: num_cmp Mystery by Andras Balogh - I know I should not respond because I don't know how num_cmp works, but I just can't resist. • 100*cos(pi/2) and -100*cos(pi/2) are both marked correct. • 200*cos(pi/2) and -200*cos(pi/2) are both marked incorrect. • (500*pi/6)*cos(pi/2) is marked correct, it is approximately 260*cos(pi/2), which is marked incorrect along with the smaller 200*cos(pi/2). It seems to me that it either takes the correct formula (500*pi/6)*cos(pi/2) or a numerical approximation of 0. In reply to Andrew Dabrowski ### Re: num_cmp Mystery by Alex Jordan - If the answer checker was the checker from MathObjects for a Real (so, not num_cmp), then I believe 1e-14 is the "zero level". Anything smaller than that in absolute value is considered equivalent to 0. (Well, really if a value is smaller than that, then comparisons are made absolutely instead of relatively, with a tolerance of 1e-12. So that includes being equivalent to 0.) Both of these numbers are more than 1e-14. The "zero level" would have to be something like 2e-14 for this to be the explanation, so it could be something else. And I see now Andras's post that suggest it is something else, not a zero level issue. In reply to Alex Jordan ### Re: num_cmp Mystery by Danny Glin - It's worth noting that num_cmp is not well-maintained. It is kept around for backwards-compatibility, but for newly authored problems you should be using the MathObjects checkers. Since your answer is already a MathObject Real, you should be able to do ANS($df->eval(t=> 3)->cmp());

I don't know if this will solve the issue you describe, but based on Alex's comments it should at least have predictable results when dealing with very small numbers. ### Re: num_cmp Mystery

by Glenn Rice -

Although you are correct about num_cmp not being maintained and using the cmp method is the correct way to do this now, the cmp method also has the same issue for this. If I am not mistaken num_cmp actually uses the MathObject methods in it's implementation.

I think Davide could shed some light on this situation. 