void check_random () { gmp_randstate_ptr rands; mpz_t bs; unsigned long arg_size, size_range; mpq_t q, r; int i; mp_bitcnt_t shift; int reps = 10000; rands = RANDS; mpz_init (bs); mpq_init (q); mpq_init (r); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */ mpz_urandomb (bs, rands, size_range); arg_size = mpz_get_ui (bs); mpz_rrandomb (mpq_numref (q), rands, arg_size); do { mpz_urandomb (bs, rands, size_range); arg_size = mpz_get_ui (bs); mpz_rrandomb (mpq_denref (q), rands, arg_size); } while (mpz_sgn (mpq_denref (q)) == 0); /* We now have a random rational in q, albeit an unnormalised one. The lack of normalisation should not matter here, so let's save the time a gcd would require. */ mpz_urandomb (bs, rands, 32); shift = mpz_get_ui (bs) % 4096; mpq_mul_2exp (r, q, shift); if (mpq_cmp (r, q) < 0) { printf ("mpq_mul_2exp wrong on random\n"); abort (); } mpq_div_2exp (r, r, shift); if (mpq_cmp (r, q) != 0) { printf ("mpq_mul_2exp or mpq_div_2exp wrong on random\n"); abort (); } } mpq_clear (q); mpq_clear (r); mpz_clear (bs); }
void ovm_q_le(oregister_t *l, oregister_t *r) { l->t = t_word; switch (r->t) { case t_void: l->v.w = mpq_sgn(oqr(l)) <= 0; break; case t_word: l->v.w = mpq_cmp_si(oqr(l), r->v.w, 1) <= 0; break; case t_float: l->v.w = mpq_get_d(oqr(l)) <= r->v.d; break; case t_mpz: mpq_set_z(oqr(r), ozr(r)); l->v.w = mpq_cmp(oqr(l), oqr(r)) <= 0; break; case t_rat: mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); l->v.w = mpq_cmp(oqr(l), oqr(r)) <= 0; break; case t_mpq: l->v.w = mpq_cmp(oqr(l), oqr(r)) <= 0; break; case t_mpr: mpfr_set_z(orr(l), ozr(l), thr_rnd); l->v.w = mpfr_lessequal_p(orr(l), orr(r)); break; default: ovm_raise(except_not_a_real_number); } }
//Overloads == to compare two points; they are equal if both the X and Y component are equal bool Point::operator==(const Point& cbRight) { if(mpq_cmp(cbRight.nX, this->nX) == 0 && mpq_cmp(cbRight.nY, this->nY) == 0) { return true; } return false; }
void max(Rational& res, const Rational& op1, const Rational& op2) { if( mpq_cmp(op1.number, op2.number) > 0 ) res = op1; else res = op2; }
static void dumpSkip(mpq_t *t, const symbol_t *scan) { static int initialized = 0; static mpq_t dt; static int de; static int nu; static mpz_t zde; static mpz_t znu; int rnd; if (! initialized) { mpq_init(dt); mpz_init(zde); mpz_init(znu); initialized = 1; } if (mpq_equal(*t, scan->start)) { return; } while (dump_tuplet_current != NO_ID) { /* stop */ fprintf(lily_out, " }"); tuplet_pop(&dump_tuplet_current); } if (mpq_cmp(*t, scan->start) > 0) { fprintf(stderr, "Uh oh -- start time "); mpq_out_str(stderr, 10, scan->start); fprintf(stderr, " is too low, should be "); mpq_out_str(stderr, 10, *t); fprintf(stderr, " -- is my voice analysis correct?\n"); return; } mpq_sub(dt, scan->start, *t); mpq_get_num(znu, dt); mpq_get_den(zde, dt); nu = mpz_get_ui(znu); de = mpz_get_ui(zde); rnd = nu / de; if (rnd != 0) { fprintf(lily_out, " s1*%d", rnd); nu -= rnd * de; } if (! is_two_pow(de)) { fprintf(stderr, "Uh oh -- skip now already a tuplet %d/%d??\n", nu, de); fprintf(lily_out, " s1*%d/%d", nu, de); } else { if (nu != 0) { fprintf(lily_out, " s%d*%d", de, nu); } } last_dumped_symbol = &sym_any_skip; mpq_set(*t, scan->start); VPRINTF(" skip to t = "); VPRINT_MPQ(*t); }
static int rational_cmp( obj a, obj b ) { mpq_t a1, b1; OBJ_TO_MPQ(a1, a); OBJ_TO_MPQ(b1, b); return mpq_cmp(a1, b1); }
gint random_integer_with_probability(mpq_t *p, gint n) { mpz_t *den; den = (mpz_t *)g_malloc(sizeof(mpz_t) * n); int i; for(i = 0; i < n; ++i) { mpz_init(den[i]); mpq_get_den(den[i], p[i]); } mpz_t l; mpz_init(l); lcm(l, den, n); mpq_t nlcm; mpq_init(nlcm); mpq_set_z(nlcm, l); int lc = mpz_get_ui(l); gint x = g_random_int_range(0, lc); mpq_t y; mpq_init(y); mpq_set_si(y, x, 1); mpq_t p_i; mpq_init(p_i); int j = n - 1; for(i = 0; i < n - 1; i++) { mpq_mul(p_i, nlcm, p[i]); if(mpq_cmp(y, p_i) < 0) { j = i; break; } mpq_sub(y, y, p_i); } for(i = 0; i < n; ++i) { mpz_clear(den[i]); } g_free(den); mpz_clear(l); mpq_clear(nlcm); mpq_clear(y); mpq_clear(p_i); return j; }
Eval prim_lesser_eq(Expr args) { Expr before = take_typed(&args, NUMBER), k; while(maybe_take_typed(&args, &k, NUMBER)) { if(!(mpq_cmp(before.num, k.num) <= 0)) return final_eval(boolean(false)); before = k; } return final_eval(boolean(true)); }
static int _compo(CRATIONAL *a, void *o, bool invert) { if (GB.Is(o, CLASS_BigInt)) { mpq_set_z(_tmp.n, ((CBIGINT *)o)->n); return mpq_cmp(a->n, _tmp.n); } else return -2; }
int QQ::compare_elems(const ring_elem f, const ring_elem g) const { gmp_QQ a = MPQ_VAL(f); gmp_QQ b = MPQ_VAL(g); int cmp = mpq_cmp(a,b); if (cmp > 0) return 1; if (cmp == 0) return 0; return -1; }
int mpq_mat_is_reduced(mpq_mat_t mu, mpq_mat_t GS, double delta, double eta){ //want to return 1 if this data could come from a reduced matrix 0 otherwise mpq_mat_t gs_len; mpq_mat_init( gs_len, 1, GS->c); mpq_t temp, temp1, temp2; mpq_init(temp); mpq_init(temp1); mpq_init(temp2); long i, j; int result = 1; for (i = 0; (i < GS->r) && (result == 1); i++){ mpq_mat_row_inner_product(gs_len->entries[i], GS, i, GS, i); if (i > 0){ mpq_div(temp, gs_len->entries[i], gs_len->entries[i-1]); mpq_mul(temp1, mu->entries[i*mu->r + i-1], mu->entries[i*mu->r + i-1]); mpq_add(temp, temp, temp1); mpq_set_d(temp1, delta - eta*eta); if (mpq_cmp(temp, temp1) < 0){ result = 0; } else{ mpq_set_d(temp2, eta); for( j = 0 ; (j < i) && (result == 1); j++) if ( mpq_cmp( mu->entries[i*mu->r + j], temp2) >= 0){ result = 0; } } // if temp < (3/4 or 1/(delta - eta^2))==temp1 then not reduced... } } mpq_clear(temp); mpq_clear(temp1); mpq_clear(temp2); mpq_mat_clear(gs_len); return result; }
int camlidl_custom_mpq_compare(value val1, value val2) { int res; __mpq_struct* mpq1; __mpq_struct* mpq2; mpq1 = (__mpq_struct*)(Data_custom_val(val1)); mpq2 = (__mpq_struct*)(Data_custom_val(val2)); res = mpq_cmp(mpq1,mpq2); res = res > 0 ? 1 : res==0 ? 0 : -1; return res; }
int camlidl_custom_mpq2_compare(value val1, value val2) { CAMLparam2(val1,val2); int res; __mpq_struct** mpq1; __mpq_struct** mpq2; mpq1 = (__mpq_struct**)(Data_custom_val(val1)); mpq2 = (__mpq_struct**)(Data_custom_val(val2)); res = mpq_cmp(*mpq1,*mpq2); res = res > 0 ? 1 : res==0 ? 0 : -1; CAMLreturn(res); }
APLRAT PrimFnDydDownStileRisRvR (APLRAT aplRatLft, APLRAT aplRatRht, LPPRIMSPEC lpPrimSpec) { APLRAT mpqRes = {0}; // Compare the two Rationals if (mpq_cmp (&aplRatLft, &aplRatRht) < 0) mpq_init_set (&mpqRes, &aplRatLft); else mpq_init_set (&mpqRes, &aplRatRht); return mpqRes; } // End PrimFnDydDownStileRisRvR
void refine_sqrt_upper(mpq_t sqrt_x, mpq_t x, int digits) /***************************************************************\ * USAGE: refine a rational upper bound on the sqrt(x) to the * * requested tolerance: 10^-digits * \***************************************************************/ { // assume (sqrt_x)^2 >= x > 0 && sqrt_x > 0 && digits >= 0 mpq_t new_sqrt_x, beta, tol; // initialize mpq_init(new_sqrt_x); mpq_init(beta); mpq_init(tol); // setup tol = (1/10)^digits mpq_set_ui(tol, 1, 10); exponentiate_mpq(tol, tol, digits); // loop until we have refined to the tol do { // compute new_sqrt_x & beta mpq_mul(beta, sqrt_x, sqrt_x); // (sqrt_x)^2 mpq_sub(beta, beta, x); // (sqrt_x)^2 - x mpq_add(new_sqrt_x, sqrt_x, sqrt_x); // 2*sqrt_x mpq_div(beta, beta, new_sqrt_x); // ((sqrt_x)^2 - x)/(2*sqrt_x) mpq_sub(new_sqrt_x, sqrt_x, beta); // sqrt_x - ((sqrt_x)^2 - x)/(2*sqrt_x) // determine if 2*beta <= tol mpq_add(beta, beta, beta); if (mpq_cmp(beta, tol) <= 0) { // success!! break; } else { // update sqrt_x & try again mpq_set(sqrt_x, new_sqrt_x); } } while (1); // clear mpq_clear(new_sqrt_x); mpq_clear(beta); mpq_clear(tol); return; }
//Refer to apps_sfdl_gen/merge_sort_cons.h for constants to use in this exogenous //check. bool merge_sortProverExo::exogenous_check(const mpz_t* input, const mpq_t* input_q, int num_inputs, const mpz_t* output, const mpq_t* output_q, int num_outputs, mpz_t prime) { bool passed_test = true; #ifdef ENABLE_EXOGENOUS_CHECKING for(int i = 1; i < num_outputs; i++){ if (!(mpq_cmp(output_q[i - 1], output_q[i]) <= 0)) { passed_test = false; //break; } //gmp_printf("%Qd\n", output_q[i]); } #else gmp_printf("<Exogenous check disabled>\n"); #endif return passed_test; };
int game_is_in_steady_state(game_t *game) { int state = 0; int n = game->graph->n; mpq_t tmp; mpq_t m; mpq_init(m); mpq_init(tmp); gboolean s = TRUE; game_get_payoff_of_player(game, 0, m); int i; for(i = 1; i < n; ++i) { game_get_payoff_of_player(game, i, tmp); if(mpq_cmp(tmp, m) != 0) { s = FALSE; break; } } int coop = game_get_number_of_cooperators(game); if(coop == 0) { state = ALL_DEFECT_STATE; } else if(coop == n) { state = ALL_COOPERATE_STATE; } else if(s) { state = MIXED_STATE; } mpq_clear(m); mpq_clear(tmp); return state; }
void ovm_q_eq(oregister_t *l, oregister_t *r) { l->t = t_word; switch (r->t) { case t_float: l->v.w = mpq_get_d(oqr(l)) == r->v.d; break; case t_mpq: l->v.w = mpq_cmp(oqr(l), oqr(r)) == 0; break; case t_mpr: mpfr_set_q(orr(l), oqr(l), thr_rnd); l->v.w = mpfr_equal_p(orr(l), orr(r)); break; default: l->v.w = 0; break; } }
static symbol_p rest_create(niffRest *p) { symbol_p s = symbol_create(t_current); note_p n = &s->symbol.note; mpq_init(n->duration); rat2mpq(n->duration, &p->duration); stem_p stem = stem_current; if (mpq_cmp(n->duration, time_sig_current->duration) >= 0 && ! mpq_equal(t_current, t_measure_start)) { fprintf(stderr, "Meet SharpEye rest(measure) bug. Replace start time "); mpq_out_str(stderr, 10, t_current); fprintf(stderr, " with measure start time "); mpq_out_str(stderr, 10, t_measure_start); fprintf(stderr, "\n"); mpq_set(s->start, t_measure_start); stem = NULL; // don't share a stem when the time is incorrect } s->type = SYM_NOTE; n->value = p->staffStep; n->flags |= FLAG_REST; if (stem == NULL) { #if VERBOSE VPRINTF("\n ****** Get a Rest chunk without stem chunk??"); #else fprintf(stderr, "Warning: ****** Get a Rest chunk without stem chunk??\n"); #endif stem = &stem_create()->symbol.stem; } n->tie_start = NO_ID; n->tie_end = NO_ID; n->stem = stem; n->tuplet = stem->tuplet; return s; }
void lps_scale(const Lps* lp) { Con* con; Nzo* nzo; mpq_t maxi; mpq_t v; assert(lps_valid(lp)); mpq_init(maxi); mpq_init(v); for(con = lp->con_root; con != NULL; con = con->next) { if ((con->flags & LP_FLAG_CON_SCALE) > 0) { mpq_set_ui(maxi, 0, 1); /* = 0 */ for(nzo = con->first; nzo != NULL; nzo = nzo->con_next) { mpq_abs(v, nzo->value); if (mpq_cmp(v, maxi) > 0) mpq_set(maxi, v); } mpq_inv(con->scale, maxi); /* scale = 1 / maxi */ if (HAS_RHS(con)) mpq_mul(con->rhs, con->rhs, con->scale); if (HAS_LHS(con)) mpq_mul(con->lhs, con->lhs, con->scale); for(nzo = con->first; nzo != NULL; nzo = nzo->con_next) mpq_mul(nzo->value, nzo->value, con->scale); } } mpq_clear(v); mpq_clear(maxi); }
void binary_searchProverExo::baseline(const mpq_t* input_q, int num_inputs, mpq_t* output_recomputed, int num_outputs) { int SIZE = binary_search_cons::SIZE; int logSIZE = binary_search_cons::logSIZE; //There are SIZE + 1 inputs, put at the end of the inputs //We ignore the merkle tree root hash, which comes at the start. int input_start = num_inputs - SIZE - 1; int present = 0; int min = 0; int max = SIZE-1; const mpq_t& search = input_q[input_start + SIZE]; for(int i = 0; i < logSIZE; i++) { int avg = (min + max) >> 1; const mpq_t& got = input_q[input_start + avg]; int cmp = mpq_cmp(search, got); if (cmp == 0) { min = avg; max = avg; present = 1; } else if (cmp < 0) { max = avg; } else if (cmp > 0) { min = avg; } } //Return value mpq_set_si(output_recomputed[0], 0, 1); //Present mpq_set_si(output_recomputed[1], present, 1); //Index mpq_set_si(output_recomputed[2], min, 1); }
static int _compf(CRATIONAL *a, double f, bool invert) { my_mpq_set_d(_tmp.n, f); return mpq_cmp(a->n, _tmp.n); }
static int _comp(CRATIONAL *a, CRATIONAL *b, bool invert) { return mpq_cmp(a->n, b->n); }
int main (int argc, char **argv){ mp_int num1,den1,num2,den2; mp_rat q1,q2,q3,q4; //mp_rat *bernoulli; int i; clock_t start,stop; if (argc < 5) { fprintf(stderr, "usage: %s integer integer integer integer \n", argv[0]); exit(EXIT_FAILURE); } mp_init_multi(&num1,&den1,&num2,&den2,NULL); mp_get_str(argv[1], &num1, 10); mp_get_str(argv[2], &den1, 10); mp_get_str(argv[3], &num2, 10); mp_get_str(argv[4], &den2, 10); printf("Numerator 1: ");mp_print(&num1);puts(""); printf("Denominator 1: ");mp_print(&den1);puts(""); printf("Numerator 2: ");mp_print(&num2);puts(""); printf("Denominator 2: ");mp_print(&den2);puts(""); mpq_init_multi(&q1,&q2,&q3,&q4,NULL);puts("000"); mpq_set(&q1,&num1,&den1);puts("111"); printf("Rational1: ");mpq_print(&q1);puts(""); mpq_set(&q2,&num2,&den2);puts("222"); printf("Rational2: ");mpq_print(&q2);puts(""); mpq_add(&q1,&q2,&q3);; printf("R1 + R2 = ");mpq_print(&q3);puts(""); mpq_sub(&q1,&q2,&q3); printf("R1 - R2 = ");mpq_print(&q3);puts(""); mpq_mul(&q1,&q2,&q3); printf("R1 * R2 = ");mpq_print(&q3);puts(""); mpq_div(&q1,&q2,&q3); printf("R1 / R2 = ");mpq_print(&q3);puts(""); //mpq_pow_d(&q1,123,&q3); printf("R1 ^ 123 = ");mpq_print(&q3);puts(""); printf("cmp(R1, R2) = %d\n",mpq_cmp(&q1,&q2)); printf("cmp(R2, R1) = %d\n",mpq_cmp(&q2,&q1)); printf("cmp(R1, R1) = %d\n",mpq_cmp(&q1,&q1)); mp_set_int(&num2,123); //mp_expt(&num1,&num2,&num1); printf("num1 ^123 = ");mp_fwrite(&num1,10,stdout);puts(""); mpq_set_epsilon(50); //mpq_set_int(&q1,128,2); //mpq_set_int(&q1,529,1849); //mpq_set_int(&q1,3481,11664); //mpq_set_int(&q1,1764,1849); mpq_set_int(&q1,44521,46656); mpq_sqrt(&q1,&q1); printf("sqrt(R1) = ");mpq_print(&q1);puts(""); //SeidelBernoulli(20); //bernoulli = malloc(sizeof(mp_rat) * 102); start = clock(); //bern_rat_init(10); //bhbern(50); stop = clock(); puts("bernoulli"); for(i=0;i<=(50);i++){ //mpq_print(&bern_array[i]);printf(" %d\n",i); } mpq_bernoulli(10,&q1); printf("B_10 = ");mpq_print(&q1);puts(""); mpq_bernoulli(4,&q1); printf("B_4 = ");mpq_print(&q1);puts(""); mpq_bernoulli(0,&q1); printf("B_0 = ");mpq_print(&q1);puts(""); mpq_bernoulli(1,&q1); printf("B_1 = ");mpq_print(&q1);puts(""); mpq_bernoulli(2,&q1); printf("B_3 = ");mpq_print(&q1);puts(""); mpq_bernoulli(100,&q1); printf("B_100 = ");mpq_print(&q1);puts(""); mpq_bernoulli(98,&q1); printf("B_98 = ");mpq_print(&q1);puts(""); printf("Time: %6.6f\n",( (double)stop - (double)start )/((double)CLOCKS_PER_SEC) ); mpq_bernoulli_free(); exit(EXIT_SUCCESS); }
int compare_elems(const ElementType& f,const ElementType& g) const { int cmp = mpq_cmp(&f,&g); if (cmp > 0) return 1; if (cmp < 0) return -1; return 0; }
APLRAT PrimFnMonDownStileRisR (APLRAT aplRatRht, LPPRIMSPEC lpPrimSpec) { APLRAT mpqRes = {0}, mpqFloor = {0}, mpqCeil = {0}, mpqTmp1 = {0}, mpqTmp2 = {0}, mpqNear = {0}; // Check for PoM infinity if (IsMpqInfinity (&aplRatRht)) // Copy to the result mpq_init_set (&mpqRes, &aplRatRht); else { // Initialize the temps mpq_init (&mpqRes); mpq_init (&mpqFloor); mpq_init (&mpqCeil ); mpq_init (&mpqTmp1); mpq_init (&mpqTmp2); mpq_init (&mpqNear); // Get the exact floor and ceiling mpq_floor (&mpqFloor, &aplRatRht); mpq_ceil (&mpqCeil , &aplRatRht); // Calculate the integer nearest the right arg mpq_sub (&mpqTmp1, &aplRatRht, &mpqFloor); mpq_sub (&mpqTmp2, &mpqCeil , &aplRatRht); // Split cases based upon the signum of the difference between // (the number and its floor) and (the ceiling and the number) switch (signumint (mpq_cmp (&mpqTmp1, &mpqTmp2))) { case 1: mpq_set (&mpqNear, &mpqCeil); break; case 0: mpq_abs (&mpqTmp1, &mpqFloor); mpq_abs (&mpqTmp2, &mpqFloor); // They are equal, so use the one with the larger absolute value mpq_set (&mpqNear, ((mpq_cmp (&mpqTmp1, &mpqTmp2) > 0) ? &mpqFloor : &mpqCeil)); break; case -1: mpq_set (&mpqNear, &mpqFloor); break; defstop break; } // End SWITCH // If Near is < Rht, return Near if (mpq_cmp (&mpqNear, &aplRatRht) < 0) mpq_set (&mpqRes, &mpqNear); else { // If Near is non-zero, and // Rht is tolerantly-equal to Near, // return Near; otherwise, return Near - 1 if (mpq_sgn (&mpqNear) NE 0) { mpq_set (&mpqRes, &mpqNear); if (!PrimFnDydEqualBisRvR (aplRatRht, mpqNear, NULL)) mpq_sub_ui (&mpqRes, &mpqRes, 1, 1); } else { // mpfNear is zero // Get -[]CT as a VFP mpq_set_d (&mpqTmp1, -GetQuadCT ()); // If Rht is between (-[]CT) and 0 (inclusive), // return 0; otherwise, return -1 if (mpq_cmp (&mpqTmp1, &aplRatRht) <= 0 && mpq_sgn (&aplRatRht) <= 0) mpq_set_si (&mpqRes, 0, 1); else mpq_set_si (&mpqRes, -1, 1); } // End IF/ELSE } // End IF/ELSE // We no longer need this storage Myq_clear (&mpqNear); Myq_clear (&mpqTmp2); Myq_clear (&mpqTmp1); Myq_clear (&mpqCeil); Myq_clear (&mpqFloor); } // End IF/ELSE return mpqRes; } // End PrimFnMonDownStileRisR
bool AlkValue::operator>=(const AlkValue &val) const { return mpq_cmp(d->m_val.get_mpq_t(), val.d->m_val.get_mpq_t()) >= 0 ? true : false; }
int _mpq_cmp_ui (mpq_srcptr op1, unsigned long int num2, unsigned long int den2) { mp_size_t num1_size = SIZ(NUM(op1)); mp_size_t den1_size = SIZ(DEN(op1)); mp_size_t tmp1_size, tmp2_size; mp_ptr tmp1_ptr, tmp2_ptr; mp_limb_t cy_limb; int cc; TMP_DECL; #if GMP_NAIL_BITS != 0 if ((num2 | den2) > GMP_NUMB_MAX) { mpq_t op2; mpq_init (op2); mpz_set_ui (mpq_numref (op2), num2); mpz_set_ui (mpq_denref (op2), den2); cc = mpq_cmp (op1, op2); mpq_clear (op2); return cc; } #endif /* need canonical sign to get right result */ ASSERT (den1_size > 0); if (UNLIKELY (den2 == 0)) DIVIDE_BY_ZERO; if (num2 == 0) return num1_size; if (num1_size <= 0) return -1; /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs. Same for NUM1 x DEN1 with respect to TMP2_SIZE. */ if (num1_size > den1_size + 1) /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */ return num1_size; if (den1_size > num1_size + 1) /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */ return -num1_size; TMP_MARK; TMP_ALLOC_LIMBS_2 (tmp1_ptr, num1_size + 1, tmp2_ptr, den1_size + 1); cy_limb = mpn_mul_1 (tmp1_ptr, PTR(NUM(op1)), num1_size, (mp_limb_t) den2); tmp1_ptr[num1_size] = cy_limb; tmp1_size = num1_size + (cy_limb != 0); cy_limb = mpn_mul_1 (tmp2_ptr, PTR(DEN(op1)), den1_size, (mp_limb_t) num2); tmp2_ptr[den1_size] = cy_limb; tmp2_size = den1_size + (cy_limb != 0); cc = tmp1_size - tmp2_size != 0 ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size); TMP_FREE; return cc; }
int ssx_phase_I(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *type = ssx->type; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; mpq_t *coef = ssx->coef; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; mpq_t *pi = ssx->pi; mpq_t *cbar = ssx->cbar; int *orig_type, orig_dir; mpq_t *orig_lb, *orig_ub, *orig_coef; int i, k, ret; /* save components of the original LP problem, which are changed by the routine */ orig_type = xcalloc(1+m+n, sizeof(int)); orig_lb = xcalloc(1+m+n, sizeof(mpq_t)); orig_ub = xcalloc(1+m+n, sizeof(mpq_t)); orig_coef = xcalloc(1+m+n, sizeof(mpq_t)); for (k = 1; k <= m+n; k++) { orig_type[k] = type[k]; mpq_init(orig_lb[k]); mpq_set(orig_lb[k], lb[k]); mpq_init(orig_ub[k]); mpq_set(orig_ub[k], ub[k]); } orig_dir = ssx->dir; for (k = 0; k <= m+n; k++) { mpq_init(orig_coef[k]); mpq_set(orig_coef[k], coef[k]); } /* build an artificial basic solution, which is primal feasible, and also build an auxiliary objective function to minimize the sum of infeasibilities for the original problem */ ssx->dir = SSX_MIN; for (k = 0; k <= m+n; k++) mpq_set_si(coef[k], 0, 1); mpq_set_si(bbar[0], 0, 1); for (i = 1; i <= m; i++) { int t; k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_LO || t == SSX_DB || t == SSX_FX) { /* in the original problem x[k] has lower bound */ if (mpq_cmp(bbar[i], lb[k]) < 0) { /* which is violated */ type[k] = SSX_UP; mpq_set(ub[k], lb[k]); mpq_set_si(lb[k], 0, 1); mpq_set_si(coef[k], -1, 1); mpq_add(bbar[0], bbar[0], ub[k]); mpq_sub(bbar[0], bbar[0], bbar[i]); } } if (t == SSX_UP || t == SSX_DB || t == SSX_FX) { /* in the original problem x[k] has upper bound */ if (mpq_cmp(bbar[i], ub[k]) > 0) { /* which is violated */ type[k] = SSX_LO; mpq_set(lb[k], ub[k]); mpq_set_si(ub[k], 0, 1); mpq_set_si(coef[k], +1, 1); mpq_add(bbar[0], bbar[0], bbar[i]); mpq_sub(bbar[0], bbar[0], lb[k]); } } } /* now the initial basic solution should be primal feasible due to changes of bounds of some basic variables, which turned to implicit artifical variables */ /* compute simplex multipliers and reduced costs */ ssx_eval_pi(ssx); ssx_eval_cbar(ssx); /* display initial progress of the search */ show_progress(ssx, 1); /* main loop starts here */ for (;;) { /* display current progress of the search */ #if 0 if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) #else if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) #endif show_progress(ssx, 1); /* we do not need to wait until all artificial variables have left the basis */ if (mpq_sgn(bbar[0]) == 0) { /* the sum of infeasibilities is zero, therefore the current solution is primal feasible for the original problem */ ret = 0; break; } /* check if the iterations limit has been exhausted */ if (ssx->it_lim == 0) { ret = 2; break; } /* check if the time limit has been exhausted */ #if 0 if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) #else if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) #endif { ret = 3; break; } /* choose non-basic variable xN[q] */ ssx_chuzc(ssx); /* if xN[q] cannot be chosen, the sum of infeasibilities is minimal but non-zero; therefore the original problem has no primal feasible solution */ if (ssx->q == 0) { ret = 1; break; } /* compute q-th column of the simplex table */ ssx_eval_col(ssx); /* choose basic variable xB[p] */ ssx_chuzr(ssx); /* the sum of infeasibilities cannot be negative, therefore the auxiliary lp problem cannot have unbounded solution */ xassert(ssx->p != 0); /* update values of basic variables */ ssx_update_bbar(ssx); if (ssx->p > 0) { /* compute p-th row of the inverse inv(B) */ ssx_eval_rho(ssx); /* compute p-th row of the simplex table */ ssx_eval_row(ssx); xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); /* update simplex multipliers */ ssx_update_pi(ssx); /* update reduced costs of non-basic variables */ ssx_update_cbar(ssx); } /* xB[p] is leaving the basis; if it is implicit artificial variable, the corresponding residual vanishes; therefore bounds of this variable should be restored to the original values */ if (ssx->p > 0) { k = Q_col[ssx->p]; /* x[k] = xB[p] */ if (type[k] != orig_type[k]) { /* x[k] is implicit artificial variable */ type[k] = orig_type[k]; mpq_set(lb[k], orig_lb[k]); mpq_set(ub[k], orig_ub[k]); xassert(ssx->p_stat == SSX_NL || ssx->p_stat == SSX_NU); ssx->p_stat = (ssx->p_stat == SSX_NL ? SSX_NU : SSX_NL); if (type[k] == SSX_FX) ssx->p_stat = SSX_NS; /* nullify the objective coefficient at x[k] */ mpq_set_si(coef[k], 0, 1); /* since coef[k] has been changed, we need to compute new reduced cost of x[k], which it will have in the adjacent basis */ /* the formula d[j] = cN[j] - pi' * N[j] is used (note that the vector pi is not changed, because it depends on objective coefficients at basic variables, but in the adjacent basis, for which the vector pi has been just recomputed, x[k] is non-basic) */ if (k <= m) { /* x[k] is auxiliary variable */ mpq_neg(cbar[ssx->q], pi[k]); } else { /* x[k] is structural variable */ int ptr; mpq_t temp; mpq_init(temp); mpq_set_si(cbar[ssx->q], 0, 1); for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { mpq_mul(temp, pi[A_ind[ptr]], A_val[ptr]); mpq_add(cbar[ssx->q], cbar[ssx->q], temp); } mpq_clear(temp); } } } /* jump to the adjacent vertex of the polyhedron */ ssx_change_basis(ssx); /* one simplex iteration has been performed */ if (ssx->it_lim > 0) ssx->it_lim--; ssx->it_cnt++; } /* display final progress of the search */ show_progress(ssx, 1); /* restore components of the original problem, which were changed by the routine */ for (k = 1; k <= m+n; k++) { type[k] = orig_type[k]; mpq_set(lb[k], orig_lb[k]); mpq_clear(orig_lb[k]); mpq_set(ub[k], orig_ub[k]); mpq_clear(orig_ub[k]); } ssx->dir = orig_dir; for (k = 0; k <= m+n; k++) { mpq_set(coef[k], orig_coef[k]); mpq_clear(orig_coef[k]); } xfree(orig_type); xfree(orig_lb); xfree(orig_ub); xfree(orig_coef); /* return to the calling program */ return ret; }
int ssx_driver(SSX *ssx) { int m = ssx->m; int *type = ssx->type; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; int i, k, ret; ssx->tm_beg = xtime(); /* factorize the initial basis matrix */ if (ssx_factorize(ssx)) { xprintf("Initial basis matrix is singular\n"); ret = 7; goto done; } /* compute values of basic variables */ ssx_eval_bbar(ssx); /* check if the initial basic solution is primal feasible */ for (i = 1; i <= m; i++) { int t; k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_LO || t == SSX_DB || t == SSX_FX) { /* x[k] has lower bound */ if (mpq_cmp(bbar[i], lb[k]) < 0) { /* which is violated */ break; } } if (t == SSX_UP || t == SSX_DB || t == SSX_FX) { /* x[k] has upper bound */ if (mpq_cmp(bbar[i], ub[k]) > 0) { /* which is violated */ break; } } } if (i > m) { /* no basic variable violates its bounds */ ret = 0; goto skip; } /* phase I: find primal feasible solution */ ret = ssx_phase_I(ssx); switch (ret) { case 0: ret = 0; break; case 1: //xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); ret = 1; break; case 2: xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 3; break; case 3: xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 5; break; default: xassert(ret != ret); } /* compute values of basic variables (actually only the objective value needs to be computed) */ ssx_eval_bbar(ssx); skip: /* compute simplex multipliers */ ssx_eval_pi(ssx); /* compute reduced costs of non-basic variables */ ssx_eval_cbar(ssx); /* if phase I failed, do not start phase II */ if (ret != 0) goto done; /* phase II: find optimal solution */ ret = ssx_phase_II(ssx); switch (ret) { case 0: //xprintf("OPTIMAL SOLUTION FOUND\n"); ret = 0; break; case 1: //xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); ret = 2; break; case 2: xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 4; break; case 3: xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 6; break; default: xassert(ret != ret); } done: /* decrease the time limit by the spent amount of time */ if (ssx->tm_lim >= 0.0) #if 0 { ssx->tm_lim -= utime() - ssx->tm_beg; #else { ssx->tm_lim -= xdifftime(xtime(), ssx->tm_beg); #endif if (ssx->tm_lim < 0.0) ssx->tm_lim = 0.0; } return ret; }