void matrix_chain_multiply_order (Matrix *ma[], int len, Matrix *m, Matrix *s) { int i, j, k, l; int q; int n = len; for (i = 1; i <= n; i++) { matrix_set_value (m, i, i, 0); } for (l = 2; l <= n; l++) { for (i = 1; i <= (n - l + 1); i++) { j = (i + l - 1); matrix_set_value (m, i, j, INT_MAX_SENTINEL); for (k = i; k <= (j - 1); k++) { q = matrix_get_value (m, i, k) + matrix_get_value (m, k + 1, j) + matrix_chain_get_dimensions (ma, len, i - 1, k, j); if (q < matrix_get_value (m, i, j)) { matrix_set_value (m, i, j, q); matrix_set_value (s, i, j, k); } } } } }
void matrix_set_values(struct matrix* m, struct symbol* symbols) { int i, j; for (i=0; i < m->dim1; i++) { for (j=0; j < m->dim2; j++) { if (symbols != NULL) { matrix_set_value(m, i, j, symbols->v.float_val); symbols = symbols->next; } } } }
bool sign_matrix(M& matrix, submatrix_indices* violator) { bool result = true; matrix_permuted <M> permuted(matrix); size_t handled_rows = 0; /// Go trough column by column. for (size_t handled_columns = 0; handled_columns < permuted.size2(); ++handled_columns) { if (find_nonzero_column(permuted, handled_columns, permuted.size2(), 0, handled_rows, handled_columns)) { /// There is a non-zero column right of the already-handled submatrix. std::set <size_t> start_nodes; std::set <size_t> end_nodes; std::set <size_t> all_nodes; bipartite_graph_dimensions dim(handled_rows, handled_columns); for (size_t row = 0; row < handled_rows; ++row) { if (permuted(row, handled_columns) != 0) { size_t index = dim.row_to_index(row); if (start_nodes.empty()) start_nodes.insert(index); else end_nodes.insert(index); all_nodes.insert(index); } } /// Start a BFS on bipartite graph of the submatrix and look for shortest paths from first 1 to all others std::vector <bipartite_graph_bfs_node> bfs_result; if (!bipartite_graph_bfs(permuted, dim, start_nodes, end_nodes, true, bfs_result)) throw std::logic_error("Signing procedure: Did not reach all nodes via bfs!"); /// Evaluate matrix-entries on the shortest paths std::map <size_t, bool> changes; for (typename std::set <size_t>::const_iterator iter = end_nodes.begin(); iter != end_nodes.end(); ++iter) { check_sign(permuted, bfs_result, dim, all_nodes, *iter, handled_columns, changes); } /// Checking changes for (std::map <size_t, bool>::iterator iter = changes.begin(); iter != changes.end(); ++iter) { if (!iter->second) continue; if (boost::is_const <M>::value) { if (violator) { /// Find the violator, going along the path std::set <size_t> violator_rows, violator_columns; size_t index = iter->first; do { if (dim.is_row(index)) violator_rows.insert(permuted.perm1()(dim.index_to_row(index))); else violator_columns.insert(permuted.perm2()(dim.index_to_column(index))); index = bfs_result[index].predecessor; } while (all_nodes.find(index) == all_nodes.end()); violator_rows.insert(permuted.perm1()(dim.index_to_row(index))); violator_columns.insert(permuted.perm2()(handled_columns)); /// Fill violator data violator->rows = submatrix_indices::indirect_array_type(violator_rows.size()); violator->columns = submatrix_indices::indirect_array_type(violator_columns.size()); size_t i = 0; for (std::set <size_t>::const_iterator iter = violator_rows.begin(); iter != violator_rows.end(); ++iter) violator->rows[i++] = *iter; i = 0; for (std::set <size_t>::const_iterator iter = violator_columns.begin(); iter != violator_columns.end(); ++iter) violator->columns[i++] = *iter; } return false; } else { /// We are not just testing, so swap the sign on a one. size_t real_row = permuted.perm1()(dim.index_to_row(iter->first)); size_t real_column = permuted.perm2()(handled_columns); matrix_set_value(matrix, real_row, real_column, -matrix(real_row, real_column)); result = false; } } matrix_reorder_rows(permuted, handled_rows, permuted.size1(), handled_columns, permuted.size2(), abs_greater <int> ()); /// Augment submatrix by rows with 1 in the new column. while (handled_rows < permuted.size1()) { if (permuted(handled_rows, handled_columns) == 0) break; else ++handled_rows; } } else { /// Handled upper-left submatrix and lower-right submatrix are disconnected for (size_t column = handled_columns; column < permuted.size2(); ++column) { size_t count = 0; for (size_t row = handled_rows; row < permuted.size1(); ++row) { if (permuted(row, column) != 0) ++count; } /// A zero column can be skipped, as it is handled by definition. if (count > 0) { /// Found a nonzero column and swap ones to the top. matrix_reorder_rows(permuted, handled_rows, permuted.size1(), handled_columns, permuted.size2(), abs_greater <int> ()); while (handled_rows < permuted.size1()) { if (permuted(handled_rows, handled_columns) == 0) break; else ++handled_rows; } break; } } } } return result; }