Simple assertion giving incorrect result?

3 visualizzazioni (ultimi 30 giorni)
Justin Wyss-Gallifent
Justin Wyss-Gallifent il 11 Lug 2020
Modificato: Walter Roberson il 11 Lug 2020
Here's a simple version of something that's arising in some code. The student needs to use vpasolve. The reference solution is this:
syms x
x1 = vpasolve(exp(abs(0.1*x))+2*sin(x)==0,-2)
This reference solution returns a value:
x1 =
-2.4487454187687442582374719820392
When the student puts in a different seed value for vpasolve:
syms x
x1 = vpasolve(exp(abs(0.1*x))+2*sin(x)==0,-3)
The learner solution returns the same value as the reference solution:
x1 =
-2.4487454187687442582374719820392
However doing a simple assertion test of whether these two variables are equal fails. Why would this happen?

Risposte (2)

Justin Wyss-Gallifent
Justin Wyss-Gallifent il 11 Lug 2020
I'm going to answer my own question here and leave it for reference. This is because vpasolve returns a symbolic expression which is slightly different even though all digits (shown) are the same. Symbolic variables have no sense of tolerance and so this fails a straight-up variable comparison. This was fixed by changing the test to Matlab code as:
x1 = double(x1)
assessVariableEqual('x1', double(referenceVariables.x1))
  2 Commenti
John D'Errico
John D'Errico il 11 Lug 2020
Sorrry, but this is still wrong. The answer is to NEVER assume a floating point number is known identically. The rsult from vpasolve is still a floating point number. It just has more digits.
The same statement of mine is true, even for double precision numbers. NEVER assume they will be identical. Testing for identically equal floating point numbers will result in failure, and then you will be back here, wondering why you have a problem.
When you test for same-ness of two floating point numbers, use a tolerance. Test to see if the absolute value of the difference is sufficiently small.
Walter Roberson
Walter Roberson il 11 Lug 2020
Modificato: Walter Roberson il 11 Lug 2020
assessVariableEqual() is part of Grader. It uses a tolerance, but only for numeric items (symbolic items are not considered numeric for this purpose.)

Accedi per commentare.


Walter Roberson
Walter Roberson il 11 Lug 2020
Symbolic floating point values have some guard digits that are not displayed when you output the number
  2 Commenti
Justin Wyss-Gallifent
Justin Wyss-Gallifent il 11 Lug 2020
Well it's less that than the fact that because the output is symbolic it has no sense of tolerance. This is one of the (admittedly many) things about Matlab that drive me crazy - the output of vpasolve looks like a number but isn't really a number, but sort of is, but isn't.
Walter Roberson
Walter Roberson il 11 Lug 2020
consider that if you have
A = 1
B = A*(1-eps)
then no matter which numeric "format" statement you choose, A and B will display the same (well, other than format hex). They will not compare equal because floating point has no sense of tolerance. assessVariableEqual is not part of MATLAB, it is part of the Grader tool.
Perhaps you are saying that assessVariableEqual has no sense of tolerance for symbolic values, but any tolerance it does have is part the grader. MATLAB itself has no approximately_equal operator, just ismembertol function call.

Accedi per commentare.

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by