Difference between revisions of "Introduction to MathObjects"

From WeBWorK_wiki
Jump to navigation Jump to search
m (Indent class descriptions)
(Added information about Point class)
Line 99: Line 99:
 
=== Real ===
 
=== Real ===
   
: Real numbers with "fuzzy" comparison (governed by the same tolerances and settings that control student answer checking). For example, <code>Real(1.0) == Real(1.0000001)</code> will be true, while <code>Real(1.0) &lt; Real(1.0000001)</code> will be false. Reals can be added, subtracted, and so on, and the results will still be MathObject Reals. Similarly, <code>sin()</code>, <code>sqrt()</code>, <code>ln()</code>, and the other functions return Real objects if their arguments are Reals. For example:
+
: The Real class implements real numbers with "fuzzy" comparison (governed by the same tolerances and settings that control student answer checking). For example, <code>Real(1.0) == Real(1.0000001)</code> will be true, while <code>Real(1.0) &lt; Real(1.0000001)</code> will be false. Reals can be added, subtracted, and so on, and the results will still be MathObject Reals. Similarly, <code>sin()</code>, <code>sqrt()</code>, <code>ln()</code>, and the other functions return Real objects if their arguments are Reals. For example:
   
 
Context("Numeric");
 
Context("Numeric");
Line 118: Line 118:
 
=== Infinity ===
 
=== Infinity ===
   
: The positive infinity of the extended reals. This value can be negated and used in intervals, but can be added to Reals (or other MathObjects) and can't be used as an argument to functions like <code>sin()</code> or <code>sqrt()</code>. In perl code, you can use <code>Infinity</code> to obtain this value, or <code>-(Infinity)</code> to obtain its negation. E.g.,
+
: The Infinity class handles the positive infinity of the extended reals. This value can be negated and used in intervals, but can be added to Reals (or other MathObjects) and can't be used as an argument to functions like <code>sin()</code> or <code>sqrt()</code>. In perl code, you can use <code>Infinity</code> to obtain this value, or <code>-(Infinity)</code> to obtain its negation. E.g.,
   
 
Context("Numeric");
 
Context("Numeric");
Line 128: Line 128:
 
=== Complex ===
 
=== Complex ===
   
: Complex numbers with "fuzzy" comparison (due to the fact that the real and complex parts are handled using MathObject Reals). As with Real objects, you can add, subtract, multiply, and perform the other usual arithmetic operations on Complex objects, and can compute <code>sin()</code>, <code>sqrt()</code> and the other standard functions on Complex arguments. In addition, there are <code>arg()</code> and <code>mod()</code>, which return the argument or modulus of a Complex value, and <code>Re()</code> and <code>Im()</code> that return its real or imaginary part. The <code>conj()</code> function returns the complex conjugate of a Complex object. The value <code>i</code> represents <math>\sqrt{-1}</math> and can be used in your perl expressions to produce complex numbers. Note that you must use <code>-(i)</code> to obtain <math>-i</math> in perl expressions (but not in strings parsed by MathObjects, such as student answers or the arguments to <code>Compute()</code>).
+
: The Complex class implements complex numbers with "fuzzy" comparison (due to the fact that the real and complex parts are handled using MathObject Reals). As with Real objects, you can add, subtract, multiply, and perform the other usual arithmetic operations on Complex objects, and can compute <code>sin()</code>, <code>sqrt()</code> and the other standard functions on Complex arguments. In addition, there are <code>arg()</code> and <code>mod()</code>, which return the argument or modulus of a Complex value, and <code>Re()</code> and <code>Im()</code> that return its real or imaginary part. The <code>conj()</code> function returns the complex conjugate of a Complex object. The value <code>i</code> represents <math>\sqrt{-1}</math> and can be used in your perl expressions to produce complex numbers. Note that you must use <code>-(i)</code> to obtain <math>-i</math> in perl expressions (but not in strings parsed by MathObjects, such as student answers or the arguments to <code>Compute()</code>).
   
 
Context("Complex");
 
Context("Complex");
Line 143: Line 143:
 
$w = $z - (i); # parens needed in perl expressions
 
$w = $z - (i); # parens needed in perl expressions
   
