WeBWorK Problems

Absolute Value in Logarithmic Functions Student Answers

Absolute Value in Logarithmic Functions Student Answers

by Brittni Lorton -
Number of replies: 6
I am working on an integration problem where the answer contains the natural log of an absolute value argument.

The code below produces the problem and it marks the student correct when they include the absolute value and incorrect when they don't include the absolute value (which is what I want).

Is there a way I can include some type of message to pop up for the student when they have the answer correct but just forgot the absolute value?

Thanks in advance.

*Brittni

DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"AnswerFormatHelp.pl",
"PGML.pl",
"PGcourse.pl",
"parserFormulaUpToConstant.pl",
);
Context()->variables->add(a => "Real");

TEXT(beginproblem());
$showPartialCorrectAnswers = 1;

###########################
# Setup
$a = random(1,6,1);
$f=Formula("1/sqrt(x^2-$a^2)")->reduce();
$fa=Formula("1/sqrt(x^2-a^2)")->reduce();
$ans1=FormulaUpToConstant("ln(abs(x+sqrt(x^2-$a^2)))+C")->with(limits=>[-45,-38])->reduce();
$ans2=FormulaUpToConstant("ln(abs(x+sqrt(x^2-a^2)))+C")->reduce();


###########################
# Main text

BEGIN_PGML
Integrate the following using the method of trigonometric substitution.
Express the final answer in terms of the original variable.

a. [``\int [$f] dx=``][__________________]{$ans1 }[@ AnswerFormatHelp("formulas") @]*

b. [``\int [$fa] dx=``][__________________]{$ans2 } (for [`a`] being any real number) [@ AnswerFormatHelp("formulas") @]*

Use a capital C for any needed constant in your answer.

END_PGML

ENDDOCUMENT();

In reply to Brittni Lorton

Re: Absolute Value in Logarithmic Functions Student Answers

by Danny Glin -
This is an interesting problem because the domain of the answer is a union of two disjoint intervals.

WeBWorK already offers a message of "The domain of your function does not match that of the correct answer" in most cases where a student omits the absolute value. This message is given when the students answer and the correct answer agree at some test points, and one or the other of the two is undefined at the remaining test points. The reason you don't see this in your example is because you are only evaluating the function at values where the argument of the absolute value is negative.

In the code you provided, if a student omits the absolute value, then their function will be undefined for every x-value that WeBWorK tries (in the interval [-45,-38]), so it will be marked wrong. You don't get the more detailed message because there are no points where the student answer agrees with the correct answer. In most cases the fix would be to expand the interval to contain x-values where the argument of the absolute value is positive, but this is problematic here because there is an interval of x-values in between for which the function is undefined.

I think the solution here is to use "test_at" to add some specified points at which to test the function. Try something like
$ans1=FormulaUpToConstant("ln(abs(x+sqrt(x^2-$a^2)))+C")->with(limits=>[-45,-38],test_at=>[[$a+2],[$a+3]])->reduce();

This should pick some random x-values in the interval [-45,-38] to test, and also test the values $a+2 and $a+3 (as a side note, your limits of the function can depend on variables, so you could use limits=>[-$a-7,-$a-2]). For more info see http://webwork.maa.org/wiki/FormulaTestPoints.

If you want to customize the message more, take a look at AnswerHints. Keep in mind that if you go that route you will still need to worry about the domain stuff described above. If you put an answer hint on the formula without the absolute value using only limits=>[-45,-38], it will be displayed for any formula that is undefined on that interval, because on that domain WeBWorK wouldn't be able to distinguish between them.

I hope that made sense...
In reply to Brittni Lorton

Re: Absolute Value in Logarithmic Functions Student Answers

by Davide Cervone -
Danny gives an excellent answer describing the issues with the limits. For absolute-value problems, you always want to force test points in both the positive and negative ranges, if you are concerned that the absolute values be required. Even if the domain were a single interval, you would still want to force test points to make sure you get both sides of the absolute value, otherwise, in some cases you can still get test points on only one side. For example, even for
   $f = Formula("|x|")->with(limits->[-5,5]);
it is possible that all the randomly selected test points will be positive. So it is best to use test_at in this case, as well.

Note that with your limits, even though you force all negative values of x, that means you can still accept incorrect answers as correct. For example, ln(-x-sqrt(x^2-4))+C would be marked correct in the case where $a is 2. So you really do need to use the test_at approach to make sure you have the needed values on both sides.

But there is one caveat: since you have added a as a variable, there are two variables in the context, and so when you give the test points, you need to have a value for both of these. This is true even in formulas that don't include both variables, since the student answer can use both (because both are part of the context). They are listed in alphabetical order, so the first coordinate is for a and x is second. So you want do do something like

