950{
951
952
953 IndexType k ;
954 IndexType pivot_col ;
955 IndexType *cp ;
956 IndexType *rp ;
957 IndexType pivot_row ;
958 IndexType *new_cp ;
959 IndexType *new_rp ;
960 IndexType pivot_row_start ;
961 IndexType pivot_row_degree ;
962 IndexType pivot_row_length ;
963 IndexType pivot_col_score ;
964 IndexType needed_memory ;
965 IndexType *cp_end ;
966 IndexType *rp_end ;
969 IndexType max_score ;
970 IndexType cur_score ;
971 unsigned int hash ;
972 IndexType head_column ;
973 IndexType first_col ;
974 IndexType tag_mark ;
975 IndexType row_mark ;
976 IndexType set_difference ;
977 IndexType min_score ;
978 IndexType col_thickness ;
979 IndexType max_mark ;
980 IndexType pivot_col_thickness ;
981 IndexType prev_col ;
982 IndexType next_col ;
983 IndexType ngarbage ;
984
985
986
987
988 max_mark = INT_MAX - n_col ;
989 tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
990 min_score = 0 ;
991 ngarbage = 0 ;
993
994
995
996 for (k = 0 ; k < n_col2 ; )
997 {
998
999
1000
1001
1005
1006
1008 {
1009 min_score++ ;
1010 }
1011 pivot_col =
head [min_score] ;
1013 next_col = Col [pivot_col].
shared4.degree_next ;
1014 head [min_score] = next_col ;
1016 {
1018 }
1019
1022
1023
1024 pivot_col_score = Col [pivot_col].
shared2.score ;
1025
1026
1027 Col [pivot_col].
shared2.order = k ;
1028
1029
1030 pivot_col_thickness = Col [pivot_col].
shared1.thickness ;
1031 k += pivot_col_thickness ;
1033
1034
1035
1036 needed_memory = numext::mini(pivot_col_score, n_col - k) ;
1037 if (pfree + needed_memory >= Alen)
1038 {
1039 pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ;
1040 ngarbage++ ;
1041
1043
1044 tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
1045
1046 }
1047
1048
1049
1050
1051 pivot_row_start = pfree ;
1052
1053
1054 pivot_row_degree = 0 ;
1055
1056
1057
1058 Col [pivot_col].
shared1.thickness = -pivot_col_thickness ;
1059
1060
1061 cp = &A [Col [pivot_col].
start] ;
1062 cp_end = cp + Col [pivot_col].
length ;
1063 while (cp < cp_end)
1064 {
1065
1068
1070 {
1071 continue ;
1072 }
1074 rp_end = rp + Row [
row].length ;
1075 while (rp < rp_end)
1076 {
1077
1079
1080 col_thickness = Col [
col].shared1.thickness ;
1082 {
1083
1084 Col [
col].shared1.thickness = -col_thickness ;
1086
1088 pivot_row_degree += col_thickness ;
1089 }
1090 }
1091 }
1092
1093
1094 Col [pivot_col].shared1.thickness = pivot_col_thickness ;
1095 max_deg = numext::maxi(max_deg, pivot_row_degree) ;
1096
1097
1098
1099
1100
1101 cp = &A [Col [pivot_col].start] ;
1102 cp_end = cp + Col [pivot_col].length ;
1103 while (cp < cp_end)
1104 {
1105
1109 }
1110
1111
1112
1113 pivot_row_length = pfree - pivot_row_start ;
1114 if (pivot_row_length > 0)
1115 {
1116
1117 pivot_row = A [Col [pivot_col].start] ;
1119 }
1120 else
1121 {
1122
1125 }
1126 COLAMD_ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ;
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 COLAMD_DEBUG3 ((
"** Computing set differences phase. **\n")) ;
1150
1151
1152
1154
1155 rp = &A [pivot_row_start] ;
1156 rp_end = rp + pivot_row_length ;
1157 while (rp < rp_end)
1158 {
1162
1163
1164 col_thickness = -Col [
col].shared1.thickness ;
1166 Col [
col].shared1.thickness = col_thickness ;
1167
1168
1169
1170 cur_score = Col [
col].shared2.score ;
1171 prev_col = Col [
col].shared3.prev ;
1172 next_col = Col [
col].shared4.degree_next ;
1177 {
1178 head [cur_score] = next_col ;
1179 }
1180 else
1181 {
1182 Col [prev_col].shared4.degree_next = next_col ;
1183 }
1185 {
1186 Col [next_col].shared3.prev = prev_col ;
1187 }
1188
1189
1190
1191 cp = &A [Col [
col].start] ;
1192 cp_end = cp + Col [
col].length ;
1193 while (cp < cp_end)
1194 {
1195
1197 row_mark = Row [
row].shared2.mark ;
1198
1200 {
1201 continue ;
1202 }
1204 set_difference = row_mark - tag_mark ;
1205
1206 if (set_difference < 0)
1207 {
1209 set_difference = Row [
row].shared1.degree ;
1210 }
1211
1212 set_difference -= col_thickness ;
1214
1215 if (set_difference == 0)
1216 {
1219 }
1220 else
1221 {
1222
1223 Row [
row].shared2.mark = set_difference + tag_mark ;
1224 }
1225 }
1226 }
1227
1228
1229
1230
1232
1233
1234 rp = &A [pivot_row_start] ;
1235 rp_end = rp + pivot_row_length ;
1236 while (rp < rp_end)
1237 {
1238
1241 hash = 0 ;
1242 cur_score = 0 ;
1243 cp = &A [Col [
col].start] ;
1244
1245 new_cp = cp ;
1246 cp_end = cp + Col [
col].length ;
1247
1249
1250 while (cp < cp_end)
1251 {
1252
1255 row_mark = Row [
row].shared2.mark ;
1256
1258 {
1259 continue ;
1260 }
1262
1264
1266
1267 cur_score += row_mark - tag_mark ;
1268
1269 cur_score = numext::mini(cur_score, n_col) ;
1270 }
1271
1272
1273 Col [
col].length = (IndexType) (new_cp - &A [Col [
col].start]) ;
1274
1275
1276
1277 if (Col [
col].length == 0)
1278 {
1280
1282 pivot_row_degree -= Col [
col].shared1.thickness ;
1284
1285 Col [
col].shared2.order = k ;
1286
1287 k += Col [
col].shared1.thickness ;
1288 }
1289 else
1290 {
1291
1292
1294
1295
1296 Col [
col].shared2.score = cur_score ;
1297
1298
1299 hash %= n_col + 1 ;
1300
1301 COLAMD_DEBUG4 ((
" Hash = %d, n_col = %d.\n", hash, n_col)) ;
1303
1304 head_column =
head [hash] ;
1306 {
1307
1308
1309 first_col = Col [head_column].shared3.headhash ;
1310 Col [head_column].shared3.headhash =
col ;
1311 }
1312 else
1313 {
1314
1315 first_col = - (head_column + 2) ;
1317 }
1318 Col [
col].shared4.hash_next = first_col ;
1319
1320
1321 Col [
col].shared3.hash = (IndexType) hash ;
1323 }
1324 }
1325
1326
1327
1328
1329
1331
1332 Eigen::internal::detect_super_cols (Col, A,
head, pivot_row_start, pivot_row_length) ;
1333
1334
1335
1337
1338
1339
1340 tag_mark += (max_deg + 1) ;
1341 if (tag_mark >= max_mark)
1342 {
1344 tag_mark = Eigen::internal::clear_mark (n_row, Row) ;
1345 }
1346
1347
1348
1350
1351
1352 rp = &A [pivot_row_start] ;
1353
1354 new_rp = rp ;
1355 rp_end = rp + pivot_row_length ;
1356 while (rp < rp_end)
1357 {
1359
1361 {
1362 continue ;
1363 }
1365
1366 A [Col [
col].start + (Col [
col].length++)] = pivot_row ;
1367
1368
1369
1370
1371 cur_score = Col [
col].shared2.score + pivot_row_degree ;
1372
1373
1374
1375
1376 max_score = n_col - k - Col [
col].shared1.thickness ;
1377
1378
1379 cur_score -= Col [
col].shared1.thickness ;
1380
1381
1382 cur_score = numext::mini(cur_score, max_score) ;
1384
1385
1386 Col [
col].shared2.score = cur_score ;
1387
1388
1389
1395 next_col =
head [cur_score] ;
1396 Col [
col].shared4.degree_next = next_col ;
1399 {
1400 Col [next_col].shared3.prev =
col ;
1401 }
1403
1404
1405 min_score = numext::mini(min_score, cur_score) ;
1406
1407 }
1408
1409
1410
1411 if (pivot_row_degree > 0)
1412 {
1413
1414
1415 Row [pivot_row].start = pivot_row_start ;
1416 Row [pivot_row].length = (IndexType) (new_rp - &A[pivot_row_start]) ;
1417 Row [pivot_row].shared1.degree = pivot_row_degree ;
1418 Row [pivot_row].shared2.mark = 0 ;
1419
1420 }
1421 }
1422
1423
1424
1425 return (ngarbage) ;
1426}
EIGEN_DEVICE_FUNC RowXpr row(Index i)
This is the const version of row(). */.
Definition BlockMethods.h:859
#define ROW_IS_MARKED_DEAD(row_mark)
Definition Eigen_Colamd.h:117
#define COLAMD_DEBUG2(params)
Definition Eigen_Colamd.h:235
#define KILL_PRINCIPAL_COL(c)
Definition Eigen_Colamd.h:123
#define COLAMD_DEBUG3(params)
Definition Eigen_Colamd.h:236
#define COLAMD_DEBUG1(params)
Definition Eigen_Colamd.h:234
#define COLAMD_DEBUG4(params)
Definition Eigen_Colamd.h:237
#define KILL_ROW(r)
Definition Eigen_Colamd.h:122
#define ROW_IS_DEAD(r)
Definition Eigen_Colamd.h:116
union internal::colamd_col::@549 shared1
IndexType start
Definition Eigen_Colamd.h:168
union internal::colamd_col::@550 shared2