Skip to content

fuzzy test for row equivalency#1427

Open
Alex-Jordan wants to merge 1 commit into
openwebwork:PG-2.21from
Alex-Jordan:isRowEquivalent
Open

fuzzy test for row equivalency#1427
Alex-Jordan wants to merge 1 commit into
openwebwork:PG-2.21from
Alex-Jordan:isRowEquivalent

Conversation

@Alex-Jordan

@Alex-Jordan Alex-Jordan commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

This adds an isREQ method for Matrix objects. Used like $A->isREQ($B).

This is a "fuzzy " check that avoids both machine rounding issues and student rounding issues (for example if they enter something like 0.3333 instead of 1/3). Instead of reducing each matrix to RREF (which could introduce extraneous pivot positions from machine rounding), this approach compares the two row spaces. If each row from one matrix is "close enough" to the other matrix's row space, then the algorithm effectively declares that row to be in the other matrix's row space. "Close enough" is based on normalizing nonzero rows to length 1, and then the usual fuzzy tolerances for comparing that normalized row and its projection onto the other matrix's row space.

For example, Matrix([ 3, 1 ], [ 1, 1 / 3 ]) and Matrix([ 1, 0.3333 ], [ 0, 0 ]) will be considered row equivalent.

But Matrix([ 3, 1 ], [ 1, 1 / 3 ]) and Matrix([ 1, 0.33 ], [ 0, 0 ]) will not be.

And of course Matrix([ 3, 1 ], [ 1, 1 / 3 ]) and Matrix([ 1, 0], [ 0, 1 ]) will not be.

For questions that ask a student to completely reduce $A, a checker could check $student->isRREF() && $student->isREQ($A).

@Alex-Jordan

Copy link
Copy Markdown
Contributor Author

I updated the top comment here, partly to fix typos, but also to explain a little more about what the comparison actually does.

In another thread, @somiaj and I were talking about actually implementing an RREF algorithm. We could do that too, I just couldn't think of a way to avoid extraneous pivot positions popping up from machine rounding. That situation would create "false negatives" where two matrices that should be considered row equivalent would not be. But here, the algorithm goes the other way. It may create "false positives" because of the fuzzy tolerances.

@drgrice1

drgrice1 commented Jun 8, 2026

Copy link
Copy Markdown
Member

I might be misunderstanding something, but I tested with the following problem:

DOCUMENT();

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

$A = Matrix([ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]);
$B = Matrix([ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ], [ 14, 16, 18 ] ]);

BEGIN_PGML
[``[$A]``] and [``[$B]``] are [$A->isREQ($B) ? 'row equivalent' : 'not row equivalent']
END_PGML

ENDDOCUMENT();

and I get the error Error evaluating variable $A->isREQ($B) ? 'row equivalent' : 'not row equivalent': Cannot compare row equivalency because matrices differ in the first dimension. It seems that these matrices should be comparable, and should be row equivalent. They have the same row space.

@Alex-Jordan

Copy link
Copy Markdown
Contributor Author

I could change it for that interpretation. But the implementation is based on A~B meaning that you could apply row operations to one to get the other. And applying row operations to a 3x3 matrix can't produce a 4x3 matrix. Even if they have the same row space.

@drgrice1

drgrice1 commented Jun 8, 2026

Copy link
Copy Markdown
Member

I see. Yeah, that is the standard definition of row equivalent matrices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants