@@ -211,10 +211,16 @@ function bareiss!(M::AbstractMatrix{T}, swap_strategy = bareiss_colswap;
211
211
end
212
212
213
213
function nullspace (A; col_order = nothing )
214
- column_pivots = collect (1 : size (A, 2 ))
214
+ n = size (A, 2 )
215
+ workspace = zeros (Int, 2 * n)
216
+ column_pivots = @view workspace[1 : n]
217
+ pivots_cache = @view workspace[(n + 1 ): (2 n)]
218
+ @inbounds for i in 1 : n
219
+ column_pivots[i] = i
220
+ end
215
221
B = copy (A)
216
222
(rank, d, column_permuted) = bareiss! (B; column_pivots)
217
- reduce_echelon! (B, rank, d)
223
+ reduce_echelon! (B, rank, d, pivots_cache )
218
224
219
225
# The first rank entries in col_order are columns that give a basis
220
226
# for the column space. The remainder give the free variables.
@@ -226,7 +232,8 @@ function nullspace(A; col_order = nothing)
226
232
end
227
233
end
228
234
229
- N = ModelingToolkit. reduced_echelon_nullspace (rank, B)
235
+ fill! (pivots_cache, 0 )
236
+ N = ModelingToolkit. reduced_echelon_nullspace (rank, B, pivots_cache)
230
237
apply_inv_pivot_rows! (N, column_pivots)
231
238
end
232
239
@@ -241,18 +248,33 @@ end
241
248
# ## Modified from AbstractAlgebra.jl
242
249
# ##
243
250
# ## https://github.com/Nemocas/AbstractAlgebra.jl/blob/4803548c7a945f3f7bd8c63f8bb7c79fac92b11a/LICENSE.md
244
- function reduce_echelon! (A:: AbstractMatrix{T} , rank, d) where {T}
251
+ function reduce_echelon! (A:: AbstractMatrix{T} , rank, d,
252
+ pivots_cache = zeros (Int, size (A, 2 ))) where {T}
245
253
m, n = size (A)
246
- for i in (rank + 1 ): m
247
- for j in 1 : n
248
- A[i, j] = zero (T)
254
+ isreduced = true
255
+ @inbounds for i in 1 : rank
256
+ for j in 1 : (i - 1 )
257
+ if A[j, i] != zero (T)
258
+ isreduced = false
259
+ @goto out
260
+ end
249
261
end
262
+ if A[i, i] != one (T)
263
+ isreduced = false
264
+ @goto out
265
+ end
266
+ end
267
+ @label out
268
+ @inbounds for i in (rank + 1 ): m, j in 1 : n
269
+ A[i, j] = zero (T)
250
270
end
251
- if rank > 1
271
+ isreduced && return A
272
+
273
+ @inbounds if rank > 1
252
274
t = zero (T)
253
275
q = zero (T)
254
276
d = - d
255
- pivots = zeros (Int, n)
277
+ pivots = pivots_cache
256
278
np = rank
257
279
j = k = 1
258
280
for i in 1 : rank
@@ -292,17 +314,18 @@ function reduce_echelon!(A::AbstractMatrix{T}, rank, d) where {T}
292
314
return A
293
315
end
294
316
295
- function reduced_echelon_nullspace (rank, A:: AbstractMatrix{T} ) where {T}
317
+ function reduced_echelon_nullspace (rank, A:: AbstractMatrix{T} ,
318
+ pivots_cache = zeros (Int, size (A, 2 ))) where {T}
296
319
n = size (A, 2 )
297
320
nullity = n - rank
298
321
U = zeros (T, n, nullity)
299
- if rank == 0
322
+ @inbounds if rank == 0
300
323
for i in 1 : nullity
301
324
U[i, i] = one (T)
302
325
end
303
326
elseif nullity != 0
304
- pivots = zeros (Int, rank)
305
- nonpivots = zeros (Int, nullity)
327
+ pivots = @view pivots_cache[ 1 : rank]
328
+ nonpivots = @view pivots_cache[(rank + 1 ) : n]
306
329
j = k = 1
307
330
for i in 1 : rank
308
331
while iszero (A[i, j])
0 commit comments