1
+ struct FreeLinearSingletonColumn{T, S} <: PresolveOperation{T, S}
2
+ i:: Int
3
+ j:: Int
4
+ aij:: T
5
+ arowi:: Row{T}
6
+ yi:: T
7
+ conival:: T
8
+ end
9
+
10
+ function free_linear_singleton_columns! (
11
+ operations:: Vector{PresolveOperation{T, S}} ,
12
+ hcols:: Vector{Col{T}} ,
13
+ arows:: Vector{Row{T}} ,
14
+ acols:: Vector{Col{T}} ,
15
+ c:: AbstractVector{T} ,
16
+ c0:: T ,
17
+ lcon:: AbstractVector{T} ,
18
+ ucon:: AbstractVector{T} ,
19
+ lvar:: AbstractVector{T} ,
20
+ uvar:: AbstractVector{T} ,
21
+ nvar,
22
+ row_cnt,
23
+ col_cnt,
24
+ kept_rows,
25
+ kept_cols,
26
+ ) where {T, S}
27
+ free_lsc_pass = false
28
+ c0_offset = zero (T)
29
+
30
+ for j= 1 : nvar
31
+ (kept_cols[j] && (col_cnt[j] == 1 )) || continue
32
+ # check infinity bounds and no hessian contribution
33
+ if lvar[j] == - T (Inf ) && uvar[j] == T (Inf ) && isempty (hcols[j]. nzind)
34
+ # find i the row index of the singleton column j, and Aij
35
+ Aij = T (Inf )
36
+ colj = acols[j]
37
+ k = 1
38
+ i = colj. nzind[k]
39
+ while ! (kept_rows[i])
40
+ k += 1
41
+ i = colj. nzind[k]
42
+ end
43
+ Aij = colj. nzval[k]
44
+
45
+ yi = c[j] / Aij
46
+ nzcj = c[j] != zero (T)
47
+ if yi < zero (T)
48
+ lcon[i] = ucon[i]
49
+ elseif yi > zero (T)
50
+ ucon[i] = lcon[i]
51
+ end
52
+ if abs (Aij) > sqrt (eps (T))
53
+ nzcj && (c0_offset += yi * ucon[i]) # update c0
54
+ nb_elem_i = row_cnt[i] - 1
55
+ rowi = arows[i] # i-th row
56
+ # new row to store for postsolve:
57
+ rowi2 = Row (zeros (Int, nb_elem_i), zeros (T, nb_elem_i))
58
+ c_i = 1
59
+ for k in 1 : length (rowi. nzind)
60
+ j2 = rowi. nzind[k]
61
+ # add all col elements to rowi2 except the col j2 == j
62
+ if kept_cols[j2] && j2 != j
63
+ rowi2. nzind[c_i] = j2
64
+ Aij2 = rowi. nzval[k]
65
+ rowi2. nzval[c_i] = Aij2
66
+ nzcj && (c[j2] -= yi * Aij2) # update c if c[j] != 0
67
+ col_cnt[j2] -= 1
68
+ c_i += 1
69
+ end
70
+ end
71
+ conival = nzcj ? ucon[i] : (lcon[i] + ucon[i]) / 2 # constant for postsolve
72
+ push! (operations, FreeLinearSingletonColumn {T, S} (i, j, Aij, rowi2, yi, conival))
73
+ kept_cols[j] = false
74
+ col_cnt[j] = - 1
75
+ kept_rows[i] = false
76
+ row_cnt[i] = - 1
77
+ free_lsc_pass = true
78
+ end
79
+ end
80
+ end
81
+ return free_lsc_pass, c0 + c0_offset
82
+ end
83
+
84
+ function postsolve! (pt:: OutputPoint{T, S} , operation:: FreeLinearSingletonColumn{T, S} ) where {T, S}
85
+ x = pt. x
86
+ j = operation. j
87
+ # x[j] = (coival - Σₖ Aik x[k]) / Aij , where k ≂̸ j
88
+ x[j] = operation. conival
89
+ for (i, Aij) in zip (operation. arowi. nzind, operation. arowi. nzval)
90
+ x[j] -= Aij * x[i]
91
+ end
92
+ x[j] /= operation. aij
93
+ pt. s_l[j] = zero (T)
94
+ pt. s_u[j] = zero (T)
95
+ pt. y[operation. i] = operation. yi
96
+ end
0 commit comments