Can adaptive parameters be used to compare two Math Object Matrices up to a scalar multiple? My first attempt to code this did not work. I thought about it, and when comparing scalar functions using adaptive parameters, there might be division involved, which wouldn't carry over well to comparing two matrices.
Based on my understanding of adaptive parameters (without actually looking at the code), they do use division to determine if functions are scalar multiples of one another.
It should be relatively simple to check if a matrix is a scalar multiple of the correct answer using a custom answer checker. I haven't written the code, but it should be a matter of finding a non-zero entry in the correct answer, dividing the same entry in the student's answer by this entry (call this n), then checking if n*correct_answer == student_answer. Of course you may also want to verify that the student answer is not the zero matrix.
Alternatively, if it is easy to convert a matrix object to a vector object (which I haven't looked into), you could use the $vec->isParallel($ans) function.
I don't know if I will have time to write any of this code, but this should be a good place to start.
Danny
That sounds like a good plan. I'm teaching linear algebra and I decided to have all vectors entered as matrices are entered. (Maybe this was a bad choice, but it's been made.) So for now what I wanted was specific to column vectors that are technically matrix objects.
After I posted my question I realized that I could just create an n by n matrix whose null space was the span of "the" correct answer, check the student's answer is nonzero, and then check that my matrix annihilated their answer. My solution can't exactly be upgraded to check multiples of m by n matrices though.
I basically wish I understood Perl better - especially arrays of arrays and references. I feel like $matrix->value should give an array of arrays, but instead it seems to give an array of references to arrays. From this I'd like to extract each entry, create a vector object (as you suggest) and use isParallel, but I haven't had success understanding what to do with the array of references.
Add to my wishlist: If Vector() is fed a matrix object, it creates a flattened elongated vector.
After I posted my question I realized that I could just create an n by n matrix whose null space was the span of "the" correct answer, check the student's answer is nonzero, and then check that my matrix annihilated their answer. My solution can't exactly be upgraded to check multiples of m by n matrices though.
I basically wish I understood Perl better - especially arrays of arrays and references. I feel like $matrix->value should give an array of arrays, but instead it seems to give an array of references to arrays. From this I'd like to extract each entry, create a vector object (as you suggest) and use isParallel, but I haven't had success understanding what to do with the array of references.
Add to my wishlist: If Vector() is fed a matrix object, it creates a flattened elongated vector.
If all you need is vectors written as column matrices, these already exist in WeBWorK.
The following code snippet should do what you need:
$vec = ColumnVector([$a,$b,$c]);
BEGIN_TEXT
Find the vector ... \{$vec->ans_array\}
END_TEXT
ANS($vec->cmp(parallel=>1));
Danny
Well that should help me a bit.
If this is a basic Math Object, should it be mentioned in the wiki? Specifically, at http://webwork.maa.org/wiki/Introduction_to_MathObjects?
If this is a basic Math Object, should it be mentioned in the wiki? Specifically, at http://webwork.maa.org/wiki/Introduction_to_MathObjects?
I feel like $matrix->value should give an array of arrays, but instead it seems to give an array of references to arrays.
The reason for this is that Perl flattens arrays or arrays into one big array, so that ((1,2),(3,4))
becomes (1,2,3,4)
. So the usual way to represent a matrix is as an array of references of arrays.
You can dereference an array using the @
operator, so
$M = Matrix([1,2],[3,4]); @r = @{($M->value)[0]}; # produces (1,2), the first row
Or you could use
$r = Vector(($M->value)[0]);to get the first row as a Vector object.
Of course, there is an easier way to do that, using
$r = Vector($M->row(1));Note that
$M->row(1)
is a Matrix with one row.
There is also a $M->column(j)
method to obtain a column (as a matrix of one-element rows), and $M->extract(i,j)
method to obtain the (i,j)-th entry of the matrix.
These may make your algorithm easier to handle.