=== List types ===
+
=== Point ===
  +
  +
: The Point class implements points in <math>{\bf R}^n</math> for arbitrary <math>n</math>. Typically, points are delimited by parentheses, but that can be controlled by settings in the Context. Points (of the same dimension) can be added and subtracted, or multiplied and divided by scalars. The answer checker for points can give students hints about the coordinates that are wrong, and about whether the number of coordinates is correct.
  +
  +
Context("Point");
  +
  +
$p = Point(3,0,-2);
  +
$p = Point([3,0,-2]);
  +
$p = Point("(3,0,-2)");
  +
$p = Compute("(3,0,-2)");
  +
  +
$q = $p + Point(1,3,7); # same as Point(4,3,5);
  +
$q = $p + [1,3,7]; # same as above
  +
$q = 3*$p; # same as Point(9,0,-6);
  +
$p = $p/2; # same as Point(3/2,0,-1);
  +
  +
=== Vector ===
  +
  +
=== Matrix ===
  +
  +
=== List ===
   
 
List objects are MathObjects whose description involves delimiters (parentheses) of some type. For example, points <code>(4,5)</code> or vectors <code>&lt;2,5&gt;</code>. Here are examples of the construction of the List Objects.
 
List objects are MathObjects whose description involves delimiters (parentheses) of some type. For example, points <code>(4,5)</code> or vectors <code>&lt;2,5&gt;</code>. Here are examples of the construction of the List Objects.
Line 152: Line 152:
 
* List: <code>$d = List("3, 7, 3+2i");</code>
 
* List: <code>$d = List("3, 7, 3+2i");</code>
   
=== Types that represent some subset of the real numbers ===
 
  +
=== Interval ===
  +
=== Set ===
  +
=== Union ===
   
 
* Interval: <code>$I = Interval("[0,1)");</code>
 
* Interval: <code>$I = Interval("[0,1)");</code>

Revision as of 12:41, 25 July 2012

What are MathObjects?

MathObjects are a set of formal objects that make the manipulation of mathematics within WeBWorK problems more intuitive. They make it possible to define variables as common mathematical objects, such as formulas, real number, complex numbers, intervals, vectors, points, and so on. For example:

   $f = Formula("sin(x^2+6)");
   $a = Real("sqrt(pi/6)");
   $z = Complex("1 + 5i");

These are useful (and powerful) because MathObjects "know" information about themselves; thus, we can add formulas to get new formulas, plug real objects into formulas to get formulas evaluated at those values, calculate derivatives of formulas, add and subtract intervals to form unions and intersections, and much more.

For several reasons it is usually preferable to write the MathObjects above using the Compute() function rather than the individual constructors for the various MathObject types.

   $f = Compute("sin(x^2+6)");
   $a = Compute("sqrt(pi/6)");
   $z = Compute("1 + 5i");

The Compute() function determines the kind of MathObject from the Context and from the syntax of its argument, which is usually a string value that is in the form that a student could type. The Compute function also sets the "correct answer" to be the exact string that it was given, so that if a student were asked to enter a number that matched $a from above and asked to see the correct answer (after the due date), then sqrt(pi/6) would be displayed rather than 0.723601. This gives you more control over the format of correct answers that are shown to students.


Why use MathObjects?

MathObjects are designed to be used in two ways. First, you can use them within your perl code when writing problems as a means of making it easier to handle formulas and other mathematical items, and in particular to be able to produce numeric values, TeX output, and answer strings from a single formula object. This avoids having to type a function three different ways (as a perl function, as a TeX string, and as an answer string), making it much easier to maintain a problem, or duplicate and modify it to use a different formula. Since MathObjects also included vectors, points, matrices, intervals, complex numbers, and a variety of other object types, it is easier to work with these kinds of values as well.

