WeBWorK Main Forum

making matrics from arrays

making matrics from arrays

by Joel Trussell -
Number of replies: 8
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() ;

In reply to Joel Trussell

Re: making matrics from arrays

by Paul Pearson -
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();
In reply to Paul Pearson

Re: making matrics from arrays

by Joel Trussell -
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. 
In reply to Joel Trussell

Re: making matrics from arrays

by Paul Pearson -
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(); 
In reply to Paul Pearson

Re: making matrics from arrays

by Joel Trussell -
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. 
In reply to Joel Trussell

Re: making matrics from arrays

by Danny Glin -
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:
  1. 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)
  2. 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_TEXT
Consider the following matrix: 
\[ $ra \]
END_TEXT
Context()->normalStrings;

This will display your matrix without having to enter anything entry-by-entry.

Danny
In reply to Danny Glin

Re: making matrics from arrays

by Joel Trussell -
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
In reply to Joel Trussell

Re: making matrics from arrays

by Danny Glin -
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.
In reply to Danny Glin

Re: making matrics from arrays

by Joel Trussell -
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