Difference between revisions of "FormulaTestPoints"

From WeBWorK_wiki
Jump to navigation Jump to search
(added historical tag and gave updated problem link)
 
(17 intermediate revisions by 8 users not shown)
Line 1: Line 1:
  +
{{historical}}
  +
  +
<p style="font-size: 120%;font-weight:bold">This problem has been replaced with [https://openwebwork.github.io/pg-docs/sample-problems/Misc/FormulaTestPoints.html a newer version of this problem]</p>
  +
  +
<p>When the solution to a problem is a formula, WeBWorK compares student answers to the given solution by evaluating them at a set of randomly chosen test points. If for all test points, neither the correct answer nor the student's evaluate to anything, an error "Can't generate enough valid points for comparison" is signaled. Thus, it is important that the test points be chosen from an interval contained in the domain of the correct answer. For instance, if a Real variable is going to have its logarithm taken, or raised to a non-integer power, then it should always be positive (<b>NB:</b> even <i>rational exponents with odd denominator</i> such as cube roots, which mathematically apply unproblematically to negative numbers, should have their domains restricted to positive numbers, since floating-point arithmetic is not reliable about being able to do such computations.) The default range from which these points are chosen is -2 to 2 for MathObjects (and -1 to 1 for the traditional checkers); this page explains how to change it.</p>
  +
 
<h2>Formula Test Points for Evaluation: PG Code Snippet</h2>
 
<h2>Formula Test Points for Evaluation: PG Code Snippet</h2>
   
Line 10: Line 16:
   
 
<p style="text-align:center;">
 
<p style="text-align:center;">
[[IndexOfProblemTechniques|Problem Techniques Index]]
+
[[Problem_Techniques|Problem Techniques Index]]
 
</p>
 
</p>
   
Line 21: Line 27:
 
<td style="background-color:#ffffdd;border:black 1px dashed;">
 
<td style="background-color:#ffffdd;border:black 1px dashed;">
 
<pre>
 
<pre>
Context()-&gt;variables-&gt;set(x=&gt;{limits=&gt;[-1,1]});
 
  +
Context("Numeric");
$func = Compute("sqrt(x+1)");
 
  +
Context()-&gt;variables-&gt;set(x=&gt;{limits=&gt;[-1,1]});
  +
$func = Compute("sqrt(x+1)");
   
## Alternately:
+
## Alternately:
# Context()-&gt;flags-&gt;set(limits=&gt;[-1,1]);
+
Context()-&gt;flags-&gt;set(limits=&gt;[2,5]);
# $func = Compute("sqrt(x+1)");
+
# $func = Compute("sqrt(x-1)");
   
## Or, setting the limits only for the given
+
## Or, setting the limits only for the given
## formula, we don't need to reset the Context,
+
## formula, we don't need to reset the Context,
## and just include
+
## and just include
# $func = Compute("sqrt(x+1)");
+
# $func = Compute("sqrt(x-1)");
# $func-&gt;{limits} = [-1,1];
+
# $func-&gt;{limits} = [2,5];
   
$gunc = Compute("sqrt(x^2 - 4)");
+
$gunc = Compute("sqrt(x^2 - 4)");
$gunc-&gt;{test_points} = [[-3],[-2],[2],[3],[4]];
+
$gunc-&gt;{test_points} = [[-3],[-2],[2],[3],[4]];
  +
#$gunc-&gt;{test_at} = [[-3],[-2],[2],[3],[4]];
 
</pre>
 
</pre>
 
</td>
 
</td>
Line 43: Line 50:
 
</p>
 
</p>
 
<p>
 
<p>
It is also possible to specify the actual points on which the Formula will be evaluated. This is an attribute of the Formula itself; the call is shown for our formula <code>$gunc</code>. In this case there is only one variable, so we have only to specify a single value for each point where the function is to be evaluated. If the function were a function of two variables, then we might use something like <code>$formula-&gt;{test_points}&nbsp;= [[-3,-2],[-2,0],[2,0],[3,2],[4,5]]</code>. <em>Note that the test points are given in alphabetical order! Thus, if the variables in the formula are specified as x and C, the test point [3,2] is C=3 and x=2.</em>
+
It is also possible to specify the actual points on which the Formula will be evaluated. This is an attribute of the Formula itself; the call is shown for our formula <code>$gunc</code>. In this case there is only one variable, so we have only to specify a single value for each point where the function is to be evaluated.
  +
(Using <code>test_at</code> adds the specified points to those already chosen from the continuous domain while with <code>test_points</code> only the specified test points are used.)
  +
If the function were a function of two variables, then we might use something like <code>$formula-&gt;{test_points}&nbsp;= [[-3,-2],[-2,0],[2,0],[3,2],[4,5]]</code>. <em>Note that the test points are given in alphabetical order by variable name! Thus, if the variables in the formula are specified as x and C, the test point [3,2] is C=3 and x=2.</em>
 
</p>
 
</p>
 
<p>
 
<p>
One final note: if the formula is a function of more than one variable and we're specifying limits in the formula, we need to specify the limits for all variables. Thus, we'd have something like <code>$formula-&gt;{limits}&nbsp;= [[-1,1],[0,2]]</code>. Again, the limits are specified for each variable in alphabetical order.
 
  +
It is possible to test at points that are not defined in the correct solution (e.g., to verify that a student didn't enter <code>ln(|x|)</code> instead of <code>ln(x)</code>). To avoid having this throw an error, however, we must tell the formula that it's allowed by setting <code>$gunc-&gt;{allowUndefinedPoints} = 1</code>.
  +
</p>
  +
<p>
  +
Note: if the formula is a function of more than one variable and we're specifying limits in the formula, we need to specify the limits for all variables. Thus, we'd have something like <code>$formula-&gt;{limits}&nbsp;= [[-1,1],[0,2]]</code>. Again, the limits are specified for each variable in alphabetical order.
  +
</p>
  +
<p>
  +
Also note that your test points must contain one value per variable, even if it doesn't appear in the formula; for instance, if <code>$gunc</code> is a function only of y, then you still need to include values for x <em>and</em> y, not just y. The alternative is to use the command
  +
<code>Context() -> variables -> are (y => 'Real')</code> early in your .pg file, which will remove the (default) variable x from the problem.
  +
</p>
  +
<p>
  +
If you are trying to set test points for a function you have added to the context (e.g., using <code>parserFunction.pl</code>) you should use the syntax <code>$h->with(test_at=>[[1],[2]])</code> as in the following code snippet:
  +
<pre>
  +
loadMacros("parserFunction.pl");
  +
  +
Context("Numeric");
  +
parserFunction("m(x)" => "log(x/2)" );
  +
$h = Formula("5 m(x)+2");
  +
$answer = $h->with(test_at => [[1],[2]]);
  +
</pre>
  +
</p>
  +
<p>
  +
If you want to add a variable <code>n</code> to the context that is only evaluated at integers, use integer limits and a resolution of 1 as in the following example:
  +
<pre>
  +
Context()->variables->add(n => ['Real', limits=>[1,20],
  +
resolution=>1]);
  +
</pre>
 
</p>
 
</p>
 
</td>
 
</td>
Line 53: Line 85:
 
<td style="background-color:#ffdddd;border:black 1px dashed;">
 
<td style="background-color:#ffdddd;border:black 1px dashed;">
 
<pre>
 
<pre>
BEGIN_TEXT
+
BEGIN_TEXT
Enter \( $func \): \{ ans_rule(35) \}
+
Enter \( $func \): \{ ans_rule(35) \}
$BR
+
$BR
Enter \( $gunc \): \{ ans_rule(35) \}
+
Enter \( $gunc \): \{ ans_rule(35) \}
END_TEXT
+
END_TEXT
 
</pre>
 
</pre>
 
<td style="background-color:#ffcccc;padding:7px;">
 
<td style="background-color:#ffcccc;padding:7px;">
Line 68: Line 100:
 
<td style="background-color:#eeddff;border:black 1px dashed;">
 
<td style="background-color:#eeddff;border:black 1px dashed;">
 
<pre>
 
<pre>
ANS( $func->cmp() );
+
ANS( $func->cmp() );
ANS( $gunc->cmp() );
+
ANS( $gunc->cmp() );
 
</pre>
 
</pre>
 
<td style="background-color:#eeccff;padding:7px;">
 
<td style="background-color:#eeccff;padding:7px;">
Line 133: Line 165:
 
[[IndexOfProblemTechniques|Problem Techniques Index]]
 
[[IndexOfProblemTechniques|Problem Techniques Index]]
 
</p>
 
</p>
  +
  +
[[Category:Problem Techniques]]

Latest revision as of 08:28, 28 June 2023

This article has been retained as a historical document. It is not up-to-date and the formatting may be lacking. Use the information herein with caution.

This problem has been replaced with a newer version of this problem

When the solution to a problem is a formula, WeBWorK compares student answers to the given solution by evaluating them at a set of randomly chosen test points. If for all test points, neither the correct answer nor the student's evaluate to anything, an error "Can't generate enough valid points for comparison" is signaled. Thus, it is important that the test points be chosen from an interval contained in the domain of the correct answer. For instance, if a Real variable is going to have its logarithm taken, or raised to a non-integer power, then it should always be positive (NB: even rational exponents with odd denominator such as cube roots, which mathematically apply unproblematically to negative numbers, should have their domains restricted to positive numbers, since floating-point arithmetic is not reliable about being able to do such computations.) The default range from which these points are chosen is -2 to 2 for MathObjects (and -1 to 1 for the traditional checkers); this page explains how to change it.

Formula Test Points for Evaluation: PG Code Snippet

This code snippet shows the essential PG code to specify the points on which a formula is evaluated when a student's answer is checked. Note that these are insertions, not a complete PG file. This code will have to be incorporated into the problem file on which you are working.

This can, of course, be done with new and old-style answer evaluators. An example of the latter appears below. Also note that we may want to do this in two different ways: either by setting the domain on which the formula is evaluated (that is, the limits of evaluation), or by setting specific test points on which the formula should be considered. These are both shown below.

Problem Techniques Index

PG problem file Explanation
Context("Numeric");
Context()->variables->set(x=>{limits=>[-1,1]});
$func = Compute("sqrt(x+1)");

## Alternately:
Context()->flags->set(limits=>[2,5]);
# $func = Compute("sqrt(x-1)");

## Or, setting the limits only for the given
##    formula, we don't need to reset the Context,
##    and just include
# $func = Compute("sqrt(x-1)");
# $func->{limits} = [2,5];

$gunc = Compute("sqrt(x^2 - 4)");
$gunc->{test_points} = [[-3],[-2],[2],[3],[4]];
#$gunc->{test_at} = [[-3],[-2],[2],[3],[4]];

We don't have to change anything in the documentation and tagging or initialization sections of the PG file. In the problem set-up, we can specify the limits on which all Formulas are evaluated by setting the limits for the variable in the problem (in this case, x) in the Context. Alternately, we can set the Context flag limits to set the limits on all variables in the Context, as shown in the commented-out line, or can set the limits for the formula itself, as in the second commented-out line. (Obviously, only one of these three is needed.)

It is also possible to specify the actual points on which the Formula will be evaluated. This is an attribute of the Formula itself; the call is shown for our formula $gunc. In this case there is only one variable, so we have only to specify a single value for each point where the function is to be evaluated. (Using test_at adds the specified points to those already chosen from the continuous domain while with test_points only the specified test points are used.) If the function were a function of two variables, then we might use something like $formula->{test_points} = [[-3,-2],[-2,0],[2,0],[3,2],[4,5]]. Note that the test points are given in alphabetical order by variable name! Thus, if the variables in the formula are specified as x and C, the test point [3,2] is C=3 and x=2.

It is possible to test at points that are not defined in the correct solution (e.g., to verify that a student didn't enter ln(|x|) instead of ln(x)). To avoid having this throw an error, however, we must tell the formula that it's allowed by setting $gunc->{allowUndefinedPoints} = 1.

Note: if the formula is a function of more than one variable and we're specifying limits in the formula, we need to specify the limits for all variables. Thus, we'd have something like $formula->{limits} = [[-1,1],[0,2]]. Again, the limits are specified for each variable in alphabetical order.

Also note that your test points must contain one value per variable, even if it doesn't appear in the formula; for instance, if $gunc is a function only of y, then you still need to include values for x and y, not just y. The alternative is to use the command Context() -> variables -> are (y => 'Real') early in your .pg file, which will remove the (default) variable x from the problem.

If you are trying to set test points for a function you have added to the context (e.g., using parserFunction.pl) you should use the syntax $h->with(test_at=>[[1],[2]]) as in the following code snippet:

loadMacros("parserFunction.pl");

Context("Numeric");
parserFunction("m(x)" => "log(x/2)" );
$h = Formula("5 m(x)+2");
$answer = $h->with(test_at => [[1],[2]]);

If you want to add a variable n to the context that is only evaluated at integers, use integer limits and a resolution of 1 as in the following example:

Context()->variables->add(n => ['Real', limits=>[1,20], 
    resolution=>1]);

BEGIN_TEXT
Enter \( $func \): \{ ans_rule(35) \}
$BR
Enter \( $gunc \): \{ ans_rule(35) \}
END_TEXT

The text portion of the file is the same as usual.

ANS( $func->cmp() );
ANS( $gunc->cmp() );

And the answer evaluation is as we'd expect.

With old-style answer evaluators, we can do the same thing:

PG problem file Explanation
  $func = "sqrt(x+1)";
  $gunc = "sqrt(x^2 - 4)";

We define the functions as expected in the problem set-up section of the file.

  BEGIN_TEXT
  Enter \( \sqrt{x+1} \): \{ ans_rule(35) \}
  $BR
  Enter \( \sqrt{x^2 - 4} \): 
  \{ ans_rule(35) \}
  END_TEXT

And the text portion of the file is similarly mundane.

  ANS(fun_cmp($func, limits=>[-1,1]));
  ANS(fun_cmp($gunc, test_points=>[-3,-2,2,3,4]));

The limits or test points are specified in the fun_cmp call. Note that we can use the short-hand [-3,-2,2,3,4] for the list of points when there is only one variable; in the case of multiple variables, we would have to specify a list of lists as we did above.

Problem Techniques Index