You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working on PR #2973, I noticed that most arithmetics there did not perform any checks on the dimensions of the involved input matrices. Likewise for vectors. (And actually, also no basedomain checks; but to keep things simpler, I'd like to focus on the dimensions in this issue; we can discuss basedomain checks separately; so for this issue, let's assume that all matrices and vectors have identical basedomain).
We should decide what we demand from resp. allow MatrixObj implementations to do when dimensions don't match. To simplify the discussion further, let's start by focusing on a single example:
What should happen two matrices are added whose dimensions differ?
If they are lists-of-lists, GAP will happily proceed; but the output may not be a matrix anymore:
gap> [[1,2]] + [[3],[4]];
[ [ 4, 2 ], [ 4 ] ]
Similarly, one can add lists of differing lengths; the missing entries in the shorter list are essentially treated as being zero.
So, here are some options I can think of:
We forbid this, and require that conformant MatrixObj implementations must check the dimensions, and must produce an error if the dimensions do not match
We document the behavior explicitly undefined. MatrixObj implementations may check the dimensions, and may produce an error if the dimensions do not match; but they can also produce bogus results
We explicitly allow this, and define what the resulting matrix should be (likely: taking the maximum of the number of rows, and the maximum of the number of columns, and create a matrix of that size; fill the result up with zeros as needed).
... other possibilities... ?
To me option 3 is the least interesting, as I see no applications of this rather artificial behavior. The drawback of option 1 is that it has a performance penalty, albeit probably a rather small one (this is a different once one considers the BaseDomain, though!).
I think I kind of prefer option 2 for this reason, although it has the drawback of letting buggy code slip through. But if we add checks inside of Assert statements in as many places as possible, one could simply set the assertion level up to get slower code that however immediately points out any such bugs.
This example of course has many variants, for addition, subtraction, multiplication; and also for vectors, and as I mentioned, for the basedomain. We should resolve all of those eventually.
The text was updated successfully, but these errors were encountered:
As for option 1, the very general arithmetic behaviour of nested lists was chosen deliberately and should not be restricted. And since a plain list of lists is regarded as a MatrixObj, one could force checks as prescribed by option 1 only for implementations other than plain lists of lists.
Option 3 looks like forcing each implementation of a new kind of MatrixObj to provide extra code for situations which are not intended.
Is there any merit in a category something like IsStrictMatrixObj which guarantees that arithmetic on objects in it will produce an error if the dimensions don't match.
Incidentally, one fundamental concept behind the behaviour of nested lists was to allow unbound entries to regarded as zeros, which people wanted for various things. There were (a lot of) other considerations.
The beauty of MatrixObj is that one can still represent zero entries by unbounded entries internally, this just would be hidden from the user. Of course one also will want ways to make the sparsity "visible", so it can be exploited, but I don't think forcing client code to inspect each entry for being bound/unbound would be helpful or relevant for that.
I am not entirely happy with option 2 as this may produce wrong results and the working mathematician might not notice this at first. Could we maybe provide wrapper functions with checks for dimension that then dispatch to a NC version of the function that can still be used internally?
While working on PR #2973, I noticed that most arithmetics there did not perform any checks on the dimensions of the involved input matrices. Likewise for vectors. (And actually, also no basedomain checks; but to keep things simpler, I'd like to focus on the dimensions in this issue; we can discuss basedomain checks separately; so for this issue, let's assume that all matrices and vectors have identical basedomain).
We should decide what we demand from resp. allow MatrixObj implementations to do when dimensions don't match. To simplify the discussion further, let's start by focusing on a single example:
What should happen two matrices are added whose dimensions differ?
If they are lists-of-lists, GAP will happily proceed; but the output may not be a matrix anymore:
Similarly, one can add lists of differing lengths; the missing entries in the shorter list are essentially treated as being zero.
So, here are some options I can think of:
We forbid this, and require that conformant MatrixObj implementations must check the dimensions, and must produce an error if the dimensions do not match
We document the behavior explicitly undefined. MatrixObj implementations may check the dimensions, and may produce an error if the dimensions do not match; but they can also produce bogus results
We explicitly allow this, and define what the resulting matrix should be (likely: taking the maximum of the number of rows, and the maximum of the number of columns, and create a matrix of that size; fill the result up with zeros as needed).
... other possibilities... ?
To me option 3 is the least interesting, as I see no applications of this rather artificial behavior. The drawback of option 1 is that it has a performance penalty, albeit probably a rather small one (this is a different once one considers the
BaseDomain
, though!).I think I kind of prefer option 2 for this reason, although it has the drawback of letting buggy code slip through. But if we add checks inside of
Assert
statements in as many places as possible, one could simply set the assertion level up to get slower code that however immediately points out any such bugs.This example of course has many variants, for addition, subtraction, multiplication; and also for vectors, and as I mentioned, for the basedomain. We should resolve all of those eventually.
The text was updated successfully, but these errors were encountered: