I coded a question to that required the students to input a matrix and I used
answer_matrix(4,4,5) . After looking at recent problems, it would be easier for the students to enter the matrix as a matrix, [[1,2,3,4],....[1,2,3,4]]. I'd like to change the problem to accept the matrix input but it appears I need to change my original array to a matrix object. I don't see how to do this. Previously, my answer checking was element by element, e.g.,
foreach $m (1..4) {
foreach $n (1..4) {
$e2[$m][$n] = 0;
if ($m == $n){
$e2[$m][$n] =1;
if ($m == $k3) {$e2[$m][$n] =$b1};
};
ANS(num_cmp($e2[$m][$n]));
}
}
How do I change the following code
DOCUMENT() ;
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"AnswerFormatHelp.pl",
"parserFunction.pl",
"answerHints.pl",
"PGmatrixmacros.pl",
"PGcourse.pl",
);
############
TEXT(beginproblem());
Context('Matrix');
foreach $i (1..4) {
foreach $j (1..4) {
# original forced only non-zero numbers
# I think they are OK
# $a[$i][$j] = non_zero_random(-10,10,1);
# $b[$i][$j] = non_zero_random(-10,10,1);
$a[$i][$j] = random(-10,10,1);
$b[$i][$j] = random(-10,10,1);
}
}
# part (a)
$k1 = random(1,4,1);
do {$k2 = random(1,4,1)} until ($k2 != $k1);
# part (b)
$k3 = random(1,4,1);
$b1 = non_zero_random(-6,6,1);
# part (c)
$k4 = random(1,4,1);
do {$k5 = random(1,4,1)} until ($k5 != $k4);
$b2 = non_zero_random(-6,6,1);
foreach $m (1..4) {
foreach $n (1..4) {
$e2[$m][$n] = 0;
if ($m == $n){
$e2[$m][$n] =1;
if ($m == $k3) {$e2[$m][$n] =$b1};
};
}
}
$re2 = Compute($e2);
$showPartialCorrectAnswers = 1 ;
BEGIN_TEXT
This problem is related to Problems 5.20 in the text.
$PAR
Consider the following matrix:
$BR
\{ mbox( display_matrix([[$a[1][1], $a[1][2], $a[1][3], $a[1][4]],
[$a[2][1], $a[2][2], $a[2][3], $a[2][4]],
[$a[3][1], $a[3][2], $a[3][3], $a[3][4]],
[$a[4][1], $a[4][2], $a[4][3], $a[4][4]]]) ) \}
$PAR
Write the Elementary Row Operation matrix that:
$PAR
(b) Multiplies row $k3 by $b1 $BR \{ ans_box(4,30)\}
END_TEXT
#answer Part(b)
# first generate identity matrix
# multiply row by b1
ANS($re2->cmp());
ENDDOCUMENT() ;
Hi Joel,
The Subject Area Templates page on the wiki
http://webwork.maa.org/wiki/Category:Subject_Area_Templates#Linear_Algebra
has some matrix examples. Below is an example that uses PGML.
In the code below, I would like to point out that for some reason $answer->ans_box() did not work for me using ww_version 2.8 and pg_version 2.8.1, but just plain ans_box() did. Perhaps $answer->ans_box() works with more recent versions of webwork. (We're upgrading webwork next month -- I'm so excited!)
Best regards,
Paul Pearson
########################
DOCUMENT();
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGML.pl",
"PGcourse.pl",
);
TEXT(beginproblem());
Context('Matrix');
$answer = Matrix([[1,2,3],[4,5,6]]);
BEGIN_PGML
Enter the matrix [`` [$answer] ``] in the form [$answer->string].
[@ ANS($answer->cmp); ans_box(3,20) @]*
END_PGML
ENDDOCUMENT();
Thanks - but the examples look like what I've seen previously. In an array I can set each element of the array to a specified value, $i=2;$j=3;
$b[$i][$j] = 5;
How do I set only the (2,3) element of a matrix to 5? All the examples I see always set the entire matrix.
Hi Joel,
You have defined arrays of Perl scalars, and you just need to put the Perl scalars from those arrays into MathObject matrices. For instance, a shearing matrix could be defined as follows.
$k = random(1,5,1); # $k is a Perl scalar
$M = Matrix([
[1,$k],
[0,1]
]); # $M is a MathObject matrix.
Or a dilation matrix could be defined as follows.
@a = ();
$a[1][1] = random(2,10,1); $a[1][2] = 0;
$a[2][1] = 0; $a[2][2] = $a[1][1];
# @a is a Perl array with two indices whose entries are Perl scalars
$A = Matrix([
[ $a[1][1], $a[1][2] ],
[ $a[2][1], $a[2][2] ]
]); # $A is a MathObject matrix
Below is a revised version of the code you posted. In general, you should create the matrix entries as Perl scalars (or an array of Perl scalars) and then put the Perl scalars into a MathObject matrix. MathObject matrices were originally not intended to be mutable, so creating a MathObject matrix and then changing its entries is not a good idea.
Best regards,
Paul Pearson
#######################################
DOCUMENT() ;
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGcourse.pl",
);
$showPartialCorrectAnswers = 1 ;
############
TEXT(beginproblem());
Context('Matrix');
$A = Matrix([
[non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1)],
[non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1)],
[non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1)],
[non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1),non_zero_random(-10,10,1)]
]);
##################################
# part (a)
$k1 = random(1,4,1);
do {$k2 = random(1,4,1)} until ($k2 != $k1);
##################################
# part (b)
$k3 = random(1,4,1);
$b1 = non_zero_random(-6,6,1);
foreach $m (1..4) {
foreach $n (1..4) {
$e2[$m][$n] = 0;
if ($m == $n){
$e2[$m][$n] =1;
if ($m == $k3) {$e2[$m][$n] =$b1};
};
}
}
$answer2 = Matrix([
[ $e2[1][1], $e2[1][2], $e2[1][3], $e2[1][4] ],
[ $e2[2][1], $e2[2][2], $e2[2][3], $e2[2][4] ],
[ $e2[3][1], $e2[3][2], $e2[3][3], $e2[3][4] ],
[ $e2[4][1], $e2[4][2], $e2[4][3], $e2[4][4] ]
]);
##################################
# part (c)
$k4 = random(1,4,1);
do {$k5 = random(1,4,1)} until ($k5 != $k4);
$b2 = non_zero_random(-6,6,1);
Context()->texStrings;
BEGIN_TEXT
Suppose
\[ A = $A \]
Write the elementary row operation matrix that
$PAR
(b) multiplies row $k3 of \( A \) by $b1 $BR \{ ANS($answer2->cmp()); ans_box(5,30) \}
END_TEXT
Context()->normalStrings;
ENDDOCUMENT();
Thanks - I think I understand that I should not try to change the value of a MathObject. I thought I had done so but maybe just used them in computations
I had tried to set the values of a "new Matrix" element by element but them it was not recognized as a MathObject. Oh well...
Thanks again.
I believe you are correct. There is currently not a method for modifying an entry in a MathObject Matrix. It would be nice if there was something like:
$A->assign(1,1,5);
to assign the value 5 to the 1,1 entry of the MathObject matrix $A (if memory serves, this existed for the old-style WW matrix objects).
You can convert an array of perl scalars to a MathObjects matrix. You just need to modify two things in your original code:
- Perl arrays are indexed starting at 0, so instead of having your for loops run from 1 to 4, have them run from 0 to 3 (and change the values of your k variables accordingly)
- Replace the line:
$re2 = Compute($e2);
with
$re2 = Matrix(@e2);
This forces it to be cast as a Matrix object, and the @ symbol passes the array, whereas the dollar sign would first convert your array to a scalar.
Also note that if you are using MathObject matrices, they have built-in methods to typeset the matrix. Consider the following code snippet:
Context('Matrix');foreach $i (0..3) {foreach $j (0..3) {$a[$i][$j] = random(-10,10,1);}}$ra = Matrix(@a);Context()->texStrings;BEGIN_TEXTConsider the following matrix:\[ $ra \]END_TEXTContext()->normalStrings;
This will display your matrix without having to enter anything entry-by-entry.
Danny
Thanks - this is VERY helpful - the $ra = Matrix(@a);
makes it easy to use the matrix format and I"M able to change a bunch of previous problems, coded with old Latex formatting to make the matrices much more readable to the students. I note that most of my faculty prefer the students to input the elements of the matrices using one block per element instead of using the matrix form. e.g., A = [[1,2,3],[4,5,6]]
But my life is easier
This is also easily done with MathObjects. If $ra is a matrix object, try the following:
BEGIN_TEXT
The matrix \(A=\) \{$ra->ans_array\}
END_TEXT
ANS($ra->cmp());
This will give you a matrix of answer boxes corresponding to $ra.
Another good suggestion - it looks good, but in the elementary problems that I"m writing, that counts the entire matrix answer wrong instead of counting individual elements in the matrix wrong. For the beginners, I'll stick with the answer blocks that give the students more feedback. I'll use the more advanced form for later in the tutorial.
Thanks