-
Notifications
You must be signed in to change notification settings - Fork 57
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
copy(::MatrixElem) can return a different type #651
Comments
Yes, copy and deepcopy should not change the type. This is a bug. Whatever similar does, it should not affect copy or deepcopy. |
Agreed. |
Do we have to fix it also in AbstractAlgebra? |
When It seems we need a function which returns a matrix of the same type as the input matrix, with the same dimensions (both for |
Besides julia> m = one(Generic.MatSpace{fmpq}(FlintQQ, 2, 2, false));
julia> typeof(m)
AbstractAlgebra.Generic.MatSpaceElem{fmpq}
julia> typeof(-m)
fmpq_mat
julia> for mat in [2m, m+m, m*m, m^2, sub(m, 1:2, 1:2), m[1:2,:], divexact(m, 1),
kronecker_product(m, m), transpose(m), gram(m),
perm"(1, 2)" * m, solve_triu(m, m), solve(m, m),
pseudo_inv(m)[1], inv(m), nullspace(m)[2],
left_kernel(m)[2], kernel(m)[2], hcat(m, m), [m; m], map(identity, m)]
@assert fmpq_mat == typeof(mat)
end
julia> typeof(m^1) == typeof(m^2)
false
julia> powers(m, 3)
ERROR: MethodError: Cannot `convert` an object of type fmpq_mat to an object of type AbstractAlgebra.Generic.MatSpaceElem{fmpq}
Closest candidates are:
[...] Bug? not bug? |
Definitely a bug. The first case alone is clearly bad. If you start with something in a given matrix space, -m should not give you something in another matrix space. We definitely need to fix this. It's not at all clear why it is doing that. I'm pretty sure Nemo didn't used to do that, did it? |
It seems that the -m bug must be in similar. It looks like similar is not actually creating a similar matrix. Let me look at the definition of similar and see if this can be fixed. |
It started when we added the option to change the base ring in |
The issue is the definition of similar in Nemo:
You just need to change the first argument to have type fmpz_mat. One clearly doesn't get a "similar" matrix in any other case. |
Or you can change the general definition of similar(M) in AbstractAlgebra to not call the version which "changes" the base ring. |
But we still want And similar for |
There is no version which does not change the base ring, since it is a keyword argument. So it will always call |
I see that you did not follow all the discussions about |
What!? The first one I can live with. The second is surely a bug! I'll come and discuss with you. |
Minor remark, it's not a keyword arg, just a normal arg with default value.
This is what I had implemented initially for this behavior:
Which looks nice, but unfortunately leads to this questionable behavior of |
@thofma and I had a (very) long discussion about what behaviour we ultimately want. In his case, he wants change_base_ring(ZZ, M) in Nemo, where M is a Generic.MatSpaceElem{nf_elem} to return an fmpz_mat. Reason: both fmpz_mat and Generic.MatSpaceElem{nf_elem} are matrices that Nemo would create. In my case, I want change_base_ring(Nemo.ZZ, p) in Singular, where p is a Singular spoly{fmpq} to return an spoly{fmpz}. Reason: both polynomials are what Singular would create over a Nemo coefficient ring. So we don't disagree on what we want, it's just not implemented that way at present (and probably wasn't implemented correctly before the new similar functionality, either). The following simple 7 steps will lead to balance being restored in the force:
2a. Create an abstract type NemoRing <: AbstractAlgebra.Ring and make all Nemo ring element types belong to this instead of directly to the AbstractAlgebra abstract type.
I don't discuss here how we handle the Singular functionality, which allows for creating Singular polynomials over Nemo coefficient rings and vice versa. But it is clear that the strategy above is consistent across all our systems and will work there too. |
I've opened a separate ticket for this. Nemocas/AbstractAlgebra.jl#490 |
Re-opening, for tracking progress on fixing the examples above. |
The examples above are now fixed, with tests for some of them. |
It was decided recently (#638) that
similar(mat, ring)
doesn't necessarily return a matrix of the the same type asmat
. With the current implementation ofcopy
, which calls out to similar, it also means thatcopy(mat)
may be of a different type thanmat
. This also means thatdeepcopy
can fail, becauseBase.deepcopy
puts a typeassert on the return type (assumed to be of the same type as the input). For example:I find
copy(mat)
not returning the same type asmat
slightly annoying, but this is consistent with some other matrix constructors which will favorfmpz_mat
when theelem_type
isfmpz
. What do you think?On the other hand,
deepcopy
should be fixed to not fail.The text was updated successfully, but these errors were encountered: