Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add elementary, permutation, and zero matrix constructors #1012

Merged
merged 3 commits into from
Apr 3, 2024

Conversation

Alex-Jordan
Copy link
Contributor

The Matrix class already has an identity matrix constructor. For example: Value:Matrix->I(4). Or if $A is already a 4x4 matrix, then $A->I will do the same.

This PR adds a few more constructors for special matrices, so you can just ask for them rather than have to build them element by element in a problem. I would like feedback on whether or not it is OK to put these directly into the Matrix class, instead of into some linear algebra macro file.

  • Elementary scalar matrix: Value:Matrix->E(4, [2], 3) makes a 4x4 matrix such that left multiplication with a 4xn matrix scales the 2nd row by 3.
  • Elementary row swap matrix: Value:Matrix->E(4, [2,3]) makes a 4x4 matrix such that left multiplication with a 4xn matrix swaps the 2nd and third rows.
  • Elementary row replacement matrix: Value:Matrix->E(4, [2,3], 5) makes a 4x4 matrix such that left multiplication with a 4xn matrix replaces the 2nd row with the 2nd row added to 5 times the 3rd row.
  • Permutation matrix: Value:Matrix->P(4, [1,2,3]) makes a 4x4 matrix corresponding to the cycle (123).
  • Permutation matrix: Value:Matrix->P(4, [1,2,3], [1,4], ...) makes a 4x4 matrix corresponding to the product of the given cycles.
  • Zero matrix: Value:Matrix->Zero(4, 5) makes a 4x5 matrix of all zeros.
  • Zero matrix: Value:Matrix->Zero(4) makes a 4x4 matrix of all zeros.

All of the constructors can be called as a method from an existing matrix like $A. However in most cases you still must supply all the arguments. The exception is with a zero matrix, where $A->Zero will give you a zero matrix with the same dimensions as $A.

@pstaabp
Copy link
Member

pstaabp commented Feb 13, 2024

I have some updates to Matrix objects as well. I started a discussion at #991 but no one weighed in. I think this is a good idea--there was some discussion about moving more into the MathObjects directly instead of using some of the macros.

@Alex-Jordan
Copy link
Contributor Author

I did not know about this macro: https://webwork.pcc.edu/webwork2/pod/macros/math/MatrixReduce.pl

It has some of the same functionality here that I'm adding to lib.

@pstaabp
Copy link
Member

pstaabp commented Feb 14, 2024

I did not know about this macro: https://webwork.pcc.edu/webwork2/pod/macros/math/MatrixReduce.pl

It has some of the same functionality here that I'm adding to lib.

I've got a few things started on this as well. Let's talk so we're not duplicating things.

lib/Value/Matrix.pm Outdated Show resolved Hide resolved
@Alex-Jordan
Copy link
Contributor Author

I opted for consistency with the macro that was already here for making an identity matrix. Should I change that one too?

Copy link
Member

@drgrice1 drgrice1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are good additions. I added a few code suggestions.

One problem with adding to this file (and a problem with MathObjects to begin with) is that there is no POD. As such we have to rely on adding documentation to the wiki (or elsewhere). A big project that is needed is to add (good) POD documentation to these files so that it is available in the POD that can be accessed from the PG problem editor.

lib/Value/Matrix.pm Outdated Show resolved Hide resolved
lib/Value/Matrix.pm Outdated Show resolved Hide resolved
lib/Value/Matrix.pm Outdated Show resolved Hide resolved
lib/Value/Matrix.pm Outdated Show resolved Hide resolved
lib/Value/Matrix.pm Outdated Show resolved Hide resolved
lib/Value/Matrix.pm Outdated Show resolved Hide resolved
@pstaabp
Copy link
Member

pstaabp commented Feb 24, 2024

I think these are good additions. I added a few code suggestions.

One problem with adding to this file (and a problem with MathObjects to begin with) is that there is no POD. As such we have to rely on adding documentation to the wiki (or elsewhere). A big project that is needed is to add (good) POD documentation to these files so that it is available in the POD that can be accessed from the PG problem editor.

