@@ -53,7 +53,7 @@ def build_sparse_matrix(pairs,rat,alg,qua,div_lead):
5353 index += 1
5454
5555 if r [6 ]& 1 : line .append (index )
56- matrix .append (line )
56+ matrix .append (set ( line ) )
5757 return matrix
5858
5959# Reduce the sparse matrix, according to various rules:
@@ -64,42 +64,69 @@ def reduce_sparse_matrix(matrix, pairs):
6464 flag = True
6565 while flag :
6666 flag = False
67- i = 0
68- while i < len (matrix ):
69- if len (matrix [i ]) == 1 :
70- flag = True
71- coeff = matrix [i ][0 ]
72- for j in range (len (matrix )):
73- if j != i :
74- stored = - 1
75- for z in range (len (matrix [j ])):
76- if matrix [j ][z ] == coeff : stored = z
77- elif matrix [j ][z ] > coeff : matrix [j ][z ] -= 1
78- if stored > - 1 : del matrix [j ][stored ]
79- del pairs [coeff ]
80- del matrix [i ]
81- else : i += 1
82- i = 0
83- while i < len (matrix ):
84- if matrix [i ] == []:
85- del matrix [i ]
86- flag = True
87- else : i += 1
88- 89- length = len (matrix )+ 10
90- pairs = pairs [:length ]
91- 92- for i in range (len (matrix )):
93- if matrix [i ][0 ] >= length :
94- flag = True
95- matrix [i ] = []
67+ 68+ singleton_queue = [index for index , row in enumerate (matrix ) if len (row ) == 1 ]
69+ active_cols = set (range (len (pairs )))
70+ 71+ flag = len (singleton_queue )
72+ 73+ while singleton_queue :
74+ index = singleton_queue .pop ()
75+ 76+ if len (matrix [index ]) != 1 : continue
77+ coeff = next (iter (matrix [index ]))
78+ 79+ for j , row in enumerate (matrix ):
80+ if j != index and coeff in row :
81+ row .remove (coeff )
82+ if len (row ) == 1 : singleton_queue .append (j )
83+ 84+ matrix [index ].clear ()
85+ active_cols .discard (coeff )
86+ 87+ matrix = [row for row in matrix if row ]
88+ 89+ pairs = [pairs [index ] for index in sorted (active_cols )]
90+ 91+ mapping = {old : new for new , old in enumerate (sorted (active_cols ))}
92+ matrix = [{mapping [c ] for c in row if c in mapping } for row in matrix ]
93+ 94+ active_cols = set (range (len (pairs )))
95+ target_n_cols = len (matrix )+ 10
96+ to_delete = len (pairs ) - target_n_cols
97+ current_len_row = 2
98+ 99+ while to_delete >= current_len_row - 1 :
100+ 101+ index = - 1
102+ for i in range (len (matrix )):
103+ if len (matrix [i ]) == current_len_row :
104+ flag = True
105+ index = i
106+ break
107+ 108+ if index != - 1 :
109+ for coeff in matrix [index ]:
110+ active_cols .discard (coeff )
111+ 112+ for j , row in enumerate (matrix ):
113+ if j != index and coeff in row :
114+ row .discard (coeff )
115+ 116+ to_delete -= current_len_row - 1
117+ 118+ matrix [index ].clear ()
119+ 96120 else :
97- for j in range (len (matrix [i ])):
98- if matrix [i ][- j - 1 ] < length :
99- if j > 0 :
100- flag = True
101- matrix [i ] = matrix [i ][:len (matrix [i ])- j ]
102- break
121+ current_len_row += 1
122+ 123+ matrix = [row for row in matrix if row ]
124+ 125+ pairs = [pairs [index ] for index in sorted (active_cols )]
126+ 127+ mapping = {old : new for new , old in enumerate (sorted (active_cols ))}
128+ matrix = [{mapping [c ] for c in row if c in mapping } for row in matrix ]
129+ 103130 return matrix , pairs
104131
105132def reduce_matrix (matrix ,pairs ):
0 commit comments