Difference between revisions of "GeneralSolutionODE1"

From WeBWorK_wiki
Jump to navigation Jump to search
(switch to PGML and remove answerFormatHelp.pl macro)
Line 15: Line 15:
   
 
<tr valign="top">
 
<tr valign="top">
<th> PG problem file </th>
+
<th style="width: 50%"> PG problem file </th>
 
<th> Explanation </th>
 
<th> Explanation </th>
 
</tr>
 
</tr>
Line 41: Line 41:
 
DOCUMENT();
 
DOCUMENT();
   
loadMacros(
 
  +
loadMacros('PGstandard.pl','MathObjects.pl','PGML.pl',
"PGstandard.pl",
 
  +
'parserAssignment.pl','PGcourse.pl');
"MathObjects.pl",
 
"PGML.pl",
 
"AnswerFormatHelp.pl",
 
"parserAssignment.pl",
 
"PGcourse.pl",
 
);
 
   
 
TEXT(beginproblem());
 
TEXT(beginproblem());
$showPartialCorrectAnswers = 1;
 
 
</pre>
 
</pre>
 
</td>
 
</td>
Line 69: Line 62:
 
<td style="background-color:#ffffdd;border:black 1px dashed;">
 
<td style="background-color:#ffffdd;border:black 1px dashed;">
 
<pre>
 
<pre>
Context("Numeric");
 
  +
'MathObjects.pl','PGML.pl',
  +
'parserAssignment.pl','PGcourse.pl');
  +
  +
TEXT(beginproblem());
  +
$showPartialCorrectAnswers = 1;
  +
  +
Context('Numeric');
 
Context()->variables->add(
 
Context()->variables->add(
'c1'=>"Real",'c2'=>"Real",'c3'=>"Real",y=>"Real",
+
c1=>'Real',c2=>'Real',c3=>'Real',y=>'Real',
 
);
 
);
 
Context()->variables->set(
 
Context()->variables->set(
'c1'=>{limits=>[2,4]},
+
c1=>{limits=>[2,4]},
'c2'=>{limits=>[2,4]},
+
c2=>{limits=>[2,4]},
'c3'=>{limits=>[2,4]}
+
c3=>{limits=>[2,4]}
 
);
 
);
 