I started doing this for this file when I added another method to this module. After we get this in, I can add another PR to do this. And clearly, we should do more with the other MathObjects.

@Alex-Jordan
Copy link
Contributor Author

Some of what you see might just be that I tried to keep the new methods consistent with the existing identity matrix method. But I'm going to go in now and make changes throughout.

@drgrice1
Copy link
Member

I see. I didn't look around elsewhere in the file.

@Alex-Jordan
Copy link
Contributor Author

I just made updates as suggested by @pstaabp and @drgrice1. I made one additional change that mostly removes the need for @row altogether except for the elementary matrix method. @drgrice1 had suggested this for the zero method, and that made me realize it could be done for the identity and permutation methods too using a conditional operator.

One question I have (because now is the time) is if this format for the elementary matrix syntax can be improved upon. One of the existing macro libraries can make these matrices too, but it uses different methods to produce a row-scale matrix, a row-swap matrix, and the other kind. I wanted something where they all fall under the same method name (E is what I went with.) But this makes the syntax not very intuitive. Like E(4, [2], 3), E(4, [2,3]), and E(4, [2,3], 5) in the PR opening post. If anyone can imagine having a more intuitive syntax for this, let's do that.

@drgrice1
Copy link
Member

Are you referring to the methods in the MatrixReduce.pl macro? That has methods to create elementary matrices, and uses a flat argument list. If you think that would be more intuitive, then you could switch to that with multiple methods. I leave that to you. I am not opposed to your current syntax though.

One thing I noticed is that some of these methods allow calling them with a Value::Matrix object. For example, to obtain an identity matrix of the same size as one you are working with you would use

$matrix = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
$I = $matrix->I;

However, the new E method does not. Should that be adapted to do so? Also, if the P method is used in this way, the arguments needed are rather counterintuitive to obtain a permutation matrix of the same size. You need to call it as in the following example.

$matrix1 = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
$matrix2 = $matrix1->P(undef, [2, 3]);

@Alex-Jordan
Copy link
Contributor Author

Now you can do all of these:

$A = Matrix([1,2,3],[4,5,6]);

$I = $A->I;
$I2 = Value::Matrix->I(3);

$E = $A->E([1],3);
$E2 = Value::Matrix->E(3,[1],3);

$P = $A->E([1,2]);
$P2 = Value::Matrix->P(3,[1,2,3]);

$Z = $A->Zero;
$Z2 = Value::Matrix->Zero(3);
$Z3 = Value::Matrix->Zero(3,4);

The zero matrix is the only one allowed to be nonsquare, so if generated from $A it will keep the dimensions of $A.

For the others, they must be square. Since these matrices (I, E, P) are most often used to multiply on the left, I made it so that if $A is mxn, these matrices (I, E, P) will be mxm. For example $I above is 2x2. This is a change in behavior for I, because previously it would not be allowed unless $A were square.

@Alex-Jordan
Copy link
Contributor Author

I have not touched POD, because I do not know what the greater POD scheme should be for files like this.

@drgrice1
Copy link
Member

Awesome. You read my mind on allowing E and P to be non-square. Changing that for I makes sense, and I don't see it being a problem that this is a change in behavior from before.

The POD can be left for later.

@Alex-Jordan Alex-Jordan mentioned this pull request Mar 6, 2024
@pstaabp
Copy link
Member

pstaabp commented Mar 20, 2024

Got around to testing again. I think the basic API for these functions is good. It would be nice to not have to do the Value::Matrix->E for example. Should we provide the shortcut E or Elem as well?

@Alex-Jordan
Copy link
Contributor Author

Note that you can do things like:

$I = Matrix(1)->I(2);

to avoid doing:

$I = Value::Matrix->I(2);

@pstaabp pstaabp merged commit d36e4e3 into openwebwork:develop Apr 3, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants