WeBWorK Problems

Odd floating point error?

Odd floating point error?

by Sean Fitzpatrick -
Number of replies: 3
The following bug came up in the attached problem, which is an updated version of one of Shaun Ault's APEX problems. For one seed (330), the problem asks for the indefinite integral \int x^5 e^(x^6) dx

(There is also a part (b), but that part works OK.)

Context is set to numeric. A student sent us an email because her answer of
(1/6)e^(x^6) was marked incorrect, despite being the right answer.

Oddly enough, if we instead input e^(x^6)/6, the problem is marked correct, and we get the message "This answer is equivalent to the one you just submitted."

So despite WeBWorK recognizing the two answers as being the same, one is marked right, and the other is marked wrong. Anyone have thoughts on what's happening?
In reply to Sean Fitzpatrick

Re: Odd floating point error?

by Danny Glin -
Without doing any actual investigation I would guess it has to do with the fact that the values of that function can get extremely large or extremely small.

My guess is that one of the following two things is happening:
  • When x is close to 0 the value of e^(x^6) is extremely small, so there could be some issue with either zero level tolerance or the value rounding to zero.
  • For x>1 e^(x^6) grows very fast, so there could be a problem with the value being too large.
One helpful thing to try is to turn on diagnostics, which will tell you what x-values WeBWorK is using to compare the answer, and what the corresponding values of the student answer and correct answer are.

You can do this by setting "diagnostics=>1" in your cmp() call, i.e.
$F1->cmp(upToConstant=>1, diagnostics=>1)

In reply to Sean Fitzpatrick

Re: Odd floating point error?

by Davide Cervone -
Danny's advice is a good start, but in this case, it is hard to tell what is going on from the diagnostic output. The key information is that it costs the adaptive value for C0 to be -0.5, but it should be zero, since the student answer and the correct answer should be equal.

It took me a bit of digging to find out what the issue was, but the issue ends up being (as Danny expected) that the values of the function can get very large. This happens during the determination of the value for C0, because one of the points used is x = 1.8 (roughly), and for this value, (1/6)e^(x^6) is on the order of 10^15 in size. Since floating-point reals store about 16 to 17 digits, that means that the least significant digits are in the 1/10 and 1/100 positions. It turns out that, at x = 1.8, e^(x^6)/6 - (1/6)e^(x^6) = -.5 rather than 0, and that is where the bad value of C0 is coming from (the computation for C0 is actually a little more complicated than that, but it gives the right idea).

Unfortunately, you don't see this x value in the diagnostics display, because the points used for the adaptive computation aren't shown there (they aren't recorded in a place where the diagnostics can see them).

One solution is restricting the range of x values, say from -1 to 1 rather than the default of -2 to 2.

The adaptive computations have some parameters that will cause a warning if the adaptive parameter gets too large, but really, it should have warnings if the FUNCTION values get too large to make computing the adaptive values reliable.
In reply to Davide Cervone

Re: Odd floating point error?

by Sean Fitzpatrick -
Thanks. I found that allowing a large relative tolerance didn't help. Diagnostics at least showed that one of the test points was way off in the comparison, as you've pointed out.
Restricting test values seems to be the safest bet. This solves the issue.