Context()->flags->set(
 
Context()->flags->set(
Line 88: Line 87:
   
 
# char poly (r-1)(r^2 + $a)
 
# char poly (r-1)(r^2 + $a)
 
$diffeq = "y^{\,\prime\prime\prime} - y^{\,\prime\prime} + $a y^{\,\prime} - $a y = 0"; # tex
 
   
 
$answer = Compute("y = c1 e^x + c2 cos(sqrt($a) x) + c3 sin(sqrt($a) x)");
 
$answer = Compute("y = c1 e^x + c2 cos(sqrt($a) x) + c3 sin(sqrt($a) x)");
</pre>
 
</td>
 
<td style="background-color:#ffffcc;padding:7px;">
 
<p>
 
<b>Setup:</b>
 
Add the arbitrary constants <code>c1, c2, c3</code> to the context as variables so that we can
 
evaluate them later. Set the domain of function evaluation on these variables to something
 
sensible. Use <code>parser::Assignment->Allow;</code> to allow equation answers of the form
 
<code>y = ...</code>.
 
</p>
 
</td>
 
</tr>
 
   
<!-- Main text section -->
 
  +
$cmp = $answer->cmp( checker => sub {
 
<tr valign="top">
 
<td style="background-color:#ffdddd;border:black 1px dashed;">
 
<pre>
 
BEGIN_PGML
 
Find the general solution to [` [$diffeq] `].
 
In your answer, use [` c_1, c_2 `] and [` c_3 `] to
 
denote arbitrary constants and [` x `]
 
the independent variable. Your answer should
 
be an equation of the form [`y = \ldots`] and
 
you should enter
 
[` c_1 `] as [| c1 |]*,
 
[` c_2 `] as [| c2 |]*, and
 
[` c_3 `] as [| c3 |]*.
 
 
[_________________________________]
 
[@ AnswerFormatHelp("equations" @]*
 
END_PGML
 
</pre>
 
<td style="background-color:#ffcccc;padding:7px;">
 
<p>
 
<b>Main Text:</b>
 
Give students detailed instructions about the format
 
of the answer that is expected.
 
</p>
 
</td>
 
</tr>
 
 
<!-- Answer evaluation section -->
 
 
<tr valign="top">
 
<td style="background-color:#eeddff;border:black 1px dashed;">
 
<pre>
 
ANS( $answer->cmp( checker => sub {
 
   
 
my ( $correct, $student, $answerHash ) = @_;
 
my ( $correct, $student, $answerHash ) = @_;
Line 147: Line 98:
 
# Check for arbitrary constants
 
# Check for arbitrary constants
 
#
 
#
Value->Error("Is your answer the most general solution?")
+
Value->Error("Is your answer the most general solution?")
if (
+
if (
Formula($stu->D('c1'))==Formula(0) ||
+
Formula($stu->D('c1'))==Formula(0) ||
Formula($stu->D('c2'))==Formula(0) ||
+
Formula($stu->D('c2'))==Formula(0) ||
Formula($stu->D('c3'))==Formula(0)
+
Formula($stu->D('c3'))==Formula(0)
 
);
 
);
   
 
##################################
 
 
# Linear independence (Wronskian)
 
# Linear independence (Wronskian)
#
 
 
my $x = Real(1.43);
 
my $x = Real(1.43);
   
Line 172: Line 120:
 
my $a33 = $stu->D('x','x')->eval('c1'=>0,'c2'=>0,'c3'=>1,x=>$x,y=>0);
 
my $a33 = $stu->D('x','x')->eval('c1'=>0,'c2'=>0,'c3'=>1,x=>$x,y=>0);
   
# my $wronskian =
 
  +
Value->Error("Your functions are not linearly independent or your answer is not complete")
# $a11*($a22*$a33-$a32*$a23) -
+
if (($a11*($a22*$a33-$a32*$a23)+$a13*($a21*$a32-$a31*$a22)) == ($a12*($a21*$a33-$a31*$a23)));
# $a12*($a21*$a33-$a31*$a23) +
 
# $a13*($a21*$a32-$a31*$a22);
 
# Value->Error("Your functions are not linearly independent or your answer is not complete")
 
# if ($wronskian==Real(0));
 
   
Value->Error("Your functions are not linearly independent or your answer is not complete")
 
if (($a11*($a22*$a33-$a32*$a23)+$a13*($a21*$a32-$a31*$a22)) == ($a12*($a21*$a33-$a31*$a23)));
 
   
 
#################################
 
 
# Check that the student answer is a solution to the DE
 
# Check that the student answer is a solution to the DE
#
 
 
my $stu1 = Formula($stu->D('x'));
 
my $stu1 = Formula($stu->D('x'));
 
my $stu2 = Formula($stu->D('x','x'));
 
my $stu2 = Formula($stu->D('x','x'));
Line 187: Line 130:
 
return ($stu3 + $a * $stu1) == ($stu2 + $a * $stu);
 
return ($stu3 + $a * $stu1) == ($stu2 + $a * $stu);
   
# my $stuDE = Formula($stuxxx - $stuxx + $a*$stux - $a*$stu)
 
  +
});
# ->with(test_points=>[[1,1,2,0.1,0],[2,1,1,0,0],[1,2,-1,-0.1,0],[-2,1,1,0,1]]);
 
# return ($stuDE==Formula(0));
 
 
 
}));
 
 
COMMENT("MathObject version. Characteristic polynomial (r-1)(r^2 + a). Uses PGML.");
 
 
ENDDOCUMENT();
 
 
</pre>
 
</pre>
<td style="background-color:#eeccff;padding:7px;">
 
  +
</td>
  +
<td style="background-color:#ffffcc;padding:7px;">
 
<p>
 
<p>
<b>Answer Evaluation:</b>
+
<b>Setup:</b>
We use <code>my $stu = Formula($student->{tree}{rop});</code> to get the right side of the
+
Add the arbitrary constants <code>c1, c2, c3</code> to the context as variables so that we can
  +
evaluate them later. Set the domain of function evaluation on these variables to something
  +
sensible. Use <code>parser::Assignment->Allow;</code> to allow equation answers of the form
  +
<code>y = ...</code>.
  +
</p>
  +
<p>For the <code>checker</code>, we use <code>my $stu = Formula($student->{tree}{rop});</code> to get the right side of the
 
student answer (to get the left side, we could have used <code>lop</code> for the left operand).
 
student answer (to get the left side, we could have used <code>lop</code> for the left operand).
 
Use <code>Formula($stu->D('c1'))==Formula(0)</code> to check that the student actually has
 
Use <code>Formula($stu->D('c1'))==Formula(0)</code> to check that the student actually has
Line 219: Line 154:
 
in order to get a more reliable answer checker.
 
in order to get a more reliable answer checker.
 
</p>
 
</p>
  +
  +
 
</td>
 
</td>
 
</tr>
 
</tr>
  +
  +
<!-- Main text section -->
  +
  +
<tr valign="top">
  +
<td style="background-color:#ffdddd;border:black 1px dashed;">
  +
<pre>
  +
BEGIN_PGML
  +
Find the general solution to
  +
[` y^{\,\prime\prime\prime} - y^{\,\prime\prime} + [$a] y^{\,\prime} - [$a] y = 0 `].
  +
  +
In your answer, use [` c_1, c_2 `] and [` c_3 `] to denote arbitrary constants and [` x `]
  +
the independent variable. Your answer should be an equation of the form [`y = \ldots`] and
  +
you should enter [` c_1 `] as [| c1 |]*,
  +
[` c_2 `] as [| c2 |]*, and
  +
[` c_3 `] as [| c3 |]*.
  +
  +
[_________________________________]{$cmp}
  +
  +
[@ helpLink('equations') @]*
  +
END_PGML
  +
  +
</pre>
  +
<td style="background-color:#ffcccc;padding:7px;">
  +
<p>
  +
<b>Main Text:</b>
  +
Give students detailed instructions about the format
  +
of the answer that is expected.
  +
</p>
  +
</td>
  +
</tr>
  +
<!-- Solution section -->
  +
  +
<tr valign="top">
  +
<td style="background-color:#ddddff;border:black 1px dashed;">
  +
<pre>
  +
BEGIN_PGML_SOLUTION
  +
Solution explanation goes here.
  +
END_PGML_SOLUTION
  +
  +
ENDDOCUMENT();
  +
</pre>
  +
<td style="background-color:#ddddff;padding:7px;">
  +
<p>
  +
<b>Solution:</b>
  +
</p>
  +
</td>
  +
</tr>
  +
   
 
</table>
 
</table>

Revision as of 12:19, 4 April 2023

General Solutions to ODEs with Arbitrary Constants

Click to enlarge

This PG code shows how to write a custom answer checker for ODEs questions where the answer is an equation of the form y = c1 f1(x) + c2 f2(x) + c3 f3(x) for some arbitrary constants c1, c2, c3.


Templates by Subject Area

PG problem file Explanation

Problem tagging data

Problem tagging:

DOCUMENT();

loadMacros('PGstandard.pl','MathObjects.pl','PGML.pl',
  'parserAssignment.pl','PGcourse.pl');

TEXT(beginproblem());

Initialization: We load parserAssignment.pl to require student answers to be of the form y = .... Please see the POD documentation parserAssignment.pl.

'MathObjects.pl','PGML.pl',
  'parserAssignment.pl','PGcourse.pl');

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

Context('Numeric');
Context()->variables->add(
  c1=>'Real',c2=>'Real',c3=>'Real',y=>'Real',
);
Context()->variables->set(
  c1=>{limits=>[2,4]},
  c2=>{limits=>[2,4]},
  c3=>{limits=>[2,4]}
);
Context()->flags->set(
    formatStudentAnswer=>'parsed',
    reduceConstants=>0,
    reduceConstantFunctions=>0,
);
parser::Assignment->Allow;

$a  = list_random(2,3,5,6,7,8);

# char poly (r-1)(r^2 + $a)

$answer = Compute("y = c1 e^x + c2 cos(sqrt($a) x) + c3 sin(sqrt($a) x)");

$cmp = $answer->cmp( checker => sub {

    my ( $correct, $student, $answerHash ) = @_;
    my $stu   = Formula($student->{tree}{rop});

    #################################
    #  Check for arbitrary constants
    #
    Value->Error("Is your answer the most general solution?")
    if (
      Formula($stu->D('c1'))==Formula(0) ||
      Formula($stu->D('c2'))==Formula(0) ||
      Formula($stu->D('c3'))==Formula(0)
    );

    #  Linear independence (Wronskian)
    my $x = Real(1.43);

    my $a11 = $stu->eval('c1'=>1,'c2'=>0,'c3'=>0,x=>$x,y=>0);
    my $a12 = $stu->eval('c1'=>0,'c2'=>1,'c3'=>0,x=>$x,y=>0);
    my $a13 = $stu->eval('c1'=>0,'c2'=>0,'c3'=>1,x=>$x,y=>0);

    my $a21 = $stu->D('x')->eval('c1'=>1,'c2'=>0,'c3'=>0,x=>$x,y=>0);
    my $a22 = $stu->D('x')->eval('c1'=>0,'c2'=>1,'c3'=>0,x=>$x,y=>0);
    my $a23 = $stu->D('x')->eval('c1'=>0,'c2'=>0,'c3'=>1,x=>$x,y=>0);

    my $a31 = $stu->D('x','x')->eval('c1'=>1,'c2'=>0,'c3'=>0,x=>$x,y=>0);
    my $a32 = $stu->D('x','x')->eval('c1'=>0,'c2'=>1,'c3'=>0,x=>$x,y=>0);
    my $a33 = $stu->D('x','x')->eval('c1'=>0,'c2'=>0,'c3'=>1,x=>$x,y=>0);

    Value->Error("Your functions are not linearly independent or your answer is not complete")
      if (($a11*($a22*$a33-$a32*$a23)+$a13*($a21*$a32-$a31*$a22)) == ($a12*($a21*$a33-$a31*$a23)));


    #  Check that the student answer is a solution to the DE
    my $stu1 = Formula($stu->D('x'));
    my $stu2 = Formula($stu->D('x','x'));
    my $stu3 = Formula($stu->D('x','x','x'));
    return ($stu3 + $a * $stu1) == ($stu2 + $a * $stu);

});

Setup: Add the arbitrary constants c1, c2, c3 to the context as variables so that we can evaluate them later. Set the domain of function evaluation on these variables to something sensible. Use parser::Assignment->Allow; to allow equation answers of the form y = ....

For the checker, we use my $stu = Formula($student->{tree}{rop}); to get the right side of the student answer (to get the left side, we could have used lop for the left operand). Use Formula($stu->D('c1'))==Formula(0) to check that the student actually has c1 in their answer.

We substitute numerical values that the student is unlikely to choose for c1, c2, c3 and then apply the Wronskian test for independence. Normally, we would check to see if the Wronskian was zero, but zero level tolerance in WeBWorK is much more stringent than non-zero level tolerance. So, we rearrange the terms of the Wronskian == 0 equation so that there are nonzero terms on both sides of the equation, and as a result we get a more reliable answer checker.

Finally, we take several derivatives of the student answer and use them to check that the student answer actually satisfies the differential equation. Again, instead of checking (left side of ODE) == 0, we rearrange the terms of the differential equation to be of the form (some nonzero function) == (some other nonzero function) in order to get a more reliable answer checker.


BEGIN_PGML
Find the general solution to
[` y^{\,\prime\prime\prime} - y^{\,\prime\prime} + [$a] y^{\,\prime} - [$a] y = 0 `].

In your answer, use [` c_1, c_2 `] and [` c_3 `] to denote arbitrary constants and [` x `]
the independent variable.  Your answer should be an equation of the form [`y = \ldots`] and
you should enter [` c_1 `] as [| c1 |]*,
[` c_2 `] as [| c2 |]*, and
[` c_3 `] as [| c3 |]*.

[_________________________________]{$cmp}

[@ helpLink('equations') @]*
END_PGML

Main Text: Give students detailed instructions about the format of the answer that is expected.

BEGIN_PGML_SOLUTION
Solution explanation goes here.
END_PGML_SOLUTION

ENDDOCUMENT();

Solution:

Templates by Subject Area