More importantly, using MathObjects improves the processing of student input. This is accomplished through special answer checkers that are part of the MathObjects' Parser package (rather than the traditional WeBWorK answer checkers). Each of these checkers has error checking customized to the type of input expected from the student and can provide helpful feedback if the syntax of the student's entry is incorrect. Because the MathObject checkers are part of a unified library, students get consistent error messages regardless of the type of answer that is expected or that they provide. For example, if a student enters a formula in an answer blank where the correct answer is actually a number, she will receive a message indicating that what she typed was a formula but that a number was expected. Thus students are given guidance automatically about this type of semantic problem with their answers. Answer checkers for points and vectors can indicate that the number of coordinates are wrong, or can tell the student which coordinates are incorrect (at the problem-author's discretion).

Answer checkers are available for each of the types of values that are part of the MathObjects library (numbers, complex numbers, infinities, points, vectors, intervals, sets, unions, formulas, lists of numbers, lists of points, lists of intervals, lists of formulas returning numbers, lists of formulas returning points, and so on). They are typically invoked using the notation $mathObject->cmp(). The pg/macros directory includes a number of extensions to the MathObjects library. Macro files that begin with parser typically define new classes of objects; e.g., parserParametricLine.pl defines a special class that handles parametric lines in arbitrary dimensions. These are documented in the Specialized parsers page.


MathObject Contexts

Although a problem may include several answer blanks, the problem generally has a collection of variables that it defines, values that it uses, and so on; these form the "context" of the problem. For example, if the problem is concerned with a function of x and y and its partial derivatives, then the context of the problem includes variable x and y, and so all the answer blanks within the problem should recognize that x and y have meaning within the problem, even if the answer blank is only asking for a number. If a student is asked to enter the value of a partial derivative at a particular point and, rather than giving a number, entered the formula for the derivative (not evaluated at the point), he should not be told "x is undefined" (which would have been the case with WeBWorK's traditional answer checkers), since x actually is defined as part of the problem. Such messages serve to confuse the student rather than help him resolve the problem.

MathObjects solves this issue by using a Context object to maintain the context of a problem. That way, all the answer blanks will know about all the variables and values defined within the problem, and can issue appropriate warning messages when a student uses them inappropriately. For example, in the situation described above where the student entered the unevaluated derivative where the value at a point was requested, he will get the message "Your answer is not a number (it seems to be a formula returning a number)", which should help him figure out what he has done wrong.

Thus one of the main purposes for the Context is to maintain the set of variables and values that are part of the problem as a whole. Another key function of the Context is to tell the answer checkers what functions and operations are available within a student answer, and what the various symbols the student can type will mean. For example, if you are asking a student to compute the value of 6 / 3, then you may want to restrict what the student can type so that she can't enter / in her answer, and must type an actual number (not an expression that is evaluated to a number). Or if you are asking a student to determine the value of sin(pi/6), you might want to restrict his answer so that he can't include sin(), but you do allow arithmetic operations. Such restrictions are also part of the context of the problem, and so are maintained by MathObjects as part of the Context.

In a similar way, some symbols mean different things in different problems. For example in a problem dealing with intervals, (4,5) means the interval between 4 and 5, while in a multi-variable calculus setting, it might mean a single point in the xy-plane. Or in a problem on complex numbers, the value i means the square root of -1, while in vector calculus, it would mean the coordinate unit vector along the x-axis. Or in a problem on inequalities, 5 < x would use < as the "less-than" sign, while in a vector calculus problem, <5,6,7> would mean the vector with coordinates 5, 6, and 7. The Context determines how these symbols will be interpreted by the MathObjects library.

MathObjects comes with a collection of predefined Contexts that you can call on to set the meanings of symbols like these to be what you need for your problems. The default Context is

   Context("Numeric");

and it will be sufficient to use the default context for most first-semester calculus problems. There are Contexts for complex numbers, inequalities, vectors, and so forth; see the list of basic contexts, and the links at the bottom of this document, for further information. The pg/macros directory includes a number of specialized Contexts as well; the files beginning with context define these, and are described on the Specialized contexts page. See the Introduction to contexts for information about how to modify an existing context (e.g., to add variables to it, or to restrict the functions that can be used).

It is possible to use more than one context within the same problem. This is discussed (need a link for this).


How to create a MathObject

In order to use MathObjects in a problem you are writing, include MathObjects.pl in your loadMacros() call. For example:

   loadMacros(
     "PGstandard.pl",
     "MathObjects.pl",
     "PGcourse.pl",
   );

Once this is done, there are several ways to create MathObjects in your problem:

  • By calling a constructor function for the type of object you want (e.g., Real(3.5) or Complex("3+4i"))
  • By calling Compute() to parse a string and return the resulting object (e.g., Compute("3+4i"))
  • By calling a method of an existing MathObject that returns another object (e.g., Formula("sin(x)")->eval(x => pi/2))
  • By combining existing MathObjects via mathematical operations (e.g., $x = Formula("x"); $f = $x**2 + 2*$x + 1)

Here are some examples:

   $a = Real(3.5);   or
   $a = Compute(3.5);   or
   $a = Compute("3.5");
   $b = Complex(3, 4);   or
   $b = Complex("3 + 4i");   or 
   $b = Compute("3 + 4i");
   $v = Vector(4,5,8);   or
   $v = Vector([4,5,8]);   or
   $v = Vector("<4,5,8>");  or
   $v = Compute("<4,5,8>");
   $f = Formula("sin(x^2) + 6");  or
   $f = Compute("sin(x^2) + 6");

Here, $a (defined any of the three ways) represents a real number and $b (defined by any of the three) represents a complex number; $v will be a vector, and $f is a formula.

In general, the Compute() variant is preferred because you enter what you want the student to type, and Compute() generates the proper MathObject to handle that (just as it will when it processes the student answer). Another important feature of Compute() is that the input string also serves as the correct answer when a student requests answers after the due date, which lets you put the correct answer in exactly the form you want it to appear. For example if you use

   Compute("<cos(pi/6),sin(pi/6), pi/6>")->cmp

the correct answer will be presented to the student as <cos(pi/6),sin(pi/6), pi/6>, while

   Vector("<cos(pi/6),sin(pi/6), pi/6>")->cmp

would show <0.866025,0.5,0.523599> as the correct answer.


The MathObject types

The MathObjects library defines the following object types:

Real

The Real class implements real numbers with "fuzzy" comparison (governed by the same tolerances and settings that control student answer checking). For example, Real(1.0) == Real(1.0000001) will be true, while Real(1.0) < Real(1.0000001) will be false. Reals can be added, subtracted, and so on, and the results will still be MathObject Reals. Similarly, sin(), sqrt(), ln(), and the other functions return Real objects if their arguments are Reals. For example:
   Context("Numeric");
   
   $a = Real(2);
   $b = $a + 5;     # same as Real(7);
   $c = sqrt($a);   # same as Real(sqrt(2));
This allows you to compute with Reals just as you would with native perl real numbers.
The value pi can be used in your perl code to represent the value of [math]\pi[/math]. Note that you must use -(pi) for [math]-\pi[/math] in perl expressions (but not in strings that will be parsed by MathObjects, such as student answers or arguments to Compute()). For instance:
   $a = pi + 2;              # same as Real("pi + 2");
   $b = 2 - (pi);            # same as Real("2 - pi");
   $c = sin(pi/2);           # same as Real(1);
   $d = Compute("2 - pi");   # parens only needed in perl expressions

Infinity

The Infinity class handles the positive infinity of the extended reals. This value can be negated and used in intervals, but can be added to Reals (or other MathObjects) and can't be used as an argument to functions like sin() or sqrt(). In perl code, you can use Infinity to obtain this value, or -(Infinity) to obtain its negation. E.g.,
   Context("Numeric");
   
   $Inf = Infinity;
   $MInf = -(Infinity);
   $I = Interval("(",0,Infinity,"]");   # easier as Interval("(0,infinity]");

Complex

The Complex class implements complex numbers with "fuzzy" comparison (due to the fact that the real and complex parts are handled using MathObject Reals). As with Real objects, you can add, subtract, multiply, and perform the other usual arithmetic operations on Complex objects, and can compute sin(), sqrt() and the other standard functions on Complex arguments. In addition, there are arg() and mod(), which return the argument or modulus of a Complex value, and Re() and Im() that return its real or imaginary part. The conj() function returns the complex conjugate of a Complex object. The value i represents [math]\sqrt{-1}[/math] and can be used in your perl expressions to produce complex numbers. Note that you must use -(i) to obtain [math]-i[/math] in perl expressions (but not in strings parsed by MathObjects, such as student answers or the arguments to Compute()).
   Context("Complex");
   
   $z = Complex(2,3);
   $z = 2 + 3 * i;
   $z = Complex("2 + 3i");
   $z = Compute("2 + 3i");
   
   $w = sin($z);      # same as Compute("sin(2+3i)");
   $w = conj($z);     # same as Complex("2 - 3i");
   $w = $z**2;        # same as Compute("(2+3i)^2");
   $w = $z + 5*i;     # same as Complex("2 + 8i");
   $w = $z - (i);     # parens needed in perl expressions

Point

The Point class implements points in [math]{\bf R}^n[/math] for arbitrary [math]n[/math]. Typically, points are delimited by parentheses, but that can be controlled by settings in the Context. Points (of the same dimension) can be added and subtracted, or multiplied and divided by scalars. The answer checker for points can give students hints about the coordinates that are wrong, and about whether the number of coordinates is correct.
   Context("Point");
   
   $p = Point(3,0,-2);
   $p = Point([3,0,-2]);
   $p = Point("(3,0,-2)");
   $p = Compute("(3,0,-2)");
   
   $q = $p + Point(1,3,7);   # same as Point(4,3,5);
   $q = $p + [1,3,7];        # same as above
   $q = 3*$p;                # same as Point(9,0,-6);
   $p = $p/2;                # same as Point(3/2,0,-1);

Vector

Matrix

List

List objects are MathObjects whose description involves delimiters (parentheses) of some type. For example, points (4,5) or vectors <2,5>. Here are examples of the construction of the List Objects.

  • Point: $a = Point("(4,5)");
  • Vector: $b = Vector("<3,5,6>");
  • Matrix: $c = Matrix("[[1,0],[0,1]]");
  • List: $d = List("3, 7, 3+2i");

Interval

Set

Union

  • Interval: $I = Interval("[0,1)");
  • Set (a finite collections of points): $S = Set("{3,5,6,8}");
  • Union (of intervals and sets): $U = Union("(-infinity,0] U [5,10)");

String

String is a special purpose type which allows comparison to an arbitrary string. The string which is the correct answer must also be one of the "legitimate" strings in the Context being used.
   String("DNE")

Formula

A Formula object represents a function whose output is one of the MathObject types defined above. Every Formula contains a parse tree which allows you to calculate output values from given input values.
   $f = Formula('2x^2+3x-5');
   $n = random(2,5,1);
   $g = Formula("$n * x**3")->reduce;

Other types

The pg/macros directory contains a number of extensions to MathObjects, including files that define specialized MathObject types. The ones that begin with parser typically define a new object class. For example, parserParametricLine.pl defines a constructor ParametricLine() for creating a special object that checks if a student's answer is a given parametric line or not, even if it is parameterized differently. These files usually contain documentation within them; see the POD documentation for versions that you can read on line.


How to invoke a MathObject's method

Use the standard Perl method call syntax:

   $obj->method;
   $obj->method($arg1,$arg2);

For example:

   ANS($a->cmp);

This compares the student's answer with $a. If $a is Real then this comparison will be "fuzzy" which means that equality is checked to a tolerance defined by the current Context.

Examples of Using MathObjects

MathObjects are useful (and powerful) because they "know" information about themselves: how to add themselves to other MathObjects, take derivatives, substitute values, and to compare themselves with student answers, and even to alert students if their entries contain syntactical errors as opposed to substantiative ones.

   $f = Compute("sin(x^2+6)");
   $a = Compute("sqrt(pi/6)");
   $z = Compute("1 + 5i");
   $v = Compute("<3,-2,5>");
   $M = Compute("[[1,0,1],[1,1,0],[0,1,1]]");

With the definitions given above all of these operations can be performed:

   $dfdx = $f->D('x');
   $dfdx_at4 = $dfdx->eval(x=>4);
   $g = $f + $dfdx;
   $z1 = 5*$z;
   $z2 = $a + $z;
   $x = $M * $v;

The results are that $dfdx is the derivative of $f, $dfdx_at4 is f'(4), and so forth.

Use the online calculators at PGLabs to experiment with MathObjects in order to quickly learn the syntax.

Methods shared by all MathObjects

  • cmp: Returns an answer checker for the Value. All of the answer checkers are defined in the file lib/Value/AnswerChecker.pm.
  • perl: Returns a string which represents the object as Perl source code.
  • perlFunction: Returns a Perl subroutine which represents the object. (Only available for Formula objects.)
  • value: Returns the value of the object.
  • TeX: Returns a string which represents the object as a TeX math expression.
  • string: Returns a string similar to that used to create the object. May include extra parentheses.
  • stringify: Produces the output of the object when inside quotes. Depending on context this is either a TeX string or a regular string. (This is called automatically by Perl when when an object is used in string context, and should not need to be called explicitly by the problem author.)
  • getFlag("flag name"): Returns the value of one of the object's internal flags. For example: $a->getFlag("tolerance"); (see ContextFlags for a partial list )

Additional methods for Formulas

Each Formula has a parsed version of its defining string attached. This is created by the parser whose purpose is to parse a string representing a formula and turn it into a parse tree.

Additional Formula methods include:

  • eval: $f_at32 = $f->eval(x=>32) evaluates the function $f at x=32. The result is no longer a formula (the parse tree is lost) but has the type of f(32) i.e. the type of the range of $f. If $a = random(2,5,1);, then $f_at_a = $f->eval(x=>"$a"); will evaluate as expected.
  • reduce: $f = $f->reduce does some simplification of the function string --e.g. replace 1x^2 by x^2. The reduction rules are defined in the Context() and some of them are listed at List_of_parser_reduction_rules_for_MathObject_Formulas. (This is advanced information and can be skipped on the first reading.)
  • substitute: $f = $f->substitute(x=>'y') replaces all occurences of the variable x by the variable y. (One will also need to add the variable y as a legal variable to the context.) The result is a new formula. Using substitute instead of eval preserves the parse string enabling more insightful correct answer hints. (See FormattingCorrectAnswers)
  • D: $fp = $f->D('x') calculates the (partial) derivative of f with respect to x; however this will not be simplified.$fp = $f->D('x')->reduce will perform easy simplifications, but will not completely simplify the formula.

The parser which creates the parse tree Formula is defined in the file pg/lib/Parser.pm and the files in the pg/lib/Parser directory. Even though the subdirectory names under pg/lib/Parser are similar to those under pg/lib/Value they refer to different although related concepts. Under pg/lib/Parser the files refer to tokens in a string that is to be parsed, while the files under pg/lib/Value refer to MathObjects.


List of Basic Contexts

A Context is a table of values that provides defaults for the Parser and for MathObjects created while the Context is in force. As a quick example: in Numeric context the answer [math](4,5)[/math] is interpreted as a point in the two dimensional plane while in Interval context it is interpreted as the real values [math]x[/math] satisfying [math]4 \lt x \lt 5[/math].

  • Define context using: Context("Numeric");
  • To obtain the current context: $context = Context();
  • Context names: defined in pg/lib/Parser/Context/Default.pm
    • Numeric: no Matrix, Complex or Vector (or Interval) type is allowed.
    • Complex: no Matrix or Vector type is allowed. Can't use "<" to compare complex numbers.
    • Point: Nearly the same as the Vector Context below, but the angle bracket notation is not allowed and vector operations on points are not defined. This is useful if you wish to force students to perform the vector calculations before entering their answer.
    • Vector: i, j, and k are defined as unit Vectors, no Complex numbers are allowed.
    • Vector2D: i and j are defined as unit Vectors, no Complex numbers are allowed.
    • Matrix: square brackets define Matrix instead of Point or Interval
    • Interval: similar to Numeric context, but (,) and [,] create Real Intervals rather than Lists. {,} creates finite sets of Reals.
    • Full: For internal use. This context is used to seed the others.
      • pi is defined
      • i is square root of minus one, but j and k are unit Vectors
      • Matrix, Vector and Complex are all defined.
      • x is a variable

When first using MathObjects it's easiest to use the standard "Numeric" context, however as you begin to search for better ways to ask questions and to evaluate student responses you will find that customizing the context is a powerful way to proceed. There is more on this subject in the following documents.

See also