Forum archive 2000-2006

Gavin LaRose - numerical vs string comp (possible parser evaluation question)

Gavin LaRose - numerical vs string comp (possible parser evaluation question)

by Arnold Pizer -
Number of replies: 0
inactiveTopicnumerical vs string comp (possible parser evaluation question) topic started 11/20/2006; 11:34:51 AM
last post 11/20/2006; 2:35:04 PM
userGavin LaRose - numerical vs string comp (possible parser evaluation question)  blueArrow
11/20/2006; 11:34:51 AM (reads: 85, responses: 3)
Hi all,

I suspect that the following is a feature of my misunderstanding the return values of some parser variables or methods. I'm including a problem below, which, with psvn 4114, generates $profitLower = 416.25 and $profitUpper = 415.84, and reports that $profitLower == $profitUpper. However, using string comparison, $profitLower lt $profitUpper, as it "should" be. Am I not forcing a numerical return value when I think I am? Is there something else going on? Thoughts and comments welcome.

Thanks,
Gavin

Included problem:
DOCUMENT();
loadMacros(
PG.pl,
PGbasicmacros.pl,
PGchoicemacros.pl,
PGanswermacros.pl,
PGauxiliaryFunctions.pl,
"Parser.pl",
);



# pick some sensible values for the coefficients
$a = 0.01; $b = random(50,90,10)*$a; $c = random(8,13,1);
$p = $c - 2;



Context()->variables->add(q=>'Real');



$profit = Formula("$p q - $cost");
$qmax = Formula( "($b + sqrt($b^2 - 3 $a($c - $p)))/(3 $a)" );
# get a numerical value (?)
$qmaxn = $qmax->eval();



$qlower = int($qmaxn);
$qupper = ( $qmaxn eq $qlower ) ? $qlower : $qlower + 1;
$profitLower = $profit->eval(q=>$qlower);
$profitUpper = $profit->eval(q=>$qupper);
if ( $profitLower > $profitUpper ) {
$maxProfit = $profitLower;
$message = "L gt U";
} elsif ( $profitLower < $profitUpper ) {
$maxProfit = $profitUpper;
$message = "U gt L";
} else {
$maxProfit = $profitUpper;
$message = "L eq U";
}



TEXT(&beginproblem);
Context()->texStrings;



BEGIN_TEXT
The larger of $profitLower and $profitUpper is:
\{ ans_rule(15) \}
$BR
(The correct answer is $maxProfit, b/c $message.)



END_TEXT



ANS( num_cmp($maxProfit, tol=>.001) );



ENDDOCUMENT();

<| Post or View Comments |>


userGavin LaRose - Re: numerical vs string comp (possible parser evaluation question)  blueArrow
11/20/2006; 1:12:16 PM (reads: 95, responses: 0)
Hi all,

As a follow-up: I don't now think that it's a parser issue. I've just found another problem where the numeric comparison doesn't work, viz.,

   ...
$qv1 = $b/(3*$a);
if ( $qv1 eq int($qv1) ) {
$expl = '';
} else {
$expl = "the two aren't equal...";
}
...

Which behaves similarly to the previous case; with numeric equality testing (==), it fails, and with string equality (eq), it tests correctly. So I'm still confused by this.

Gavin

<| Post or View Comments |>


userDavide P. Cervone - Re: numerical vs string comp (possible parser evaluation question)  blueArrow
11/20/2006; 1:49:57 PM (reads: 90, responses: 0)
Gavin:

The comparisons for Parser reals are fuzzy checks based on the tolerances in place for the problem. In your case, 416.25 and 415.84 have a relative difference of .00098, which is below the tolerance of .001, and so these ARE equal as far as fuzzy tolerances are concerned.

Since a < b, a == b, a > b are supposed to be mutually exclusive conditions, when fuzzy math is used, a < b means that two conditions are met: a < b in the absolute sense and a != b in the fuzzy sense. Similarly for a > b. The idea is to prevent a < b and a == b from BOTH being true simultaneously

So the effect you are obtaining is correct, but not what you expected. If you really want to do an absolute rather than fuzzy check, use $profitLower->value < $profitUpper->value which will force a non-fuzzy comparison.

You definitely do NOT want to do string comparisons for these things.

As for your other example, I'm not sure what it means to "fail" or "test correctly" in this case, since I don't know what the values of $b and $a are, and whether they are Parser Reals or not. (Both of which will make a difference.) If they are Parser Reals, then the numeric equality is a fuzzy equality based on the current tolerances.

If they aren't Parser Reals, I don't think you'd want to do $qv1 == int($qv1) either, since you really DO want to do a fuzzy check (but perhaps with sharper tolerances) rather than a floating point equality comparison.

If they are Parser Reals, you might try $qv1 - int($qv1) == 0 instead, since that will kick in the zero tolerance rather than the standard relative tolerance for non-zero numbers. This suggests you could also use $profitLower - $profitUpper < 0 rather than $profitLower < $profitUpper as well to get fuzzy checks against zero (where the zeroLevelTolerance takes over).

Davide

<| Post or View Comments |>


userGavin LaRose - Re: numerical vs string comp (possible parser evaluation question)  blueArrow
11/20/2006; 2:35:04 PM (reads: 85, responses: 0)
Hi Davide,

Thanks. I think that clears it up. The first example is using Parser Reals, the latter just straight arithmetic comparison. I had misread the problems as arising from the same issue on account of getting something that looked like correct behavior by making the same change in both.

Changing to $var->value fixes the first case, and the second, as you noted, requires being careful with the tolerance allowed when testing inequality. I've bumped into that before, so you might think that I'd have thought of that, but I evidentally didn't learn quite enough then.

Thanks again,
Gavin

<| Post or View Comments |>