# PGfunctionevaluators.pl - Macros that generate function answer evaluators.

### From WeBWorK

- NAME
- SYNOPSIS
- DESCRIPTION
- fun_cmp
- Single-variable Function Comparisons
- function_cmp
- function_cmp_up_to_constant
- function_cmp_abs
- function_cmp_up_to_constant_abs
- adaptive_function_cmp
- Multi-variable Function Comparisons
- SEE ALSO

# NAME

PGfunctionevaluators.pl - Macros that generate function answer evaluators.

# SYNOPSIS

ANS(fun_cmp($answer_or_answer_array_ref, %options));

ANS(function_cmp($correctEqn, $var, $llimit, $ulimit, $relTol, $numPoints, $zeroLevel, $zeroLevelTol)); ANS(function_cmp_up_to_constant($correctEqn, $var, $llimit, $ulimit, $relpercentTol, $numOfPoints, $maxConstantOfIntegration, $zeroLevel, $zeroLevelTol)); ANS(function_cmp_abs($correctFunction, $var, $llimit, $ulimit, $absTol, $numOfPoints)); ANS(function_cmp_up_to_constant_abs($correctFunction, $var, $llimit, $ulimit, $absTol, $numOfPoints, $maxConstantOfIntegration));

# DESCRIPTION

Function answer evaluators take in a function, compare it numerically to a correct function, and return a score. They can require an exactly equivalent function, or one that is equal up to a constant. They can accept or reject an answer based on specified tolerances for numerical deviation.

The general function answer evaluator is `fun_cmp()`

. It takes a hash of named
options as parameters. There are also several specific function_cmp_*() answer
evaluators for use in common situations which feature a simplified syntax.

## MathObjects and answer evaluators

The MathObjects system provides a Formula->`cmp()`

method that produce answer
evaluators for function comparisons. `fun_cmp()`

has been rewritten to use
Formula->`cmp()`

to produce the answer evaluator. It is recommended that you use
the Formula object's `cmp()`

method directly if possible.

# fun_cmp

ANS(fun_cmp($answer_or_answer_array_ref, %options));

Compares a function or a list of functions, using a named hash of options to set
parameters. This can make for more readable code than using the `function_cmp()`

style, but some people find one or the other easier to remember.

## Options

$answer_or_answer_array_ref can either be a string scalar representing the
correct formula or a reference to an array of string scalars. If multiple
formulas are provided, `fun_cmp()`

will return a list of answer evaluators, one
for each answer specified. The answer can contain functions, pi, e, and
arithmetic operations. However, the correct answer string follows a slightly
stricter syntax than student answers; specifically, there is no implicit
multiplication. So the correct answer must be "3*x" rather than "3 x". Students
can still enter "3 x".

%options is a hash containing options that affect the way the comparison is performed. All hash items are optional. Allowed options are:

**mode**-
This determines the evaluation mode. The recognized modes are:

**std (default)**-
Function must match exactly.

**antider**-
Function must match up to a constant.

**tol**-
An absolute tolerance value. When the student and correct functions are evaluated, the result for each evaluation point must be within a fixed distance from the correct answer to qualify. For example, an absolute tolerance of 5 means that any result which is +-5 of the correct answer qualifies as correct. abstol is accepted as a synonym for tol.

**relTol**-
A relative tolerance. Relative tolerances are given in percentages. A relative tolerance of 1 indicates that when the student's function are evaluated, the result of evaluation at each point must be within within 1% of the correct answer to qualify as correct. In other words, a student answer is correct when

abs(studentAnswer - correctAnswer) <= abs(.01*relTol*correctAnswer)

tol and relTol are mutually exclusive. reltol is also accpeted as a synonym for relTol.

**zeroLevel, zeroLevelTol**-
zeroLevel and zeroLevelTol specify a alternative absolute tolerance to use when the correct answer is very close to zero.

If the correct answer has an absolute value less than or equal to zeroLevel, then the student answer must be, in absolute terms, within zeroLevelTol of correctAnswer, i.e.,

abs(studentAnswer - correctAnswer) <= zeroLevelTol

In other words, if the correct answer is very near zero, an absolute tolerance will be used. One must do this to handle floating point answers very near zero, because of the inaccuracy of floating point arithmetic. However, the default values are almost always adequate.

**var**-
The var parameter can contain a number, a string, or a reference to an array of variable names. If it contains a number, the variables are named automatically as follows:

var | variables used -----+-------------------- 1 | x 2 | x, y 3 | x, y, z 4+ | x_1, x_2, x_3, ...

If the var parameter contains a reference to an array of variable names, then the number of variables is determined by the number of items in the array. For example:

var=>['r','s','t']

If the var parameter contains a string, the string is used as the name of a single variable. Hence, the following are equivalent:

var=>['t'] var=>'t'

vars is recognied as a synonym for var. The default is a single variable, x.

