int bool_mat_is_transitive(const bool_mat_t mat) { slong n, i, j, k; if (!bool_mat_is_square(mat)) { flint_printf("bool_mat_is_transitive: a square matrix is required!\n"); abort(); } if (bool_mat_is_empty(mat)) return 1; n = bool_mat_nrows(mat); for (i = 0; i < n; i++) for (j = 0; j < n; j++) for (k = 0; k < n; k++) if (bool_mat_get_entry(mat, i, j) && bool_mat_get_entry(mat, j, k) && !bool_mat_get_entry(mat, i, k)) { return 0; } return 1; }
void _bool_mat_permute(bool_mat_t B, const bool_mat_t A, const slong *perm) { slong n, i, j; if (!bool_mat_is_square(A)) abort(); /* assert */ if (A == B) abort(); /* assert */ n = bool_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { bool_mat_set_entry( B, perm[i], perm[j], bool_mat_get_entry(A, i, j)); } } }
/* following Tarjan */ slong bool_mat_get_strongly_connected_components(slong *partition, const bool_mat_t A) { slong i, n, result; _tarjan_t t; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_get_strongly_connected_components: " "a square matrix is required!\n"); flint_abort(); } if (bool_mat_is_empty(A)) return 0; n = bool_mat_nrows(A); if (n == 1) { partition[0] = 0; return 1; } _tarjan_init(t, n); for (i = 0; i < n; i++) { partition[i] = _tarjan_UNDEFINED; } for (i = 0; i < n; i++) { if (*_tarjan_index(t, i) == _tarjan_UNDEFINED) { _tarjan_strongconnect(partition, t, A, i); } } result = t->nsccs; _tarjan_clear(t); return result; }
slong bool_mat_nilpotency_degree(const bool_mat_t A) { slong n; if (!bool_mat_is_square(A)) { flint_printf("bool_mat_nilpotency_degree: a square matrix is required!\n"); abort(); } if (bool_mat_is_empty(A)) return 0; n = bool_mat_nrows(A); if (n == 1) { return bool_mat_get_entry(A, 0, 0) ? -1 : 1; } else { _toposort_s s; slong i; int has_cycle; int result; _toposort_init(&s, n); for (has_cycle = 0, i = 0; !has_cycle && i < n; i++) if (!s.v[i]) has_cycle = _toposort_visit(&s, A, i); if (has_cycle) { result = -1; } else { /* Find the length of the longest path within the DAG */ /* http://stackoverflow.com/a/10737524/4072759 */ slong x, y, z; slong max_overall; fmpz_mat_t E; fmpz_mat_init(E, n, n); fmpz_mat_zero(E); max_overall = 0; for (i = n - 1; i >= 0; i--) { slong max_in = 0; y = s.post[i]; for (x = 0; x < n; x++) { max_in = FLINT_MAX(max_in, fmpz_get_si(fmpz_mat_entry(E, x, y))); } for (z = 0; z < n; z++) { if (bool_mat_get_entry(A, y, z)) { fmpz_set_si(fmpz_mat_entry(E, y, z), max_in + 1); max_overall = FLINT_MAX(max_overall, max_in + 1); } } } fmpz_mat_clear(E); result = max_overall + 1; } _toposort_clear(&s); return result; } }