@@ -450,20 +450,28 @@ count_nonzeros(a::AbstractArray) = count(!iszero, a)
450
450
# Here we have a guarantee that they won't, so we can make this identification
451
451
count_nonzeros (a:: SparseVector ) = nnz (a)
452
452
453
- function aag_bareiss! (graph, var_to_diff, mm_orig:: SparseMatrixCLIL , only_algebraic = true ,
454
- irreducibles = ())
453
+ function aag_bareiss! (graph, var_to_diff, mm_orig:: SparseMatrixCLIL , irreducibles = ())
455
454
mm = copy (mm_orig)
456
455
is_linear_equations = falses (size (AsSubMatrix (mm_orig), 1 ))
457
456
for e in mm_orig. nzrows
458
457
is_linear_equations[e] = true
459
458
end
460
459
461
- is_not_potential_state = isnothing .(var_to_diff)
460
+ # If linear highest differentiated variables cannot be assigned to a pivot,
461
+ # then we can set it to zero. We use `rank1` to track this.
462
+ #
463
+ # We only use alias graph to record reducible variables. We use `rank2` to
464
+ # track this.
465
+ #
466
+ # For all the other variables, we can update the original system with
467
+ # Bareiss'ed coefficients as Gaussian elimination is nullspace perserving
468
+ # and we are only working on linear homogeneous subsystem.
469
+ is_linear_variables = isnothing .(var_to_diff)
470
+ is_reducible = trues (length (var_to_diff))
462
471
for v in irreducibles
463
- is_not_potential_state[v] = false
472
+ is_linear_variables[v] = false
473
+ is_reducible[v] = false
464
474
end
465
- is_linear_variables = only_algebraic ? copy (is_not_potential_state) :
466
- is_not_potential_state
467
475
for i in 𝑠vertices (graph)
468
476
is_linear_equations[i] && continue
469
477
for j in 𝑠neighbors (graph, i)
@@ -481,12 +489,10 @@ function aag_bareiss!(graph, var_to_diff, mm_orig::SparseMatrixCLIL, only_algebr
481
489
r != = nothing && return r
482
490
rank1 = k - 1
483
491
end
484
- if only_algebraic
485
- if rank2 === nothing
486
- r = find_masked_pivot (is_not_potential_state, M, k)
487
- r != = nothing && return r
488
- rank2 = k - 1
489
- end
492
+ if rank2 === nothing
493
+ r = find_masked_pivot (is_reducible, M, k)
494
+ r != = nothing && return r
495
+ rank2 = k - 1
490
496
end
491
497
# TODO : It would be better to sort the variables by
492
498
# derivative order here to enable more elimination
@@ -524,25 +530,9 @@ function lss(mm, pivots, ag)
524
530
end
525
531
end
526
532
527
- function simple_aliases! (ag, graph, var_to_diff, mm_orig, only_algebraic, irreducibles = ())
528
- # Let `m = the number of linear equations` and `n = the number of
529
- # variables`.
530
- #
531
- # `do_bareiss` conceptually gives us this system:
532
- # rank1 | [ M₁₁ M₁₂ | M₁₃ ] [v₁] = [0]
533
- # rank2 | [ 0 M₂₂ | M₂₃ ] P [v₂] = [0]
534
- # -------------------|-------------------
535
- # [ 0 0 | 0 ] [v₃] = [0]
536
-
537
- # Where `v₁` are the purely linear algebraic variables (i.e. those that only
538
- # appear in linear algebraic equations), `v₂` are the variables that may be
539
- # potentially solved by the linear system, and `v₃` are the variables that
540
- # contribute to the equations, but are not solved by the linear system. Note
541
- # that the complete system may be larger than the linear subsystem and
542
- # include variables that do not appear here.
533
+ function simple_aliases! (ag, graph, var_to_diff, mm_orig, irreducibles = ())
543
534
mm, solvable_variables, (rank1, rank2, rank3, pivots) = aag_bareiss! (graph, var_to_diff,
544
535
mm_orig,
545
- only_algebraic,
546
536
irreducibles)
547
537
548
538
# Step 2: Simplify the system using the Bareiss factorization
@@ -585,7 +575,7 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
585
575
#
586
576
nvars = ndsts (graph)
587
577
ag = AliasGraph (nvars)
588
- mm = simple_aliases! (ag, graph, var_to_diff, mm_orig, false )
578
+ mm = simple_aliases! (ag, graph, var_to_diff, mm_orig)
589
579
590
580
# Step 3: Handle differentiated variables
591
581
# At this point, `var_to_diff` and `ag` form a tree structure like the
@@ -694,7 +684,7 @@ function alias_eliminate_graph!(graph, var_to_diff, mm_orig::SparseMatrixCLIL)
694
684
if ! isempty (irreducibles)
695
685
ag = newag
696
686
mm_orig2 = isempty (ag) ? mm_orig : reduce! (copy (mm_orig), ag)
697
- mm = simple_aliases! (ag, graph, var_to_diff, mm_orig2, true , irreducibles)
687
+ mm = simple_aliases! (ag, graph, var_to_diff, mm_orig2, irreducibles)
698
688
end
699
689
700
690
# for (v, (c, a)) in ag
0 commit comments