int main(int argc, char **argv) { MPI_Init(&argc, &argv); libmrc_params_init(argc, argv); struct vector *vec = vector_create(MPI_COMM_WORLD); vector_set_from_options(vec); vector_setup(vec); vector_view(vec); int nr_elements; vector_get_param_int(vec, "nr_elements", &nr_elements); for (int i = 0; i < nr_elements; i++) { vector_set_element(vec, i, 2. * i); } for (int i = 0; i < nr_elements; i++) { assert(vector_get_element(vec, i) == 2. * i); } vector_destroy(vec); MPI_Finalize(); }
/* extract row i of a matrix into a vector */ void matrix_get_row(mat *M, int i, vec *row_vec){ int j; #pragma omp parallel shared(row_vec,M,i) private(j) { #pragma omp parallel for for(j=0; j<M->ncols; j++){ vector_set_element(row_vec,j,matrix_get_element(M,i,j)); } } }
/* extract column of a matrix into a vector */ void matrix_get_col(mat *M, int j, vec *column_vec){ int i; #pragma omp parallel shared(column_vec,M,j) private(i) { #pragma omp parallel for for(i=0; i<M->nrows; i++){ vector_set_element(column_vec,i,matrix_get_element(M,i,j)); } } }
void compute_matrix_column_norms(mat *M, vec *column_norms){ int j; #pragma omp parallel shared(column_norms,M) private(j) { #pragma omp parallel for for(j=0; j<(M->ncols); j++){ vector_set_element(column_norms,j, get_matrix_column_norm_squared(M,j)); } } }
void lp_sol_init(LP* lp) { mpq_t* q; int i; for (i = 0; i < lp->vars; i ++) { lp->is_basis[i] = FALSE; if (is_const_var(lp, i)) continue; if (lp->lower.is_valid[i] && lp->upper.is_valid[i]) { q = vector_get_element_ptr(lp->c, i); if (mpq_sgn(*q) > 0) vector_set_element(lp->x, lp->upper.bound[i], i); else vector_set_element(lp->x, lp->lower.bound[i], i); } if (lp->lower.is_valid[i]) { vector_set_element(lp->x, lp->lower.bound[i], i); } else if (lp->upper.is_valid[i]) { vector_set_element(lp->x, lp->upper.bound[i], i); } } }
void eta_file_btran(eta_file* ef, EXLPvector* c, EXLPvector* y) { /* yB = c を解く. */ eta_matrix* U; mpq_t q; int i; U = my_malloc(sizeof(eta_matrix)); vector_copy(y, c); mpq_init(q); vector_permutate(ef->R, y); for (i = 0; i < ef->U->columns; i ++) { U->eta_column = i; U->eta_vector = ef->U->column[i]; eta_matrix_solve_yE_is_equal_to_v(U, y); } vector_permutate(ef->Q, y); for (i = ef->s-1; i >= 0; i --) { if (ef->Ls[i]->row == ef->Ls[i]->column) { vector_mul_element(y, ef->Ls[i]->value, ef->Ls[i]->row); } else { vector_get_element(&q, y, ef->Ls[i]->row); mympq_mul(q, q, ef->Ls[i]->value); vector_add_element(y, q, ef->Ls[i]->column); } } for (i = ef->U->columns-1; i >= 0; i --) { if (ef->L[i]->eta_vector->nonzeros == 1) { vector_mul_element(y, ef->L[i]->eta_vector->value[0], i); } else { vector_inner_product(&q, y, ef->L[i]->eta_vector); vector_set_element(y, q, i); } vector_swap_elements(y, i, ef->P[i]); } mpq_clear(q); free(U); }
/* output = input[inds] */ void fill_vector_from_row_list(vec *input, vec *inds, vec *output){ int i,col_num; for(i=0; i<(input->nrows); i++){ vector_set_element(output,i,vector_get_element(input,vector_get_element(inds,i))); } }
void lp_add_artificials(LP* lp) { mpq_t q1, q2, q3, best; char buf[LP_NAME_LEN_MAX]; int i, j, k, l, m, x, best_var; mpq_init(q1); mpq_init(q2); mpq_init(q3); mpq_init(best); vector_zero_clear(lp->c); vector_zero_clear(lp->cb); x = lp_select_basis(lp); for (i = 0; i < lp->rows; i ++) { if (lp->basis_column[i] != -1) continue; get_valid_rhs(&q1, lp, i); if (mpq_sgn(q1) < 0) { matrix_rev_row_sgn(lp->A, i); vector_rev_element_sgn(lp->b, i); mpq_neg(q1, q1); } best_var = -1; for (m = 0; m < lp->A->row[i]->nonzeros; m ++) { j = lp->A->row[i]->i[m]; if (!is_normal_var(lp, j) || lp->is_basis[j] || lp->A->column[j]->nonzeros == 0) continue; if (vector_get_first_nonzero_i(lp->A->column[j]) != i) continue; if (mpq_sgn(*vector_get_element_ptr(lp->x, j))) continue; mympq_div(q2, q1, *vector_get_element_ptr(lp->A->column[j], i)); if ((lp->upper.is_valid[j] && mpq_cmp(lp->upper.bound[j], q2) < 0) || (lp->lower.is_valid[j] && mpq_cmp(lp->lower.bound[j], q2) > 0)) continue; if (mpq_sgn(q2)) { l = 0; for (k = 0; k < lp->A->column[j]->nonzeros; k ++) { if (lp->basis_column[lp->A->column[j]->i[k]] == -1 || lp->A->column[j]->i[k] == i) continue; l = 1; break; } if (l) continue; } vector_get_element(&q3, lp->c_back, j); mympq_mul(q3, q3, q2); //if (!lp->maximize) // mpq_neg(q3, q3); if (best_var >= 0 && mpq_cmp(best, q3) >= 0) continue; best_var = j; mpq_set(best, q3); } if (best_var < 0) continue; x ++; j = best_var; mympq_div(q2, q1, *vector_get_element_ptr(lp->A->column[j], vector_get_first_nonzero_i(lp->A->column[j]))); lp->is_basis[j] = TRUE; lp->basis_column[i] = j; vector_set_element(lp->x, q2, j); vector_set_element(lp->xb, q2, i); } matrix_resize(lp->A, lp->rows, lp->vars + lp->rows - x); for (i = 0; i < lp->rows; i ++) { if (lp->basis_column[i] >= 0) continue; get_valid_rhs(&q1, lp, i); if(lp->var_name == NULL) j = lp_add_var_without_A(lp, NULL); else { strncpy(buf, "#A", LP_NAME_LEN_MAX); strncat(buf, lp->row_name[i], LP_NAME_LEN_MAX); j = lp_add_var_without_A(lp, buf); } lp_add_slackref(lp, -(i+1)); lp->var_type[j] = LP_VAR_TYPE_ARTIFICIAL; lp->basis_column[i] = j; lp->is_basis[j] = TRUE; lp_set_coefficient(lp, mympq_one, i, j); vector_set_element(lp->x, q1, j); vector_set_element(lp->xb, q1, i); vector_set_element(lp->c, mympq_minus_one, j); vector_set_element(lp->cb, mympq_minus_one, i); } #if 0 lp->vars = MIN(lp->vars, lp->A->columns); #endif mpq_clear(q1); mpq_clear(q2); mpq_clear(q3); mpq_clear(best); }
void lp_sol_init_dual(LP* lp) { mpq_t q1, q2; mpq_t* q3; EXLPvector* v1; EXLPvector* v2; int i, j, k; if (lp->preprocess < 2) { mpq_init(q1); //mpq_set_si(q1, 1, 10000); for (i = 0; i < lp->vars; i ++) { if (is_const_var(lp, i)) continue; mpq_set_si(q1, i, lp->vars*lp->vars*lp->vars*lp->vars); if (lp->lower.is_valid[i] && lp->upper.is_valid[i]) { q3 = vector_get_element_ptr(lp->c, i); if (mpq_sgn(*q3) > 0) { vector_set_element(lp->x, lp->upper.bound[i], i); if (lp->is_basis[i]) { vector_sub_element(lp->x, q1, i); if (mpq_cmp(*vector_get_element_ptr(lp->x, i), lp->lower.bound[i]) < 0) vector_add_element(lp->x, q1, i); } } else { vector_set_element(lp->x, lp->lower.bound[i], i); if (lp->is_basis[i]) { vector_add_element(lp->x, q1, i); if (mpq_cmp(*vector_get_element_ptr(lp->x, i), lp->upper.bound[i]) > 0) vector_sub_element(lp->x, q1, i); } } } if (lp->lower.is_valid[i]) { vector_set_element(lp->x, lp->lower.bound[i], i); if (lp->is_basis[i]) vector_add_element(lp->x, q1, i); } else if (lp->upper.is_valid[i]) { vector_set_element(lp->x, lp->upper.bound[i], i); if (lp->is_basis[i]) vector_sub_element(lp->x, q1, i); } } mpq_clear(q1); for (i = 0; i < lp->rows; i ++) { vector_set_element(lp->xb, *vector_get_element_ptr(lp->x, lp->basis_column[i]), i); } } else { reinversion(lp); mpq_init(q1); mpq_init(q2); v1 = new_vector(lp->rows); v2 = new_vector(lp->vars); eta_file_btran(lp->eta, lp->cb, v1); vector_copy(v2, lp->c); for (i = 0; i < lp->vars; i ++) { if (lp->is_basis[i] || is_const_var(lp, i)) continue; vector_inner_product(&q1, v1, lp->A->column[i]); vector_sub_element(v2, q1, i); } for (i = 0; i < lp->vars; i ++) { if (is_const_var(lp, i) || lp->is_basis[i]) continue; if (lp->lower.is_valid[i] && lp->upper.is_valid[i]) { q3 = vector_get_element_ptr(v2, i); if (mpq_sgn(*q3) > 0) vector_set_element(lp->x, lp->upper.bound[i], i); else vector_set_element(lp->x, lp->lower.bound[i], i); } else if (lp->lower.is_valid[i]) { vector_set_element(lp->x, lp->lower.bound[i], i); } else if (lp->upper.is_valid[i]) { vector_set_element(lp->x, lp->upper.bound[i], i); } } vector_resize(v2, lp->rows); vector_copy(v1, lp->b); for (i = 0; i < lp->rows; i ++) { mpq_set_si(q1, 0, 1); for (j = 0; j < lp->A->row[i]->nonzeros; j ++) { k = lp->A->row[i]->i[j]; if (is_const_var(lp, k) || lp->is_basis[k]) continue; mympq_mul(q2, *matrix_get_element_ptr(lp->A, i, k), *vector_get_element_ptr(lp->x, k)); mympq_add(q1, q1, q2); } vector_sub_element(v1, q1, i); } eta_file_ftran(lp->eta, v1, v2, NULL); //mpq_set_si(q1, 1, 10000); mpq_set_si(q1, i, lp->vars*lp->vars*lp->vars*lp->vars); for (i = 0; i < lp->rows; i ++) { k = lp->basis_column[i]; q3 = vector_get_element_ptr(v2, i); //mpq_set_si(q1, 1, 100000);mympq_mul(q1, q1, *q3); if (lp->lower.is_valid[k] && mpq_cmp(*q3, lp->lower.bound[k]) <= 0) { vector_set_element(lp->x, lp->lower.bound[k], k); vector_set_element(lp->xb, lp->lower.bound[k], i); vector_add_element(lp->x, q1, k); vector_add_element(lp->xb, q1, i); if (lp->upper.is_valid[k] && mpq_cmp(lp->upper.bound[k], *vector_get_element_ptr(lp->x, k)) < 0) { vector_sub_element(lp->x, q1, k); vector_sub_element(lp->xb, q1, i); } continue; } if (lp->upper.is_valid[k] && mpq_cmp(*q3, lp->upper.bound[k]) >= 0) { vector_set_element(lp->x, lp->upper.bound[k], k); vector_set_element(lp->xb, lp->upper.bound[k], i); vector_sub_element(lp->x, q1, k); vector_sub_element(lp->xb, q1, i); if (lp->lower.is_valid[k] && mpq_cmp(lp->lower.bound[k], *vector_get_element_ptr(lp->x, k)) > 0) { vector_add_element(lp->x, q1, k); vector_add_element(lp->xb, q1, i); } continue; } vector_set_element(lp->x, *q3, k); vector_set_element(lp->xb, *q3, i); } mpq_clear(q1); mpq_clear(q2); vector_free(&v1); vector_free(&v2); } }
void lp_set_rhs(LP* lp, int row, mpq_t q) { if (0 <= row && row < lp->b->dimension) vector_set_element(lp->b, q, row); }
void lp_set_coefficient(LP* lp, mpq_t c, int row, int var) { if (row == lp->rows) vector_set_element(lp->c, c, var); else matrix_set_element(lp->A, c, row, var); }