**limits**-
Limits are specified with the limits parameter. If you specify limits for one variable, you must specify them for all variables. The limit parameter must be a reference to an array of arrays of the form

`[$lower_limit. $upper_limit]`

, each array corresponding to the lower and upper endpoints of the (half-open) domain of one variable. For example,vars=>2, limits=>[[0,2], [-3,8]]

would cause x to be evaluated in [0,2) and y to be evaluated in [-3,8). If only one variable is being used, you can write either:

limits => [[0,3]] limits => [0,3]

domain is recognized as a synonym for limits.

**test_points**-
In some cases, the problem writer may want to specify the points used to check a particular function. For example, if you want to use only integer values, they can be specified. With one variable, either of these two forms work:

test_points=>[1,4,5,6] test_points=>[[1,4,5,6]]

With more variables, specify the list for the first variable, then the second, and so on:

vars=>['x','y'], test_points=>[[1,4,5],[7,14,29]]".

If the problem writer wants random values which need to meet some special restrictions (such as being integers), they can be generated in the problem:

test_points=>[random(1,50), random(1,50), random(1,50), random(1,50)]

Note that test_points should not be used for function checks which involve parameters (either explicitly given by "params", or as antiderivatives).

**numPoints**-
The number of sample points to use when evaluating the function.

**maxConstantOfIntegration**-
Maximum size for the constant of integration (in antider mode).

**params**-
A reference to an array of "free" parameters which can be used to adapt the correct answer to the submitted answer. (e.g. ['c'] for a constant of integration in the answer x^3/3+c.

**debug**-
If set to one, extra debugging information will be output.

## Examples

# standard compare, variable is x fun_cmp("3*x");

# standard compare, defaults used for all three functions fun_cmp(["3*x", "4*x+3", "3*x**2"]);

# standard compare, variable is t fun_cmp("3*t", var=>'t');

# x, y and z are the variables fun_cmp("5*x*y*z", var=>3);

# student answer must match up to constant (i.e., 5x+C) fun_cmp("5*x", mode=>'antider');

# x is evaluated in [0,2), y in [5,7) fun_cmp(["3*x*y", "4*x*y"], limits=>[[0,2], [5,7]]);

# Single-variable Function Comparisons

There are four single-variable function answer evaluators: "normal," absolute tolerance, antiderivative, and antiderivative with absolute tolerance. All parameters (other than the correct equation) are optional.

## function_cmp

ANS(function_cmp($correctEqn, $var, $llimit, $ulimit, $relTol, $numPoints, $zeroLevel, $zeroLevelTol));

`function_cmp()`

uses standard comparison and relative tolerance. It takes a
string representing a single-variable function and compares the student answer
to that function numerically. $var, $relTol, $numPoints, $zeroLevel, and
$zeroLevelTol are equivalent to the identically-named options to `fun_cmp()`

,
above. $llimit and $ulimit are combined to form the value of limits above.

## function_cmp_up_to_constant

ANS(function_cmp_up_to_constant($correctEqn, $var, $llimit, $ulimit, $relpercentTol, $numOfPoints, $maxConstantOfIntegration, $zeroLevel, $zeroLevelTol));

`function_cmp_up_to_constant()`

uses antiderivative compare and relative
tolerance. All but the first argument are optional. All options work exactly
like `function_cmp()`

, except of course $maxConstantOfIntegration. It will accept
as correct any function which differs from $correctEqn by at most a constant;
that is, if

$studentEqn = $correctEqn + C, where C <= $maxConstantOfIntegration

the answer is correct.

## function_cmp_abs

ANS(function_cmp_abs($correctFunction, $var, $llimit, $ulimit, $absTol, $numOfPoints));

`function_cmp_abs()`

uses standard compare and absolute tolerance. All but the
first argument are optional. $absTol defines the absolute tolerance value. See
the corresponding option to `fun_cmp()`

, above. All other options work exactly as
for `function_cmp()`

.

## function_cmp_up_to_constant_abs

ANS(function_cmp_up_to_constant_abs($correctFunction, $var, $llimit, $ulimit, $absTol, $numOfPoints, $maxConstantOfIntegration));

`function_cmp_up_to_constant_abs()`

uses antiderivative compare and absolute
tolerance. All but the first argument are optional. $absTol defines the absolute
tolerance value. See the corresponding option to `fun_cmp()`

, above. All other
options work exactly as with `function_cmp_up_to_constant()`

.

## adaptive_function_cmp

FIXME undocumented.

# Multi-variable Function Comparisons

## [DEPRECATED] multivar_function_cmp

ANS(multivar_function_cmp($correctFunction, $var, $limits, $relTol, $numPoints, $zeroLevel, $zeroLevelTol));

This function is deprecated. Use fun_cmp instead:

ANS(fun_cmp($correctFunction, var=>$var, limits=>$limits, ...));

# SEE ALSO

the PGanswermacros.pl manpage, *MathObjects*.