1
1
# FiniteRange gives the nonzero entries in a row/column
2
2
struct FiniteRange end
3
3
4
- getindex (A:: AbstractMatrix ,:: Type{FiniteRange} ,j:: Integer ) = A[1 : colstop (A,j),j]
4
+ getindex (A:: AbstractMatrix ,:: Type{FiniteRange} ,j:: Integer ) = A[colrange (A,j),j]
5
5
getindex (A:: AbstractMatrix ,k:: Integer ,:: Type{FiniteRange} ) = A[k,1 : rowstop (A,k)]
6
6
7
7
const ⤓ = FiniteRange
@@ -32,40 +32,48 @@ RaggedMatrix{T}(::UndefInitializer, m::Int, colns::AbstractVector{Int}) where {T
32
32
RaggedMatrix (Vector {T} (undef, sum (colns)),Int[1 ;1 .+ cumsum (colns)],m)
33
33
34
34
35
- Base . size (A:: RaggedMatrix ) = (A. m,length (A. cols)- 1 )
35
+ size (A:: RaggedMatrix ) = (A. m,length (A. cols)- 1 )
36
36
37
37
colstart (A:: RaggedMatrix ,j:: Integer ) = 1
38
38
colstop (A:: RaggedMatrix ,j:: Integer ) = min (A. cols[j+ 1 ]- A. cols[j],size (A,1 ))
39
39
40
- @inline function incol (A, k, j, ind = A. cols[j]+ k- 1 )
40
+ Base . @propagate_inbounds function incol (A, k, j, ind = A. cols[j]+ k- 1 )
41
41
ind < A. cols[j+ 1 ]
42
42
end
43
43
44
- function getindex (A:: RaggedMatrix ,k:: Int ,j:: Int )
45
- if k> size (A,1 ) || k < 1 || j> size (A,2 ) || j < 1
44
+ Base. @propagate_inbounds function incols_getindex (A:: RaggedMatrix , k:: Int , j:: Int , ind = A. cols[j]+ k- 1 )
45
+ A. data[ind]
46
+ end
47
+ Base. @propagate_inbounds function incols_setindex! (A:: RaggedMatrix , v, k:: Int , j:: Int , ind = A. cols[j]+ k- 1 )
48
+ A. data[ind] = v
49
+ A
50
+ end
51
+
52
+ Base. @propagate_inbounds function getindex (A:: RaggedMatrix ,k:: Int ,j:: Int )
53
+ @boundscheck if k> size (A,1 ) || k < 1 || j> size (A,2 ) || j < 1
46
54
throw (BoundsError (A,(k,j)))
47
55
end
48
56
49
57
ind = A. cols[j]+ k- 1
50
58
if incol (A, k, j, ind)
51
- A . data[ ind]
59
+ incols_getindex (A, k, j, ind)
52
60
else
53
61
zero (eltype (A))
54
62
end
55
63
end
56
64
57
- function Base. setindex! (A:: RaggedMatrix ,v,k:: Int ,j:: Int )
58
- if k> size (A,1 ) || k < 1 || j> size (A,2 ) || j < 1
65
+ Base. @propagate_inbounds function setindex! (A:: RaggedMatrix ,v,k:: Int ,j:: Int )
66
+ @boundscheck if k> size (A,1 ) || k < 1 || j> size (A,2 ) || j < 1
59
67
throw (BoundsError (A,(k,j)))
60
68
end
61
69
62
70
ind = A. cols[j]+ k- 1
63
71
if incol (A, k, j, ind)
64
- A . data[ind] = v
72
+ incols_setindex! (A, v, k, j, ind)
65
73
elseif v ≠ 0
66
- throw (BoundsError (A,( k,j)))
74
+ throw (ArgumentError ( " Can't set index $(( k,j)) of a RaggedMatrix to a non-zero value " ))
67
75
end
68
- v
76
+ A
69
77
end
70
78
71
79
convert (:: Type{RaggedMatrix{T}} , R:: RaggedMatrix{T} ) where T = R
@@ -75,40 +83,32 @@ convert(::Type{RaggedMatrix{T}}, R::RaggedMatrix) where T =
75
83
76
84
77
85
function convert (:: Type{Matrix{T}} , A:: RaggedMatrix ) where T
78
- ret = zeros (T,size (A,1 ),size (A,2 ))
79
- for j= 1 : size (A,2 )
80
- ret[1 : colstop (A,j),j] = view (A,1 : colstop (A,j),j)
86
+ ret = zeros (T, size (A))
87
+ @inbounds for j in axes (A,2 ), k in colrange (A,j)
88
+ v = incols_getindex (A, k, j)
89
+ ret[k,j] = v
81
90
end
82
91
ret
83
92
end
84
93
85
94
convert (:: Type{Matrix} , A:: RaggedMatrix ) = Matrix {eltype(A)} (A)
86
95
87
- function convert (:: Type{RaggedMatrix{T}} , B:: BandedMatrix ) where T
88
- l = bandwidth (B,1 )
89
- ret = RaggedMatrix (Zeros {T} (size (B)), Int[colstop (B,j) for j= 1 : size (B,2 )])
90
- for j= 1 : size (B,2 ),k= colrange (B,j)
91
- ret[k,j] = B[k,j]
92
- end
93
- ret
94
- end
95
-
96
96
convert (:: Type{RaggedMatrix} , B:: BandedMatrix ) = RaggedMatrix {eltype(B)} (B)
97
97
98
98
function convert (:: Type{RaggedMatrix{T}} , B:: AbstractMatrix ) where T
99
- ret = RaggedMatrix (Zeros {T} (size (B)), Int[colstop (B,j) for j= 1 : size (B,2 )])
100
- for j= 1 : size (B,2 ), k= colrange (B,j)
101
- ret[k,j] = B[k,j]
99
+ ret = RaggedMatrix (Zeros {T} (size (B)), Int[colstop (B,j) for j= axes (B,2 )])
100
+ @inbounds for j in axes (B,2 ), k in colrange (B,j)
101
+ incols_setindex! ( ret, B [k,j], k, j)
102
102
end
103
103
ret
104
104
end
105
105
106
- convert (:: Type{RaggedMatrix} , B:: AbstractMatrix ) = RaggedMatrix {eltype(B)} ( B)
106
+ convert (:: Type{RaggedMatrix} , B:: AbstractMatrix ) = strictconvert ( RaggedMatrix{eltype (B)}, B)
107
107
108
108
RaggedMatrix (B:: AbstractMatrix ) = strictconvert (RaggedMatrix, B)
109
109
RaggedMatrix {T} (B:: AbstractMatrix ) where T = strictconvert (RaggedMatrix{T}, B)
110
110
111
- Base . similar (B:: RaggedMatrix ,:: Type{T} ) where {T} = RaggedMatrix (similar (B. data, T),copy (B. cols),B. m)
111
+ similar (B:: RaggedMatrix ,:: Type{T} ) where {T} = RaggedMatrix (similar (B. data, T),copy (B. cols),B. m)
112
112
113
113
for (op,bop) in ((:(Base. rand), :rrand ),)
114
114
@eval begin
@@ -126,9 +126,13 @@ function RaggedMatrix{T}(Z::Zeros, colns::AbstractVector{Int}) where {T}
126
126
end
127
127
128
128
function RaggedMatrix {T} (A:: AbstractMatrix , colns:: AbstractVector{Int} ) where T
129
+ Base. require_one_based_indexing (A)
130
+ Base. require_one_based_indexing (colns)
129
131
ret = RaggedMatrix {T} (undef, size (A,1 ), colns)
130
- @inbounds for j = 1 : length (colns), k = 1 : colns[j]
131
- ret[k,j] = A[k,j]
132
+ (length (colns) == size (A,2 ) && all (<= (size (A,1 )), colns)) ||
133
+ throw (ArgumentError (" column stops $colns incompatible with input matrix of size $(size (A)) " ))
134
+ for j in axes (A,2 ), k = 1 : colns[j]
135
+ @inbounds incols_setindex! (ret, A[k,j], k, j)
132
136
end
133
137
ret
134
138
end
@@ -149,7 +153,7 @@ function mul!(y::Vector, A::RaggedMatrix, b::Vector)
149
153
end
150
154
T= eltype (y)
151
155
fill! (y,zero (T))
152
- for j= 1 : m
156
+ for j in axes (A, 2 )
153
157
kr= A. cols[j]: A. cols[j+ 1 ]- 1
154
158
axpy! (b[j],view (A. data,kr),view (y,1 : length (kr)))
155
159
end
@@ -165,7 +169,7 @@ function axpy!(a, X::RaggedMatrix, Y::RaggedMatrix)
165
169
if X. cols == Y. cols
166
170
axpy! (a,X. data,Y. data)
167
171
else
168
- for j = 1 : size (X,2 )
172
+ for j = axes (X,2 )
169
173
Xn = colstop (X,j)
170
174
Yn = colstop (Y,j)
171
175
if Xn > Yn # check zeros otherwise
@@ -174,8 +178,8 @@ function axpy!(a, X::RaggedMatrix, Y::RaggedMatrix)
174
178
end
175
179
end
176
180
cs = min (Xn,Yn)
177
- axpy! (a,view (X. data,X. cols[j]: X . cols[j] + cs - 1 ),
178
- view (Y. data,Y. cols[j]: Y . cols[j] + cs - 1 ))
181
+ axpy! (a, view (X. data, range ( X. cols[j], length = cs) ),
182
+ view (Y. data, range ( Y. cols[j], length = cs) ))
179
183
end
180
184
end
181
185
Y
@@ -196,7 +200,7 @@ function axpy!(a,X::RaggedMatrix,
196
200
ksh = first (parentindices (Y)[1 ]) - 1 # how much to shift
197
201
jsh = first (parentindices (Y)[2 ]) - 1 # how much to shift
198
202
199
- for j= 1 : size (X,2 )
203
+ for j= axes (X,2 )
200
204
cx= colstop (X,j)
201
205
cy= colstop (Y,j)
202
206
if cx > cy
@@ -205,7 +209,7 @@ function axpy!(a,X::RaggedMatrix,
205
209
throw (BoundsError (" Trying to add a non-zero to a zero." ))
206
210
end
207
211
end
208
- kr = X. cols[j]: X . cols[j] + cy - 1
212
+ kr = range ( X. cols[j], length = cy)
209
213
else
210
214
kr = X. cols[j]: X. cols[j+ 1 ]- 1
211
215
end
222
226
function * (A:: RaggedMatrix ,B:: RaggedMatrix )
223
227
cols = zeros (Int,size (B,2 ))
224
228
T = promote_type (eltype (A),eltype (B))
225
- for j= 1 : size (B,2 ),k= 1 : colstop (B,j)
229
+ for j= axes (B,2 ),k= colrange (B,j)
226
230
cols[j] = max (cols[j],colstop (A,k))
227
231
end
228
232
@@ -232,23 +236,23 @@ end
232
236
function unsafe_mul! (Y:: RaggedMatrix ,A:: RaggedMatrix ,B:: RaggedMatrix )
233
237
fill! (Y. data,0 )
234
238
235
- for j= 1 : size (B,2 ),k= 1 : colstop (B,j)
236
- axpy! (B[k,j], view (A,1 : colstop (A,k),k),
237
- view (Y. data,Y. cols[j] .- 1 .+ (1 : colstop (A,k))))
239
+ for j= axes (B,2 ),k= colrange (B,j)
240
+ axpy! (B[k,j], view (A,colrange (A,k),k),
241
+ view (Y. data,Y. cols[j] .- 1 .+ (colrange (A,k))))
238
242
end
239
243
240
244
Y
241
245
end
242
246
243
247
function mul! (Y:: RaggedMatrix ,A:: RaggedMatrix ,B:: RaggedMatrix )
244
- for j= 1 : size (B,2 )
248
+ for j= axes (B,2 )
245
249
col = 0
246
- for k= 1 : colstop (B,j)
250
+ for k= colrange (B,j)
247
251
col = max (col,colstop (A,k))
248
252
end
249
253
250
254
if col > colstop (Y,j)
251
- throw (BoundsError ())
255
+ throw (BoundsError (Y, (col,j) ))
252
256
end
253
257
end
254
258
0 commit comments