Skip to content

Commit dd23a38

Browse files
authored
Change similar, zero_matrix, ones_matrix to use UndefInitializer constructors (#1909)
1 parent 2248f24 commit dd23a38

File tree

3 files changed

+25
-63
lines changed

3 files changed

+25
-63
lines changed

src/Matrix.jl

Lines changed: 18 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ function _check_dim(r::Int, c::Int, a::MatrixElem)
4949
return nothing
5050
end
5151

52-
function _check_bases(a, b)
53-
base_ring(a) == base_ring(b) || throw(DomainError((a, b), "Base rings do not match."))
54-
return nothing
55-
end
56-
5752
_checkbounds(i::Int, j::Int) = 1 <= j <= i
5853

5954
_checkbounds(i::Int, j::AbstractVector{Int}) = all(jj -> 1 <= jj <= i, j)
@@ -96,55 +91,20 @@ end
9691

9792
function (s::MatSpace{T})(a::MatrixElem{T}) where {T <: NCRingElement}
9893
_check_dim(nrows(s), ncols(s), a)
99-
_check_bases(s, a)
94+
base_ring(s) == base_ring(a) || throw(DomainError((s, a), "Base rings do not match."))
10095
a isa eltype(s) && return a
101-
M = s() # zero matrix
102-
R = base_ring(s)
103-
if R == base_ring(a)
104-
for i = 1:nrows(s), j = 1:ncols(s)
105-
M[i, j] = a[i, j]
106-
end
107-
else
108-
for i = 1:nrows(s), j = 1:ncols(s)
109-
M[i, j] = R(a[i, j])
110-
end
111-
end
112-
return M
96+
return matrix(base_ring(s), a)
11397
end
11498

11599
# create a matrix with b on the diagonal
116100
function (s::MatSpace)(b::NCRingElement)
117-
M = s() # zero matrix
118101
R = base_ring(s)
119-
rb = R(b)
120-
for i in 1:min(nrows(s), ncols(s))
121-
M[i, i] = rb
122-
end
123-
return M
124-
end
125-
126-
# convert a Julia matrix
127-
function (a::MatSpace{T})(b::AbstractMatrix{S}) where {T <: NCRingElement, S}
128-
_check_dim(nrows(a), ncols(a), b)
129-
R = base_ring(a)
130-
131-
# minor optimization for MatSpaceElem
132-
if S === T && dense_matrix_type(T) === Generic.MatSpaceElem{T} && all(x -> R === parent(x), b)
133-
return Generic.MatSpaceElem{T}(R, b)
134-
end
135-
136-
# generic code
137-
M = a() # zero matrix
138-
for i = 1:nrows(a), j = 1:ncols(a)
139-
M[i, j] = R(b[i, j])
140-
end
141-
return M
102+
return diagonal_matrix(R(b), nrows(s), ncols(s))
142103
end
143104

144-
# convert a Julia vector
145-
function (a::MatSpace{T})(b::AbstractVector) where T <: NCRingElement
146-
_check_dim(nrows(a), ncols(a), b)
147-
return a(transpose(reshape(b, a.ncols, a.nrows)))
105+
# convert a Julia matrix or vector
106+
function (a::MatSpace{T})(b::AbstractVecOrMat) where T <: NCRingElement
107+
return matrix(base_ring(a), nrows(a), ncols(a), b)
148108
end
149109

150110

@@ -395,7 +355,7 @@ end
395355
Create an uninitialized matrix over the given ring and dimensions,
396356
with defaults based upon the given source matrix `x`.
397357
"""
398-
similar(x::MatElem, R::NCRing, r::Int, c::Int) = zero_matrix(R, r, c)
358+
similar(x::MatElem, R::NCRing, r::Int, c::Int) = dense_matrix_type(R)(R, undef, r, c)
399359

400360
similar(x::MatElem, R::NCRing) = similar(x, R, nrows(x), ncols(x))
401361

@@ -879,7 +839,7 @@ function zero!(x::MatrixElem{T}) where T <: NCRingElement
879839
for i = 1:nrows(x), j = 1:ncols(x)
880840
x[i, j] = zero(R)
881841
end
882-
x
842+
return x
883843
end
884844

885845
function add!(c::MatrixElem{T}, a::MatrixElem{T}, b::MatrixElem{T}) where T <: NCRingElement
@@ -6669,7 +6629,11 @@ function matrix(R::NCRing, arr::MatElem)
66696629
end
66706630

66716631
function matrix(R::NCRing, arr::MatRingElem)
6672-
return matrix_space(R, nrows(arr), ncols(arr))(arr)
6632+
M = zero_matrix(R, nrows(arr), ncols(arr))
6633+
for i in 1:nrows(arr), j in 1:ncols(arr)
6634+
M[i, j] = arr[i, j]
6635+
end
6636+
return M
66736637
end
66746638

66756639
function matrix(mat::MatrixElem{T}) where {T<:NCRingElement}
@@ -6726,14 +6690,8 @@ end
67266690
Return the $r \times c$ zero matrix over $R$.
67276691
"""
67286692
function zero_matrix(R::NCRing, r::Int, c::Int)
6729-
arr = Matrix{elem_type(R)}(undef, r, c)
6730-
for i in 1:r
6731-
for j in 1:c
6732-
arr[i, j] = zero(R)
6733-
end
6734-
end
6735-
z = Generic.MatSpaceElem{elem_type(R)}(R, arr)
6736-
return z
6693+
(r < 0 || c < 0) && error("Dimensions must be non-negative")
6694+
return zero!(dense_matrix_type(R)(R, undef, r, c))
67376695
end
67386696

67396697
zero_matrix(::Type{MatElem}, R::Ring, n::Int, m::Int) = zero_matrix(R, n, m)
@@ -6750,11 +6708,9 @@ zero_matrix(::Type{MatElem}, R::Ring, n::Int, m::Int) = zero_matrix(R, n, m)
67506708
Return the $r \times c$ ones matrix over $R$.
67516709
"""
67526710
function ones_matrix(R::NCRing, r::Int, c::Int)
6753-
z = zero_matrix(R, r, c)
6754-
for i in 1:r
6755-
for j in 1:c
6756-
z[i, j] = one(R)
6757-
end
6711+
z = dense_matrix_type(R)(R, undef, r, c)
6712+
for i in 1:r, j in 1:c
6713+
z[i, j] = one(R)
67586714
end
67596715
return z
67606716
end

src/generic/Matrix.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ parent(a::MatElem) = matrix_space(base_ring(a), nrows(a), ncols(a))
2525
2626
Return the type of matrices with coefficients of type `T` respectively
2727
`elem_type(S)`.
28+
29+
Implementations of the ring interface only need to provide a method
30+
for the argument a subtype of `NCRingElement`; the other variants are
31+
implemented by calling that method.
2832
"""
2933
dense_matrix_type(::T) where T <: NCRing = dense_matrix_type(elem_type(T))
3034
dense_matrix_type(::T) where T <: NCRingElement = dense_matrix_type(T)

test/generic/Matrix-test.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,13 @@ struct F2Matrix <: AbstractAlgebra.MatElem{F2Elem}
7373
m::Generic.MatSpaceElem{F2Elem}
7474
end
7575

76+
F2Matrix(::F2, ::UndefInitializer, r::Int, c::Int) = F2Matrix(Generic.MatSpaceElem{F2Elem}(F2(), undef, r, c))
77+
7678
AbstractAlgebra.elem_type(::Type{F2MatSpace}) = F2Matrix
7779
AbstractAlgebra.parent_type(::Type{F2Matrix}) = F2MatSpace
7880

7981
AbstractAlgebra.base_ring(::F2MatSpace) = F2()
80-
AbstractAlgebra.dense_matrix_type(::Type{F2}) = F2Matrix
82+
AbstractAlgebra.dense_matrix_type(::Type{F2Elem}) = F2Matrix
8183
AbstractAlgebra.matrix_space(::F2, r::Int, c::Int) = F2MatSpace(F2(), r, c)
8284

8385
AbstractAlgebra.number_of_rows(a::F2Matrix) = nrows(a.m)

0 commit comments

Comments
 (0)