Forum archive 2000-2006

Edgar Fisher - Plotting functions with unknown domain

Edgar Fisher - Plotting functions with unknown domain

by Arnold Pizer -
Number of replies: 0
inactiveTopicPlotting functions with unknown domain topic started 7/12/2005; 2:36:09 PM
last post 8/2/2005; 5:31:29 PM
userEdgar Fisher - Plotting functions with unknown domain  blueArrow
7/12/2005; 2:36:09 PM (reads: 1138, responses: 4)
I am trying to plot a function from student input for checking purposes. Currently the student answer is a shifted sqrt function, and so I need to know the domain to graph it. The plot function returns an error if I use values outside the domain. Is there a way to plot a function on its domain, without having to specify it? This is the standard, Maple, Mathematica and Derive ignore undefined values when plotting.

Edgar Fisher

<| Post or View Comments |>


userMichael Gage - Re: Plotting functions with unknown domain  blueArrow
7/23/2005; 12:49:11 PM (reads: 1358, responses: 0)
I have an untested suggestion for resolving this:

If you use the student's string to create a function with the Parser objects, and then install that parser object function in the graph, I believe that the Parser object is much smarter about checking for undefined values than the standard functions were.

This is something of a bleeding edge topic right at the moment so there is not much experience, much less documentation, about how best to do this. If you find something that works, please report back. There is some documentation on parser objects in /webwork2/doc/parser. There is documentation on the details of the graph objects at WWPlot.pm

<| Post or View Comments |>


userNandor Sieben - Re: Plotting functions with unknown domain  blueArrow
7/24/2005; 10:36:57 PM (reads: 1356, responses: 0)
The 'undef' value implemented for function comparison not long ago could somehow help to solve this problem. Nandor

<| Post or View Comments |>


userDavide P. Cervone - Re: Plotting functions with unknown domain  blueArrow
8/1/2005; 12:23:17 PM (reads: 1331, responses: 0)
It is possible to use the new Parser to handle this, as Mike suggests. It is a little subtle, however, so here are the main ideas:

The hardest part is to trap errors that occur during the function evaluation so that you can ignore them. This is not so easy to do in WW, since the problem is executed in a limited subset of perl, and that subset does not include the commands for trapping errors. There are some special cases, however, where WW will trap errors for you. The Parser provides one of these with the Parser::Evaluate() function. This takes a Formula object and a list of substitions (e.g., x=>5,y=>-2) and substitutes those values into the formula (just like the Formula's eval method), but traps errors so that they will not produce error messages or stop the code from running. Instead, if an error is detected, Parser::Evaluate returns an undefined value, and the error message is in the Formula's context's {error} object.

This is useful in this case, because the graphics plotting routine looks for undefined values and skips over them, so if we can get it to wrap Parser::Evaluate around the formula that it is plotting, we will be able to not worry about the domain. The problem is that plot_functions() uses AlgParser to evaluate the formula to be plotted, so we are restricted to using only the functions that AlgParser knows about (which doesn't include Parser::Evaluate).

Fortunately, we can bypass plot_functions and go to a slightly lower level of code and insert our own functions into the graph directly. This is done using a Fun object (short for Function). When a Fun object is created, it accepts a perl subroutine reference, not a string representing the function like plot_functions, so we can include calls to anything we want in that subroutine.

So here's the plan: parse the student's answer into a Parser Formula object, then create a Fun object whose subroutine calls Parser::Evaluate on the student's answer, thereby ignoring error messages. For example, suppose you have a variable $G that is the graphic object created via init_graph() earlier, and the student answer is in $student_ans. Then you can plot the student answer using

 

      $F = Formula($student_ans);
$f = new Fun(sub {Parser::Evaluate($F,x=>shift)},$G);

This assumes the variable in the student's formula is x, but you can change x=>shift to be whatever variable is appropriate for you.

If you want to set the color or weight for the plot, you can use something like

 

    $f->color("red");
$f->weight(2);

to do that. If you think there will be gaps in the student's function, you may want to plot more points than the default 20 in order to make the endpoints of the gaps more accurate. You can use

 

   $f->steps(100);

for example, but the number of points might need to be more (or less) depending on the size of the final graph that you are producing.

Note that if the student has made a syntax error, the $F = Formula($student_ans); line may cause an error. You probably want to trap this error and report it in the answer message area rather than get the pink warning screen or some other error condition. The parser has a function to help you with that as well: Parser::Formula(). This parses the string passed to it and returns an undefined value if there was an error, with the error message stored in the context's {error} object. You can then call Value->cmp_error() to clean up and format that error (e.g., hilight the location of the error) and insert it into the answer-hash's message field. For example, if the answer hash is $ans,

 

    $F = Parser::Formula($student_ans);
if (defined($F)) {
$f = new Fun(sub {Parser::Evaluate($F,x=>shift)},$G);
$f->color("red"); $f->weight(2); $f->steps(100);
} else {
Value->cmp_error($ans);
}

would parse the student answer and either plot the student's function (no matter what it's domain) or report an error if the student's answer didn't parse.

Note that the plot might not show anything if the student's function is not defined on the domain of the graph, or if the values of the function are outside the vertical range of the graph.

Anyway, hope that does what you want.

Davide

<| Post or View Comments |>


userNandor Sieben - Re: Plotting functions with unknown domain  blueArrow
8/2/2005; 5:31:29 PM (reads: 1344, responses: 0)
It works thank you. Nandor

<| Post or View Comments |>