moodle-qtype_formulas icon indicating copy to clipboard operation
moodle-qtype_formulas copied to clipboard

Add function for equality with absolute/relative tolerance

Open PhilippImhof opened this issue 3 months ago • 2 comments

It is often required to perform either types of tolerance check. Having to write abs(a - b) < abs_tol or abs(a - b) < rel_tol * max(abs(a), abs(b)) for every comparison can quickly become tedious.

It would therefore be convenient to have a function like Python’s math.isclose(a, b, rel_tol=1e-09, abs_tol=0.0).

Originally posted by @dbauer-ets in #208

PhilippImhof avatar Sep 26 '25 20:09 PhilippImhof

Just thinking of it, I wonder whether it might make sense to allow setting a default value per question. Say we already have a variable tolerance = 0.001. Then, if I have to write

is_close(_0, x, tolerance)

I could just as well write

abs(_0 - x) < tolerance

The suggested change in notation would thus only be helpful for the relative error, because the right-hand side is longer than just a number or a variable.

Maybe I can find a way where we can write

set_tolerance(0.001);
is_close(_0, x);
is_rel_close(_1, y);
is_close(_2, x, 0.1);
is_rel_close(_3, y, 0.02);

As we can see, the function would support specifying different tolerance upon invocation. The setting of the tolerance could be done globally (global variables) and overridden locally per part (local or grading variables)

(The names above are just for illustration, I haven't yet decided how to call them. But I am sure the names should be short.)

@dbauer-ets What do you think about this, Dominique?

PhilippImhof avatar Nov 14 '25 07:11 PhilippImhof

Thinking of it further, I wonder: is there really a need for these functions?

We currently have the special variable _d which holds the absolute difference between the model answer and the student's response, so instead of

is_close(_0, x, 0.001)

one can write

_d[0] < 0.001

which is probably the shortest way to do this.

Instead of adding a new function, it might make sense to introduce another special variable _dr or _drel that would hold the relative difference between the model answer and the student's answer, with the model answer being the base. It could be set to NAN if the model answer is zero, and it would not be available for algebraic answer types. So one could write

_drel[0] < 0.001

instead of

is_rel_close(_0, x, 0.001)

Does that seem like a good solution to you @dbauer-ets?

Of course, having functions is_close() and is_rel_close() would allow the user to compare other numbers than just answers. But I don't know whether there is a real need for that.

PhilippImhof avatar Nov 14 '25 15:11 PhilippImhof