WeBWorK Problems

Matrix Custom Answer Checking

Matrix Custom Answer Checking

by John Travis -
Number of replies: 3
I am trying to find a way to check a students entered matrix for a homogeneous system Ax=0 vs the "correct" one.  Since of course there are two obvious choices for each row (take variables all left side or all right side) checking against multiple options is difficult.  I was attempting to demand that the rows not be swapped and to check the LU decomposition of the programmed answer to the LU of the student's answer.  However, the following code just returns the (1,1) position of the student's answer instead of the whole matrix.   (Below I was just attempting to look at the L part of the decomposition.)

$LA = $A->L;

BEGIN_TEXT

\{$A->ans_array\}

END_TEXT
Context()->normalStrings;

ANS( $LA->cmp( checker=>sub {
  my ( $correct, $student, $ansHash ) = @_;
  $LS = $student->L;
  return $correct == $LS;
} ) );

Any help appreciated.

JT
In reply to John Travis

Re: Matrix Custom Answer Checking

by Davide Cervone -
One issue is that you have used $A->ans_array but have used the answer hecker for $LA instead of $A. The and_array sets up the Matrix to know how to collect all the elements of the array, but $LA hasn't had that setup. So it only is tied to the single answer blank that is the upper left-hand entry.

See if switching $A->ans_array to $LA->ans_array helps.

Davide
In reply to Davide Cervone

Re: Matrix Custom Answer Checking

by John Travis -
Thanks for the suggestion but that doesn't work.  If it helps, here is the entire problem:

##DESCRIPTION
##  Application using a homogeneous linear system
##  Balancing Chemical Equations 
##ENDDESCRIPTION

##KEYWORDS('Chemistry', 'linear system', 'homogeneous')

## DBsubject('Linear Algebra')
## DBchapter('')
## DBsection('')
## Date('2/7/2013')
## Author('John Travis')
## Institution('Mississippi College')
## TitleText1('Linear Algebra')
## EditionText1('')
## AuthorText1('Lay')
## Section1('')
## Problem1('')

########################################################################

DOCUMENT();      

loadMacros(
   "PGstandard.pl",     # Standard macros for PG language
   "MathObjects.pl",
   "PGmatrixmacros.pl"
);

# Print problem number and point value (weight) for the problem
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1;

##############################################################
#
#  Setup a collection of equations to randomly pick from
#

$chem[0] ="Sn O_2 + H_2 \rightarrow Sn + H_2 O";
$chemxs[0] ="x_1Sn O_2 + x_2H_2 \rightarrow x_3Sn + x_4H_2 O";
$elements[0] = 'Tin, Oxygen, Hydrogen';

$chem[1] ="C_2H_6 + O_2 \rightarrow H_2 O + CO_2";
$elements[1] = 'Carbon, Hydrogen, Oxygen';

$chem[2] ="NH_3 + O_2 \rightarrow NO + HO_2";
$elements[2] = 'Nitrogen, Hydrogen, Oxygen';

$r = random(1,3,1);   #  pick one of the equations to balance

$r = 0;  #  Until we get everything else working, just use the first one.

#  we look at each element in the prescribed order 
#  and move all terms to the left to get each row

@ar1 = (1, 0, -1, 0, 0);
@ar2 = (2, 0, 0, -1, 0);
@ar3 = (0, 2, 0, -2, 0);

#  Then, take the rows and create the (homogeneous) augmented matrix.
#  Later, this can all be created dynamically 

Context ("Matrix");
$A = Matrix( [1, 0, -1, 0, 0],
                   [2, 0, 0, -1, 0],
                   [0, 2, 0, -2, 0] );

#  Finally, create the Lower triangular part of the LU decomposition for 
#  checking purposes.  If this is the term that always has 1's on the
#  diagonal, then checking this matrix vs the students L should be sufficient.

$LA = $A->L;

#   For the second part of this problem, use the general solution from the
#   system above to get a particular solution.  Requires setting x_4 = given
#   and solving the resulting equations for the remaining
#   variables.  For now, all of the other variables are set = 1.

$given_quantity = random(10,30,5);
$soln = $given_quantity*Vector( 1,1,1,1);  
#  this needs to be a soln determined by WW

##############################################################

Context()->texStrings;
BEGIN_TEXT

In this problem, use homogeneous linear equations to balance the chemical equation \($chem[0]\).
$PAR
To balance the equation, you must determine the number of moles \(x_k\) of each chemical species to use.
$BCENTER
\($chemxs[0]\)
$ECENTER

$BR
The augmented matrix equation of the form \( Ax = 0 \) with \(x =[x_1,x_2,x_3,x_4]^T\) which describes this problem:  
$BR

$BCENTER
\{$A->ans_array\}
$BITALIC
$BR
Express your answer for the rows above in the order $elements[0]
$EITALIC
$ECENTER

$PAR
Suppose you are given that \(x_4 = $given_quantity\) moles.  Determine a particular solution to this problem and express the answer as a vector.  (Round to the nearest digit.)
$BCENTER
ANS not coded yet...\(<x_1,x_2,x_3,x_4> = \)\{ans_rule(40)\}
$ECENTER

END_TEXT
Context()->normalStrings;

##############################################################
#
#  Answers
#
#

# Check for the Matrix Equation Ax = 0

ANS($A->cmp);
 
# ANS( $LA->cmp( checker=>sub {
#  my ( $correct, $student, $ansHash ) = @_;
 # $LS = $student->L;
 # return $correct == $LS;
# } ) );


ANS( Compute("$soln")->cmp(tolerance => 1) );

ENDDOCUMENT();        
In reply to John Travis

Re: Matrix Custom Answer Checking

by Davide Cervone -
A couple of issues, here.

First, my understanding is that LR decomposition is only value for square matrices, which yours isn't. Perhaps you want to keep A separate from the augmented form of A and work with that?

If you want to have the students enter the augmented matrix, you will need to use $A->ans_array as you have done, but then you will need to use $A->cmp with a custom checker, not $LA->cmp. The custom checker can use $LA internally (and ignore $correct) if you want, or you could wait to compute $LA within the answer checker (from the correct answer). Whatever you prefer.

I think you will need to remove the last column of the correct and student answer. There is no really convenient way to do that, however. Here is one possibility for deleting the fifth column from a matrix $M.

    $Mt = $M->transpose;
    $MM = Matrix(
            $Mt->extract(1),
            $Mt->extract(2),
            $Mt->extract(3),
            $Mt->extract(4),
          )->transpose;
So you could use that to get the square matrix whose LR decomposition you would need to compute.

There are a couple of other minor issues as well: I would recommend using \rm in your chemical equations to get the right font for the chemicals:

    $chem[0] ="\rm Sn O_2 + H_2 \rightarrow Sn + H_2 O";
    $chemxs[0] ="x_1{\rm Sn O_2} + x_2{\rm H_2} \rightarrow x_3{\rm Sn} + x_4{\rm H_2 O}";
Also, creating $A dynamically from your row arrays is easy:
    $A = Matrix([@ar1],[@ar2],[@ar3]);

See if any of that helps.

Davide