Skip to content

Commit dbfbb60

Browse files
authored
Simplify and fix similar and zero for our matrix types (#1890)
Remove the internal helper `_similar` which untangles the `MatElem` and `MatRingElem` code further and makes it easier to see what's going on. Also change `similar` for `MatElem` to default to calling `zero_matrix`. With this `similar(::ZZMatrix)` in Nemo returns a new `ZZMatrix` instead of a `AbstractAlgebra.Generic.MatSpaceElem{ZZRingElem}`. Also untangle `zero` and `similar` methods for `MatElem` versus `MatRingElem`.
1 parent 286b6b4 commit dbfbb60

File tree

6 files changed

+89
-39
lines changed

6 files changed

+89
-39
lines changed

docs/src/matrix.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ diagonal_matrix(::RingElement, ::Int, ::Int)
433433

434434
```@docs
435435
zero(::MatSpace)
436-
zero(::MatrixElem{T}, ::Ring) where T <: RingElement
436+
zero(::MatElem{T}, ::Ring) where T <: RingElement
437437
```
438438

439439
```@docs

src/MatRing.jl

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,23 @@ is_finite(R::MatRing) = iszero(nrows(a)) || is_finite(base_ring(R))
7979
###############################################################################
8080

8181
@doc raw"""
82-
similar(x::Generic.MatrixElem, R::NCRing=base_ring(x))
83-
similar(x::Generic.MatrixElem, R::NCRing, r::Int, c::Int)
84-
similar(x::Generic.MatrixElem, r::Int, c::Int)
8582
similar(x::MatRingElem, R::NCRing, n::Int)
83+
similar(x::MatRingElem, R::NCRing)
8684
similar(x::MatRingElem, n::Int)
85+
similar(x::MatRingElem)
8786
88-
Create an uninitialized matrix over the given ring and dimensions,
89-
with defaults based upon the given source matrix `x`.
87+
Create an uninitialized matrix ring element over the given ring and dimension,
88+
with defaults based upon the given source matrix ring element `x`.
9089
"""
91-
similar(x::MatRingElem, R::NCRing, n::Int) = _similar(x, R, n, n)
92-
93-
similar(x::MatRingElem, R::NCRing=base_ring(x)) = similar(x, R, degree(x))
90+
function similar(x::MatRingElem, R::NCRing=base_ring(x), n::Int=degree(x))
91+
TT = elem_type(R)
92+
M = Matrix{TT}(undef, (n, n))
93+
return Generic.MatRingElem{TT}(R, M)
94+
end
9495

9596
similar(x::MatRingElem, n::Int) = similar(x, base_ring(x), n)
9697

98+
# TODO: deprecate these:
9799
function similar(x::MatRingElem{T}, R::NCRing, m::Int, n::Int) where T <: NCRingElement
98100
m != n && error("Dimensions don't match in similar")
99101
return similar(x, R, n)
@@ -102,18 +104,21 @@ end
102104
similar(x::MatRingElem, m::Int, n::Int) = similar(x, base_ring(x), m, n)
103105

104106
@doc raw"""
105-
zero(x::MatrixElem, R::NCRing=base_ring(x))
106-
zero(x::MatrixElem, R::NCRing, r::Int, c::Int)
107-
zero(x::MatrixElem, r::Int, c::Int)
108107
zero(x::MatRingElem, R::NCRing, n::Int)
108+
zero(x::MatRingElem, R::NCRing)
109109
zero(x::MatRingElem, n::Int)
110+
zero(x::MatRingElem)
110111
111-
Create a zero matrix over the given ring and dimensions,
112-
with defaults based upon the given source matrix `x`.
112+
Create a zero matrix ring element over the given ring and dimension,
113+
with defaults based upon the given source matrix ring element `x`.
113114
"""
114-
zero(x::MatRingElem, R::NCRing, n::Int) = zero!(similar(x, R, n))
115+
zero(x::MatRingElem, R::NCRing=base_ring(x), n::Int=degree(x)) = zero!(similar(x, R, n))
115116
zero(x::MatRingElem, n::Int) = zero!(similar(x, n))
116117

118+
# TODO: deprecate these
119+
zero(x::MatRingElem, R::NCRing, r::Int, c::Int) = zero!(similar(x, R, r, c))
120+
zero(x::MatRingElem, r::Int, c::Int) = zero!(similar(x, r, c))
121+
117122
################################################################################
118123
#
119124
# Copy and deepcopy

src/Matrix.jl

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -229,18 +229,6 @@ Return the zero matrix in the given matrix space.
229229
"""
230230
zero(a::MatSpace) = a()
231231

232-
@doc raw"""
233-
zero(x::MatrixElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
234-
zero(x::MatrixElem{T}, R::NCRing=base_ring(x)) where T <: NCRingElement
235-
zero(x::MatrixElem{T}, r::Int, c::Int) where T <: NCRingElement
236-
237-
Return a zero matrix similar to the given matrix, with optionally different
238-
base ring or dimensions.
239-
"""
240-
zero(x::MatrixElem{T}, R::NCRing=base_ring(x)) where T <: NCRingElement = zero(x, R, nrows(x), ncols(x))
241-
zero(x::MatrixElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement = zero!(similar(x, R, r, c))
242-
zero(x::MatrixElem{T}, r::Int, c::Int) where T <: NCRingElement = zero(x, base_ring(x), r, c)
243-
244232
@doc raw"""
245233
one(a::MatSpace)
246234
@@ -398,19 +386,37 @@ end
398386
#
399387
###############################################################################
400388

401-
function _similar(x::MatrixElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
402-
TT = elem_type(R)
403-
M = Matrix{TT}(undef, (r, c))
404-
z = x isa MatElem ? Generic.MatSpaceElem{TT}(R, M) : Generic.MatRingElem{TT}(R, M)
405-
return z
406-
end
407-
408-
similar(x::MatElem, R::NCRing, r::Int, c::Int) = _similar(x, R, r, c)
389+
@doc raw"""
390+
similar(x::MatElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
391+
similar(x::MatElem{T}, R::NCRing) where T <: NCRingElement
392+
similar(x::MatElem{T}, r::Int, c::Int) where T <: NCRingElement
393+
similar(x::MatElem{T}) where T <: NCRingElement
409394
410-
similar(x::MatElem, R::NCRing=base_ring(x)) = similar(x, R, nrows(x), ncols(x))
395+
Create an uninitialized matrix over the given ring and dimensions,
396+
with defaults based upon the given source matrix `x`.
397+
"""
398+
similar(x::MatElem, R::NCRing, r::Int, c::Int) = zero_matrix(R, r, c)
399+
400+
similar(x::MatElem, R::NCRing) = similar(x, R, nrows(x), ncols(x))
411401

412402
similar(x::MatElem, r::Int, c::Int) = similar(x, base_ring(x), r, c)
413403

404+
similar(x::MatElem) = similar(x, nrows(x), ncols(x))
405+
406+
@doc raw"""
407+
zero(x::MatElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement
408+
zero(x::MatElem{T}, r::Int, c::Int) where T <: NCRingElement
409+
zero(x::MatElem{T}, R::NCRing) where T <: NCRingElement
410+
zero(x::MatElem{T}) where T <: NCRingElement
411+
412+
Create an zero matrix over the given ring and dimensions,
413+
with defaults based upon the given source matrix `x`.
414+
"""
415+
zero(x::MatElem{T}, R::NCRing) where T <: NCRingElement = zero(x, R, nrows(x), ncols(x))
416+
zero(x::MatElem{T}) where T <: NCRingElement = zero(x, nrows(x), ncols(x))
417+
zero(x::MatElem{T}, R::NCRing, r::Int, c::Int) where T <: NCRingElement = zero!(similar(x, R, r, c))
418+
zero(x::MatElem{T}, r::Int, c::Int) where T <: NCRingElement = zero!(similar(x, r, c))
419+
414420
###############################################################################
415421
#
416422
# Canonicalisation
@@ -1014,7 +1020,7 @@ function +(x::T, y::MatrixElem{T}) where {T <: NCRingElem}
10141020
end
10151021

10161022
@doc raw"""
1017-
+(x::Generic.MatrixElem{T}, y::T) where {T <: RingElem}
1023+
+(x::MatrixElem{T}, y::T) where {T <: RingElem}
10181024
10191025
Return $x + S(y)$ where $S$ is the parent of $x$.
10201026
"""

src/generic/Matrix.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ Base.isassigned(a::Union{Mat,MatRingElem}, i, j) = isassigned(a.entries, i, j)
5858
#
5959
################################################################################
6060

61+
function similar(x::MatSpaceElem{T}, r::Int, c::Int) where T <: NCRingElement
62+
M = Matrix{T}(undef, (r, c))
63+
return MatSpaceElem{T}(base_ring(x), M)
64+
end
65+
6166
function copy(d::MatSpaceElem{T}) where T <: NCRingElement
6267
return MatSpaceElem{T}(base_ring(d), copy(d.entries))
6368
end

test/Rings-conformance-tests.jl

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ function test_MatSpace_interface(S::MatSpace; reps = 20)
740740
R = base_ring(S)
741741
T = elem_type(R)
742742

743+
@test base_ring_type(S) == typeof(R)
744+
@test parent_type(ST) == typeof(S)
745+
@test dense_matrix_type(R) == ST
746+
743747
@testset "MatSpace interface for $(S) of type $(typeof(S))" begin
744748

745749
@testset "Constructors" begin
@@ -752,6 +756,29 @@ function test_MatSpace_interface(S::MatSpace; reps = 20)
752756
@test a == matrix(R, T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)])
753757
@test a == matrix(R, nrows(S), ncols(S),
754758
T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)])
759+
760+
b = similar(a)
761+
@test b isa ST
762+
@test nrows(b) == nrows(S)
763+
@test ncols(b) == ncols(S)
764+
765+
b = similar(a, nrows(S)+1, ncols(S)+1)
766+
@test b isa ST
767+
@test nrows(b) == nrows(S)+1
768+
@test ncols(b) == ncols(S)+1
769+
770+
b = similar(a, R)
771+
@test b isa MatElem
772+
#@test b isa ST # undefined
773+
@test nrows(b) == nrows(S)
774+
@test ncols(b) == ncols(S)
775+
776+
b = similar(a, R, nrows(S)+1, ncols(S)+1)
777+
@test b isa MatElem
778+
#@test b isa ST # undefined
779+
@test nrows(b) == nrows(S)+1
780+
@test ncols(b) == ncols(S)+1
781+
755782
end
756783
@test iszero(zero_matrix(R, nrows(S), ncols(S)))
757784
end
@@ -767,12 +794,20 @@ function test_MatSpace_interface(S::MatSpace; reps = 20)
767794
for k in 1:reps
768795
a = test_elem(S)::ST
769796
A = deepcopy(a)
797+
@test A isa ST
798+
770799
b = zero_matrix(R, nrows(a), ncols(a))
800+
@test b isa ST
771801
for i in 1:nrows(a), j in 1:ncols(a)
772802
b[i, j] = a[i, j]
773803
end
774804
@test b == a
775-
@test transpose(transpose(a)) == a
805+
806+
t = transpose(a)
807+
@test t isa ST
808+
@test nrows(t) == ncols(S)
809+
@test ncols(t) == nrows(S)
810+
@test transpose(t) == a
776811
@test a == A
777812
end
778813
end

test/generic/Matrix-test.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ AbstractAlgebra.base_ring(::F2Matrix) = F2()
8686

8787
Base.getindex(a::F2Matrix, r::Int64, c::Int64) = a.m[r, c]
8888
Base.setindex!(a::F2Matrix, x::F2Elem, r::Int64, c::Int64) = a.m[r, c] = x
89-
Base.similar(x::F2Matrix, R::F2, r::Int, c::Int) = F2Matrix(similar(x.m, r, c))
9089

9190
function AbstractAlgebra.zero_matrix(R::F2, r::Int, c::Int)
9291
mat = Matrix{F2Elem}(undef, r, c)

0 commit comments

Comments
 (0)