$ans1 = FormulaUpToConstant("ln(abs(x+sqrt(x^2-$a^2)))+C")->with(limits => [-45,-38], test_at => [[$a,$a+2],[$a,$a+3]])->reduce();
You will also have to do the same sort of thing for the formula involving a rather than the value of a. I think that limits => [-45, -36] applies to both the x and the a, so it is possible that you would get points where a > x, and the root will be undefined. WeBWorK will try again and look for additional points, but it is possible that this will happen enough times that WeBWorK will give up, so you might want to give the limits for a when you create it, so that they are always less than x, via something like
Context()->variables->set(a => {limits => [-2, 2]});

Finally, Danny has also suggested AnswerHints() as a way to provide a warning message when the student forgets the absolute values. In order to do that in PGML, one approach is to set $ans1 to the answer checker itself. For example:

$ans1 = $ans1->cmp()->withPostFilter(AnswerHints(
FormulaUpToConstant("ln(x+sqrt(x^2-$a^2))+C")->with(limits=>[6,10]) => "What happens if x is negative?"
));
Note that the answer hint will only run when the answer is incorrect (by default), and so you don't have to worry about matching the correct answer, here. But you do have to set the limits to values of x that are in the domain of the function.

Hope that helps.

In reply to Davide Cervone

Re: Absolute Value in Logarithmic Functions Student Answers

by Brittni Lorton -
Thank you both Danny and David - this is great information and has been helpful.

Great ideas about the test_at rather than just changing limits. I didn't realize that is exactly what I needed.

The fix I went with is
Context()->variables->set(a => {limits => [-2, 2]}); 

to have fixed limits for a. And then I chose to use

$ans1=FormulaUpToConstant("ln(abs(x+sqrt(x^2-$a^2)))+C")->with(limits => [[$a,-$a-7],[$a,-$a-2]], test_at => [[$a,$a+2],[$a,$a+3]])->reduce(); 
$ans1 = $ans1->cmp()->withPostFilter(AnswerHints( FormulaUpToConstant("ln(x+sqrt(x^2-$a^2))+C")->with(limits=>[6,10]) => "Are you missing an absolute value somewhere?" ));
$ans2=FormulaUpToConstant("ln(abs(x+sqrt(x^2-a^2)))+C")->with(limits => [[1,-6],[1,-2]], test_at => [[1,2],[1,6]])->reduce(); 
$ans2 = $ans2->cmp()->withPostFilter(AnswerHints( FormulaUpToConstant("ln(x+sqrt(x^2-a^2))+C")->with(limits=>[6,10]) => "Are you missing an absolute value somewhere?" )); 
to create the set limits and the AnswerHints.

It seems to be doing exactly what I was hoping for.

Thanks!

*Brittni
In reply to Brittni Lorton

Re: Absolute Value in Logarithmic Functions Student Answers

by Brittni Lorton -
I know it's been a while but I would like to revisit this problem. The fix I had above seemed to work fine but today I am noticing some more issues with it.

The issue I am seeing is that the second part of the problem (where the answer includes both x and a as variables) the answer written as ln|x+sqrt(x^2-a^2)|+C is accepted but the answer written as ln|x/a+sqrt(x^2/a^2-1)|+C is not accepted. But those two are the same functions up to a constant.

Any ideas and why that is?



As I have been staring at this problem I also feel like maybe I am misunderstanding the with(limits) portion of these mulitvariable functions. Here is an example I am thinking of:

If I have a problem where the two variables defined are 'x' and 'a' and I include something like:
$ans = Formula("x+a")->with(limits => [[1,3],[2,6]]);

Does it mean that the limits for a are [1, 3] and the limits for x are [2,6]
OR does it mean the limits for a are [1,2] and the limits for x are [3,6]?

I appreciate any insight on this.

Thanks,

Brittni
In reply to Brittni Lorton

Re: Absolute Value in Logarithmic Functions Student Answers

by Davide Cervone -
But those two are the same functions up to a constant.

These answers differ by ln|a|, but in the problem as you have coded it, this is not a constant, since a is a variable, not a constant. You are thinking of a as a constant, but you have added it to the context as a variable.

Try using

Context()->constants->add(a => sqrt(1/e));  # a value unlikely to be used by students
instead of
Context()->variables->add(a => "Real");
and see if that helps. You will need to change the test points, since a is no longer a variable, but since you haven't includes an updated copy of the problem code, I will leave that to you.
In reply to Brittni Lorton

Re: Absolute Value in Logarithmic Functions Student Answers

by Davide Cervone -
Forgot to answer the second half of the question.

Does it mean that the limits for a are [1, 3] and the limits for x are [2,6]
OR does it mean the limits for a are [1,2] and the limits for x are [3,6]?

It is the first of the two.

Note, however, that for a FormulaUpToConstant(), there is also a variable C that is added to the context automatically. Since the variables are handled in ASCII order, they are C, a, x, so in this case, you have set C to [1,3] and a to [2,6], and because you don't give a third set, x gets the first value in your list, [1,3].

For this reason, it is often best to set the limits in the context rather than in with() calls, as I indicated above:

Context()->variables->set(a => {limits => [1,3]});

This may also affect the coordinates of the test points, but I haven't checked (and it has been many years since I wrote that section of the code, so can't remember of the top of my head).