void ssx_eval_col(SSX *ssx) { int m = ssx->m; int n = ssx->n; 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; int q = ssx->q; mpq_t *aq = ssx->aq; int i, k, ptr; xassert(1 <= q && q <= n); /* aq := 0 */ for (i = 1; i <= m; i++) mpq_set_si(aq[i], 0, 1); /* aq := N[q] */ k = Q_col[m+q]; /* x[k] = xN[q] */ if (k <= m) { /* N[q] is a column of the unity matrix I */ mpq_set_si(aq[k], 1, 1); } else { /* N[q] is a column of the original constraint matrix -A */ for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) mpq_neg(aq[A_ind[ptr]], A_val[ptr]); } /* aq := inv(B) * aq */ bfx_ftran(ssx->binv, aq, 1); /* aq := - aq */ for (i = 1; i <= m; i++) mpq_neg(aq[i], aq[i]); return; }
void check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub) { mpq_t got; int neg_x, neg_y, swap; mpq_init (got); MPQ_CHECK_FORMAT (want_add); MPQ_CHECK_FORMAT (want_sub); MPQ_CHECK_FORMAT (x); MPQ_CHECK_FORMAT (y); for (swap = 0; swap <= 1; swap++) { for (neg_x = 0; neg_x <= 1; neg_x++) { for (neg_y = 0; neg_y <= 1; neg_y++) { mpq_add (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_add)) { printf ("mpq_add wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_add); abort (); } mpq_sub (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_sub)) { printf ("mpq_sub wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_sub); abort (); } mpq_neg (y, y); mpq_swap (want_add, want_sub); } mpq_neg (x, x); mpq_swap (want_add, want_sub); mpq_neg (want_add, want_add); mpq_neg (want_sub, want_sub); } mpq_swap (x, y); mpq_neg (want_sub, want_sub); } mpq_clear (got); }
void check_all (mpq_ptr x, mpq_ptr y, int want) { check_one (x, y, want); check_one (y, x, want); mpq_neg (x, x); mpq_neg (y, y); check_one (x, y, want); check_one (y, x, want); }
void check_samples (void) { mpq_t q; mpq_init (q); mpq_set_ui (q, 0L, 1L); check_one (q, 10, "0"); check_one (q, 10, "0/1"); check_one (q, 10, "0 / 1"); check_one (q, 0, "0x0/ 1"); check_one (q, 0, "0x0/ 0x1"); check_one (q, 0, "0 / 0x1"); check_one (q, 10, "-0"); check_one (q, 10, "-0/1"); check_one (q, 10, "-0 / 1"); check_one (q, 0, "-0x0/ 1"); check_one (q, 0, "-0x0/ 0x1"); check_one (q, 0, "-0 / 0x1"); mpq_set_ui (q, 255L, 256L); check_one (q, 10, "255/256"); check_one (q, 0, "0xFF/0x100"); check_one (q, 16, "FF/100"); mpq_neg (q, q); check_one (q, 10, "-255/256"); check_one (q, 0, "-0xFF/0x100"); check_one (q, 16, "-FF/100"); mpq_clear (q); }
static void _taylor_mpfr (gulong l, mpq_t q, mpfr_ptr res, mp_rnd_t rnd) { NcmBinSplit **bs_ptr = _ncm_mpsf_sbessel_get_bs (); NcmBinSplit *bs = *bs_ptr; _binsplit_spherical_bessel *data = (_binsplit_spherical_bessel *) bs->userdata; gulong n; data->l = l; mpq_mul (data->mq2_2, q, q); mpq_neg (data->mq2_2, data->mq2_2); mpq_div_2exp (data->mq2_2, data->mq2_2, 1); //mpfr_printf ("# Taylor %ld %Qd | %Qd\n", l, q, data->mq2_2); ncm_binsplit_eval_prec (bs, binsplit_spherical_bessel_taylor, 10, mpfr_get_prec (res)); //mpfr_printf ("# Taylor %ld %Qd | %Zd %Zd\n", l, q, bs->T, bs->Q); mpfr_set_q (res, q, rnd); mpfr_pow_ui (res, res, l, rnd); mpfr_mul_z (res, res, bs->T, rnd); mpfr_div_z (res, res, bs->Q, rnd); for (n = 1; n <= l; n++) mpfr_div_ui (res, res, 2L * n + 1, rnd); ncm_memory_pool_return (bs_ptr); return; }
AlkValue AlkValue::operator-() const { AlkValue result; mpq_neg(result.d->m_val.get_mpq_t(), d->m_val.get_mpq_t()); result.d->m_val.canonicalize(); return result; }
static int basis_col(void *info, int j, int ind[], mpq_t val[]) { /* this auxiliary routine provides row indices and numeric values of non-zero elements in j-th column of the matrix B */ SSX *ssx = info; int m = ssx->m; int n = ssx->n; 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; int k, len, ptr; xassert(1 <= j && j <= m); k = Q_col[j]; /* x[k] = xB[j] */ xassert(1 <= k && k <= m+n); /* j-th column of the matrix B is k-th column of the augmented constraint matrix (I | -A) */ if (k <= m) { /* it is a column of the unity matrix I */ len = 1, ind[1] = k, mpq_set_si(val[1], 1, 1); } else { /* it is a column of the original constraint matrix -A */ len = 0; for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { len++; ind[len] = A_ind[ptr]; mpq_neg(val[len], A_val[ptr]); } } return len; }
void ssx_eval_row(SSX *ssx) { int m = ssx->m; int n = ssx->n; 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 *rho = ssx->rho; mpq_t *ap = ssx->ap; int j, k, ptr; mpq_t temp; mpq_init(temp); for (j = 1; j <= n; j++) { /* ap[j] := - N'[j] * rho (inner product) */ k = Q_col[m+j]; /* x[k] = xN[j] */ if (k <= m) mpq_neg(ap[j], rho[k]); else { mpq_set_si(ap[j], 0, 1); for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { mpq_mul(temp, A_val[ptr], rho[A_ind[ptr]]); mpq_add(ap[j], ap[j], temp); } } } mpq_clear(temp); return; }
Rational Rational::operator-() { Rational res(*this); mpq_neg(res.number, number); return res; }
/* Check various values 2^n and 1/2^n. */ void check_onebit (void) { static const long data[] = { -3*GMP_NUMB_BITS-1, -3*GMP_NUMB_BITS, -3*GMP_NUMB_BITS+1, -2*GMP_NUMB_BITS-1, -2*GMP_NUMB_BITS, -2*GMP_NUMB_BITS+1, -GMP_NUMB_BITS-1, -GMP_NUMB_BITS, -GMP_NUMB_BITS+1, -5, -2, -1, 0, 1, 2, 5, GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1, 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1, 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1, }; int i, neg; long exp, l; mpq_t q; double got, want; mpq_init (q); for (i = 0; i < numberof (data); i++) { exp = data[i]; mpq_set_ui (q, 1L, 1L); if (exp >= 0) mpq_mul_2exp (q, q, exp); else mpq_div_2exp (q, q, -exp); want = 1.0; for (l = 0; l < exp; l++) want *= 2.0; for (l = 0; l > exp; l--) want /= 2.0; for (neg = 0; neg <= 1; neg++) { if (neg) { mpq_neg (q, q); want = -want; } got = mpq_get_d (q); if (got != want) { printf ("mpq_get_d wrong on %s2**%ld\n", neg ? "-" : "", exp); mpq_trace (" q ", q); d_trace (" want ", want); d_trace (" got ", got); abort(); } } } mpq_clear (q); }
void lp_set_row_range(LP* lp, int row, mpq_t q) { mpq_t q2; int var; mpq_init(q2); if(lp->row_name != NULL) { char buf[LP_NAME_LEN_MAX]; buf[0] = '#'; buf[1] = 'R'; buf[2] = 0; strncat(buf, lp->row_name[row], LP_NAME_LEN_MAX-3); var = lp_add_var(lp, buf); } else var = lp_add_var(lp, NULL); lp_add_slackref(lp, row+1); vector_get_element(&q2, lp->b, row); lp->upper.is_valid[var] = TRUE; mpq_init(lp->upper.bound[var]); if (lp->row_equality[row] == LP_EQUALITY_GE) { if (mpq_sgn(q) < 0) mpq_neg(q, q); mpq_set(lp->lower.bound[var], q2); mympq_add(q2, q2, q); mpq_set(lp->upper.bound[var], q2); } else if (lp->row_equality[row] == LP_EQUALITY_LE) { if (mpq_sgn(q) < 0) mpq_neg(q, q); mpq_set(lp->upper.bound[var], q2); mympq_sub(q2, q2, q); mpq_set(lp->lower.bound[var], q2); } else if (mpq_sgn(q) > 0) { mpq_set(lp->lower.bound[var], q2); mympq_add(q2, q2, q); mpq_set(lp->upper.bound[var], q2); } else { mpq_set(lp->upper.bound[var], q2); mympq_add(q2, q2, q); mpq_set(lp->lower.bound[var], q2); } lp_set_row_equality(lp, row, LP_EQUALITY_EQ); lp_set_coefficient(lp, mympq_minus_one, row, var); vector_delete_element(lp->b, row); mpq_clear(q2); }
static inline rsexp negate_fixreal (RState* r, rsexp n) { rsexp neg; ensure (neg = smi_to_fixreal (r, R_ZERO)); mpq_neg (fixreal_value (neg), fixreal_value (n)); return neg; }
static void from_double(mpq_t n, double f, int level) { double fa; int nfa; mpq_t ni, nn; bool neg; //fprintf(stderr, "from_double: %.14g\n", f); if (level >= 10) goto __DEFAULT; fa = fabs(f); if (fa >= 1E8 || fa <= 1E-8) goto __DEFAULT; neg = (f < 0); nfa = (int)fa; if (nfa >= 1) fa -= nfa; //fprintf(stderr, "fa = %.14g %.14g\n", fa, (fa*1E8) - (int)(fa*1E8)); if (nfa && fa < 1E-8) { mpq_set_si(n, 0, 1); } else if (((fa*1E8) - (int)(fa*1E8)) < 1E-8) { mpq_set_si(n, (int)(fa*1E8), 100000000); } else { mpq_init(ni); from_double(ni, 1 / fa, level + 1); mpq_inv(n, ni); mpq_clear(ni); } mpq_init(nn); mpq_set_si(nn, nfa, 1); mpq_add(n, n, nn); mpq_clear(nn); if (neg) mpq_neg(n, n); mpq_canonicalize(n); return; __DEFAULT: mpq_set_d(n, f); }
static PyObject * Pympq_neg(PympqObject *self) { PympqObject *result; if ((result = (PympqObject*)Pympq_new())) { mpq_neg(result->q, self->q); } return (PyObject*)result; }
static PyObject * _GMPy_MPQ_Minus(PyObject *x, CTXT_Object *context) { MPQ_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPQ_New(context))) { return NULL; } mpq_neg(result->q, MPQ(x)); return (PyObject*)result; }
void ovm_q_rem(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: ovm_raise(except_floating_point_error); case t_word: if (r->v.w == 0) ovm_raise(except_floating_point_error); if (r->v.w > 0) mpz_mul_ui(ozr(r), ozs(l), r->v.w); else { mpz_set_si(ozr(r), r->v.w); mpz_mul(ozr(r), ozs(l), ozr(r)); } mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); mpq_canonicalize(oqr(l)); check_mpq(l); break; case t_float: l->t = t_float; l->v.d = fmod(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: mpz_mul(ozr(r), ozs(l), ozr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); check_mpq(l); break; case t_rat: mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); case t_mpq: mpq_div(oqr(l), oqr(l), oqr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozs(l)); mpz_mul(ozs(l), ozs(l), ozs(r)); mpq_canonicalize(oqr(l)); if (mpq_sgn(oqr(r)) < 0) mpq_neg(oqr(l), oqr(l)); check_mpq(l); break; case t_mpr: l->t = t_mpr; mpfr_set_q(orr(l), oqr(l), thr_rnd); mpfr_fmod(orr(l), orr(l), orr(r), thr_rnd); break; default: ovm_raise(except_not_a_real_number); } }
bool QQ::lower_associate_divisor(ring_elem &f, const ring_elem g) const { gmp_QQ a = MPQ_VAL(f); gmp_QQ b = MPQ_VAL(g); int sa = mpq_sgn(a); int sb = mpq_sgn(b); int s = (sa == 0 ? sb : sa); gmp_QQ result = QQ::new_elem(); mpz_gcd(mpq_numref(result), mpq_numref(a), mpq_numref(b)); mpz_lcm(mpq_denref(result), mpq_denref(a), mpq_denref(b)); if (s != mpq_sgn(result)) mpq_neg(result,result); f = MPQ_RINGELEM(result); return true; // the answer could become lower, if a newer g has a larger denom }
void QQ::lower_content(ring_elem &c, const ring_elem g) const { if (is_zero(c)) { c = g; return; } gmp_QQ a = MPQ_VAL(c); gmp_QQ b = MPQ_VAL(g); int sa = mpq_sgn(a); gmp_QQ result = QQ::new_elem(); mpz_gcd(mpq_numref(result), mpq_numref(a), mpq_numref(b)); mpz_lcm(mpq_denref(result), mpq_denref(a), mpq_denref(b)); if (sa != mpq_sgn(result)) mpq_neg(result,result); c = MPQ_RINGELEM(result); }
void mpq_mat_GS(mpq_mat_t mu, mpq_mat_t GS, mpq_mat_t mat){ if ( ( GS->c != mat->c ) || ( GS->r != mat->r ) ){ printf("FLINT exception: dimensions don't match\n"); abort(); } if ( ( mu->r != mu->c) || (mu->r != mat->r) ){ printf("FLINT exception: mu dimensions don't match\n"); abort(); } //I'm going to use mu[0] to store <GS[i], GS[i]> until the end mpq_t temp; mpq_init(temp); long i, j, k; //setting GS[0] := mat[0] for (i = 0; i < mat->c; i++) mpq_set(GS->entries[i], mat->entries[i]); mpq_mat_row_inner_product(mu->entries[0], GS, 0, GS, 0); //mu[i,i] := 1 for (i = 1; i < mu->r; i++) mpq_set_ui(mu->entries[i*mu->c + i], 1L, 1L); for (i = 1; i < mat->r; i++){ //in this loop we want to find GS[i] := mat[i] - sum (mu[i,j]*mat[j]) //start with GS[i] = mat[i] then for each j < i compute mu and subtract for (k = 0; k < mat->c; k++) mpq_set(GS->entries[i*mat->c + k], mat->entries[i*mat->c + k]); for (j = 0; j < i; j++){ //temp will be the numerator of mu[i,j] which is <mat[i], GS[j]> mpq_mat_row_inner_product(temp, mat, i, GS, j); if (mpq_sgn(mu->entries[j]) != 0) mpq_div(mu->entries[i*mu->c + j], temp, mu->entries[j]); else mpq_set_ui(mu->entries[i*mu->c + j], 0L, 1L); //now need GS[i] := GS[i] - mu[i,j]*GS[j] for (k=0; k < mat->c; k++){ //temp = mu[i,j] * GS[j,k] mpq_mul(temp, mu->entries[i*mu->c + j], GS->entries[j*GS->c + k]); mpq_neg(temp, temp); mpq_add(GS->entries[i*GS->c + k], GS->entries[i*GS->c + k], temp); } } if (i+1 < mu->c) mpq_mat_row_inner_product(mu->entries[i], GS, i, GS, i); } mpq_set_ui(mu->entries[0], 1L, 1L); for (k = 1; k < mu->c; k++) mpq_set_ui(mu->entries[k], 0L, 1L); mpq_clear(temp); return; }
static PSResult simple_cols( Lps* lp, Bool* again, int verbose_level) { PSResult res; mpq_t maxobj; int rem_cols = 0; int rem_nzos = 0; Var* var; mpq_init(maxobj); for(var = lp->var_root; var != NULL; var = var->next) { if (var->type == VAR_FIXED && var->size == 0) continue; /* Empty column ? */ if (var->size == 0) { mpq_set(maxobj, var->cost); if (lp->direct == LP_MIN) mpq_neg(maxobj, maxobj); if (mpq_cmp(maxobj, const_zero) > 0) { /* Do we not have an upper bound ? */ if (!HAS_UPPER(var)) { printf("Var %s unbounded\n", var->name); return PRESOLVE_UNBOUNDED; } lps_setlower(var, var->upper); } else if (mpq_cmp(maxobj, const_zero) < 0) { /* Do we not have an lower bound ? */ if (!HAS_LOWER(var)) { printf("Var %s unbounded\n", var->name); return PRESOLVE_UNBOUNDED; } lps_setupper(var, var->lower); } else { assert(mpq_equal(maxobj, const_zero)); /* any value within the bounds is ok */ if (HAS_LOWER(var)) lps_setupper(var, var->lower); else if (HAS_UPPER(var)) lps_setlower(var, var->upper); else { lps_setlower(var, const_zero); lps_setupper(var, const_zero); } } if (verbose_level > 1) printf("Empty var %s fixed\n", var->name); rem_cols++; continue; } /* infeasible bounds ? */ if (var->type == VAR_BOXED && mpq_cmp(var->lower, var->upper) > 0) { printf("Var %s infeasible bounds lower=%g upper=%g\n", var->name, mpq_get_d(var->lower), mpq_get_d(var->upper)); return PRESOLVE_INFEASIBLE; } /* Fixed column ? */ if (var->type == VAR_FIXED) { assert(var->size > 0); rem_cols++; rem_nzos += var->size; remove_fixed_var(lp, var, verbose_level); continue; } /* Column singleton */ if (var->size == 1) { res = handle_col_singleton(lp, var, verbose_level, &rem_cols, &rem_nzos); if (res != PRESOLVE_OKAY) return res; } } assert(rem_cols != 0 || rem_nzos == 0); if (rem_cols > 0) { *again = TRUE; if (verbose_level > 0) printf("Simple col presolve removed %d cols and %d non-zeros\n", rem_cols, rem_nzos); } mpq_clear(maxobj); return PRESOLVE_OKAY; }
/** @name arithmetic @{ */ void negate(ElementType& result,const ElementType& a) const { mpq_neg(&result,&a); }
AlkValue::AlkValue(const QString & str, const QChar & decimalSymbol) : d(new Private) { // empty strings are easy if (str.isEmpty()) { return; } // take care of mixed prices of the form "5 8/16" as well // as own internal string representation QRegExp regExp(QLatin1String("^((\\d+)\\s+|-)?(\\d+/\\d+)")); // +-#2-+ +---#3----+ // +-----#1-----+ if (regExp.indexIn(str) > -1) { d->m_val = qPrintable(str.mid(regExp.pos(3))); d->m_val.canonicalize(); const QString &part1 = regExp.cap(1); if (!part1.isEmpty()) { if (part1 == QLatin1String("-")) { mpq_neg(d->m_val.get_mpq_t(), d->m_val.get_mpq_t()); } else { mpq_class summand(qPrintable(part1)); mpq_add(d->m_val.get_mpq_t(), d->m_val.get_mpq_t(), summand.get_mpq_t()); d->m_val.canonicalize(); } } return; } // qDebug("we got '%s' to convert", qPrintable(str)); // everything else gets down here const QString negChars = QString::fromLatin1("\\-\\(\\)"); const QString validChars = QString::fromLatin1("\\d\\%1%2").arg(decimalSymbol, negChars); QRegExp invCharSet(QString::fromLatin1("[^%1]").arg(validChars)); QRegExp negCharSet(QString::fromLatin1("[%1]").arg(negChars)); QString res(str); // get rid of any character that is not allowed. res.remove(invCharSet); // qDebug("we reduced it to '%s'", qPrintable(res)); // check if number is negative bool isNegative = false; if (res.indexOf(negCharSet) != -1) { isNegative = true; res.remove(negCharSet); } // qDebug("and modified it to '%s'", qPrintable(res)); // if someone uses the decimal symbol more than once, we get // rid of them except the right most one int pos; while (res.count(decimalSymbol) > 1) { pos = res.indexOf(decimalSymbol); res.remove(pos, 1); } // take care of any fractional part pos = res.indexOf(decimalSymbol); int len = res.length(); QString fraction = QString::fromLatin1("/1"); if ((pos != -1) && (pos < len)) { fraction += QString(len - pos - 1, QLatin1Char('0')); res.remove(pos, 1); } // check if the resulting numerator contains any leading zeros ... int cnt = 0; len = res.length() - 1; while (res[cnt] == QLatin1Char('0') && cnt < len) { ++cnt; } // ... and remove them if (cnt) { res.remove(0, cnt); } // in case the numerator is empty, we convert it to "0" if (res.isEmpty()) { res = QLatin1Char('0'); } res += fraction; // looks like we now have a pretty normalized string that we // can convert right away // qDebug("and try to convert '%s'", qPrintable(res)); try { d->m_val = mpq_class(qPrintable(res)); } catch (const std::invalid_argument &) { qWarning("Invalid argument '%s' to mpq_class() in AlkValue. Arguments to ctor: '%s', '%c'", qPrintable(res), qPrintable(str), decimalSymbol.toLatin1()); d->m_val = mpq_class(0); } d->m_val.canonicalize(); // now we make sure that we use the right sign if (isNegative) { d->m_val = -d->m_val; } }
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; }
static void addsubq_overflow_aux (mpfr_exp_t e) { mpfr_t x, y; mpq_t q; mpfr_exp_t emax; int inex; int rnd; int sign, sub; MPFR_ASSERTN (e <= LONG_MAX); emax = mpfr_get_emax (); set_emax (e); mpfr_inits2 (16, x, y, (mpfr_ptr) 0); mpq_init (q); mpfr_set_inf (x, 1); mpfr_nextbelow (x); mpq_set_ui (q, 1, 1); for (sign = 0; sign <= 1; sign++) { for (sub = 0; sub <= 1; sub++) { RND_LOOP(rnd) { unsigned int flags, ex_flags; int inf; inf = rnd == MPFR_RNDA || rnd == (sign ? MPFR_RNDD : MPFR_RNDU); ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0); mpfr_clear_flags (); inex = sub ? mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) : mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd); flags = __gmpfr_flags; if (inex == 0 || flags != ex_flags || (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y))) { printf ("Error in addsubq_overflow_aux(%ld)," " sign = %d, %s\n", (long) e, sign, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); printf ("Got inex = %d, y = ", inex); mpfr_dump (y); printf ("Expected flags:"); flags_out (ex_flags); printf ("Got flags: "); flags_out (flags); exit (1); } } mpq_neg (q, q); } mpfr_neg (x, x, MPFR_RNDN); mpq_neg (q, q); } mpq_clear (q); mpfr_clears (x, y, (mpfr_ptr) 0); set_emax (emax); }
int AB_Value_Negate(AB_VALUE *v) { assert(v); mpq_neg(v->value, v->value); return 0; }
AB_VALUE *AB_Value_fromString(const char *s) { AB_VALUE *v; const char *currency=NULL; int conversion_succeeded = 1; // assume conversion will succeed char *tmpString=NULL; char *p; char *t; char decimalComma; int isNeg=0; if( !s ) { DBG_ERROR(AQBANKING_LOGDOMAIN, "Attempt to convert a NULL value"); return NULL; } tmpString=strdup(s); p=tmpString; while(*p && *p<33) p++; if (*p=='-') { isNeg=1; p++; } else if (*p=='+') { p++; } t=strchr(p, ':'); if (t) { currency=t+1; *t=0; } /* remove thousand's comma */ decimalComma=AB_Value_determineDecimalComma(p); if (decimalComma) { char *s1, *d1; s1=p; d1=p; while(*s1) { register char c; c=*(s1++); if (isdigit(c) || c=='/') *(d1++)=c; else if (c==decimalComma) /* always use '.' as decimal comma */ *(d1++)='.'; } *d1=0; } v=AB_Value_new(); t=strchr(p, '.'); if (t) { // remove comma and calculate denominator unsigned long denominator = 1; char *next; do { next=t+1; *t=*next; if (*next != 0) denominator *= 10; t++; } while (*next); // set denominator to the calculated value mpz_set_ui(mpq_denref(v->value), denominator); // set numerator to the resulting integer string without comma if (mpz_set_str(mpq_numref(v->value), p, 10) == -1) { conversion_succeeded = 0; } } else { /*DBG_ERROR(0, "Scanning this value: %s\n", p);*/ conversion_succeeded = (gmp_sscanf(p, "%Qu", v->value) == 1); } /* set currency (if any) */ if (currency) v->currency=strdup(currency); /* temporary string no longer needed */ free(tmpString); if (!conversion_succeeded) { DBG_ERROR(AQBANKING_LOGDOMAIN, "[%s] is not a valid value", s); AB_Value_free(v); return NULL; } if (isNeg) mpq_neg(v->value, v->value); return v; }
void lp_get_object_value(LP* lp, mpq_t* q) { vector_inner_product(q, lp->c_back, lp->x); mympq_add(*q, *q, lp->c_const); if (lp->maximize == FALSE) mpq_neg(*q, *q); }
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); }
static void eliminate(LUX *lux, LUXWKA *wka, LUXELM *piv, int flag[], mpq_t work[]) { DMP *pool = lux->pool; LUXELM **F_row = lux->F_row; LUXELM **F_col = lux->F_col; mpq_t *V_piv = lux->V_piv; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *R_len = wka->R_len; int *R_head = wka->R_head; int *R_prev = wka->R_prev; int *R_next = wka->R_next; int *C_len = wka->C_len; int *C_head = wka->C_head; int *C_prev = wka->C_prev; int *C_next = wka->C_next; LUXELM *fip, *vij, *vpj, *viq, *next; mpq_t temp; int i, j, p, q; mpq_init(temp); /* determine row and column indices of the pivot v[p,q] */ xassert(piv != NULL); p = piv->i, q = piv->j; /* remove p-th (pivot) row from the active set; it will never return there */ if (R_prev[p] == 0) R_head[R_len[p]] = R_next[p]; else R_next[R_prev[p]] = R_next[p]; if (R_next[p] == 0) ; else R_prev[R_next[p]] = R_prev[p]; /* remove q-th (pivot) column from the active set; it will never return there */ if (C_prev[q] == 0) C_head[C_len[q]] = C_next[q]; else C_next[C_prev[q]] = C_next[q]; if (C_next[q] == 0) ; else C_prev[C_next[q]] = C_prev[q]; /* store the pivot value in a separate array */ mpq_set(V_piv[p], piv->val); /* remove the pivot from p-th row */ if (piv->r_prev == NULL) V_row[p] = piv->r_next; else piv->r_prev->r_next = piv->r_next; if (piv->r_next == NULL) ; else piv->r_next->r_prev = piv->r_prev; R_len[p]--; /* remove the pivot from q-th column */ if (piv->c_prev == NULL) V_col[q] = piv->c_next; else piv->c_prev->c_next = piv->c_next; if (piv->c_next == NULL) ; else piv->c_next->c_prev = piv->c_prev; C_len[q]--; /* free the space occupied by the pivot */ mpq_clear(piv->val); dmp_free_atom(pool, piv, sizeof(LUXELM)); /* walk through p-th (pivot) row, which already does not contain the pivot v[p,q], and do the following... */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { /* get column index of v[p,j] */ j = vpj->j; /* store v[p,j] in the working array */ flag[j] = 1; mpq_set(work[j], vpj->val); /* remove j-th column from the active set; it will return there later with a new length */ if (C_prev[j] == 0) C_head[C_len[j]] = C_next[j]; else C_next[C_prev[j]] = C_next[j]; if (C_next[j] == 0) ; else C_prev[C_next[j]] = C_prev[j]; /* v[p,j] leaves the active submatrix, so remove it from j-th column; however, v[p,j] is kept in p-th row */ if (vpj->c_prev == NULL) V_col[j] = vpj->c_next; else vpj->c_prev->c_next = vpj->c_next; if (vpj->c_next == NULL) ; else vpj->c_next->c_prev = vpj->c_prev; C_len[j]--; } /* now walk through q-th (pivot) column, which already does not contain the pivot v[p,q], and perform gaussian elimination */ while (V_col[q] != NULL) { /* element v[i,q] has to be eliminated */ viq = V_col[q]; /* get row index of v[i,q] */ i = viq->i; /* remove i-th row from the active set; later it will return there with a new length */ if (R_prev[i] == 0) R_head[R_len[i]] = R_next[i]; else R_next[R_prev[i]] = R_next[i]; if (R_next[i] == 0) ; else R_prev[R_next[i]] = R_prev[i]; /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] and store it in the matrix F */ fip = dmp_get_atom(pool, sizeof(LUXELM)); fip->i = i, fip->j = p; mpq_init(fip->val); mpq_div(fip->val, viq->val, V_piv[p]); fip->r_prev = NULL; fip->r_next = F_row[i]; fip->c_prev = NULL; fip->c_next = F_col[p]; if (fip->r_next != NULL) fip->r_next->r_prev = fip; if (fip->c_next != NULL) fip->c_next->c_prev = fip; F_row[i] = F_col[p] = fip; /* v[i,q] has to be eliminated, so remove it from i-th row */ if (viq->r_prev == NULL) V_row[i] = viq->r_next; else viq->r_prev->r_next = viq->r_next; if (viq->r_next == NULL) ; else viq->r_next->r_prev = viq->r_prev; R_len[i]--; /* and also from q-th column */ V_col[q] = viq->c_next; C_len[q]--; /* free the space occupied by v[i,q] */ mpq_clear(viq->val); dmp_free_atom(pool, viq, sizeof(LUXELM)); /* perform gaussian transformation: (i-th row) := (i-th row) - f[i,p] * (p-th row) note that now p-th row, which is in the working array, does not contain the pivot v[p,q], and i-th row does not contain the element v[i,q] to be eliminated */ /* walk through i-th row and transform existing non-zero elements */ for (vij = V_row[i]; vij != NULL; vij = next) { next = vij->r_next; /* get column index of v[i,j] */ j = vij->j; /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ if (flag[j]) { /* v[p,j] != 0 */ flag[j] = 0; mpq_mul(temp, fip->val, work[j]); mpq_sub(vij->val, vij->val, temp); if (mpq_sgn(vij->val) == 0) { /* new v[i,j] is zero, so remove it from the active submatrix */ /* remove v[i,j] from i-th row */ if (vij->r_prev == NULL) V_row[i] = vij->r_next; else vij->r_prev->r_next = vij->r_next; if (vij->r_next == NULL) ; else vij->r_next->r_prev = vij->r_prev; R_len[i]--; /* remove v[i,j] from j-th column */ if (vij->c_prev == NULL) V_col[j] = vij->c_next; else vij->c_prev->c_next = vij->c_next; if (vij->c_next == NULL) ; else vij->c_next->c_prev = vij->c_prev; C_len[j]--; /* free the space occupied by v[i,j] */ mpq_clear(vij->val); dmp_free_atom(pool, vij, sizeof(LUXELM)); } } } /* now flag is the pattern of the set v[p,*] \ v[i,*] */ /* walk through p-th (pivot) row and create new elements in i-th row, which appear due to fill-in */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { j = vpj->j; if (flag[j]) { /* create new non-zero v[i,j] = 0 - f[i,p] * v[p,j] and add it to i-th row and j-th column */ vij = dmp_get_atom(pool, sizeof(LUXELM)); vij->i = i, vij->j = j; mpq_init(vij->val); mpq_mul(vij->val, fip->val, work[j]); mpq_neg(vij->val, vij->val); vij->r_prev = NULL; vij->r_next = V_row[i]; vij->c_prev = NULL; vij->c_next = V_col[j]; if (vij->r_next != NULL) vij->r_next->r_prev = vij; if (vij->c_next != NULL) vij->c_next->c_prev = vij; V_row[i] = V_col[j] = vij; R_len[i]++, C_len[j]++; } else { /* there is no fill-in, because v[i,j] already exists in i-th row; restore the flag, which was reset before */ flag[j] = 1; } } /* now i-th row has been completely transformed and can return to the active set with a new length */ R_prev[i] = 0; R_next[i] = R_head[R_len[i]]; if (R_next[i] != 0) R_prev[R_next[i]] = i; R_head[R_len[i]] = i; } /* at this point q-th (pivot) column must be empty */ xassert(C_len[q] == 0); /* walk through p-th (pivot) row again and do the following... */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { /* get column index of v[p,j] */ j = vpj->j; /* erase v[p,j] from the working array */ flag[j] = 0; mpq_set_si(work[j], 0, 1); /* now j-th column has been completely transformed, so it can return to the active list with a new length */ C_prev[j] = 0; C_next[j] = C_head[C_len[j]]; if (C_next[j] != 0) C_prev[C_next[j]] = j; C_head[C_len[j]] = j; } mpq_clear(temp); /* return to the factorizing routine */ return; }
int main (int argc, char **argv) { mpq_t op1, op2; mp_size_t size; int i; int reps = 10000; FILE *fp; int base; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; size_t nread; tests_start (); rands = RANDS; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpq_init (op1); mpq_init (op2); fp = fopen (FILENAME, "w+"); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 10 + 2; mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_errandomb (mpq_numref(op1), rands, 512L); mpz_errandomb_nonzero (mpq_denref(op1), rands, 512L); mpq_canonicalize (op1); mpz_urandomb (bs, rands, 1); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpq_neg (op1, op1); mpz_urandomb (bs, rands, 16); bsi = mpz_get_ui (bs); base = bsi % 36 + 1; if (base == 1) base = 0; rewind (fp); if (mpq_out_str (fp, base, op1) == 0 || putc (' ', fp) == EOF || fflush (fp) != 0) { printf ("mpq_out_str write error\n"); abort (); } rewind (fp); nread = mpq_inp_str (op2, fp, base); if (nread == 0) { if (ferror (fp)) printf ("mpq_inp_str stream read error\n"); else printf ("mpq_inp_str data conversion error\n"); abort (); } if (nread != ftell(fp)) { printf ("mpq_inp_str nread doesn't match ftell\n"); printf (" nread %lu\n", (unsigned long) nread); printf (" ftell %ld\n", ftell(fp)); abort (); } if (mpq_cmp (op1, op2)) { printf ("ERROR\n"); printf ("op1 = "); debug_mp (op1, -16); printf ("op2 = "); debug_mp (op2, -16); printf ("base = %d\n", base); abort (); } } fclose (fp); unlink (FILENAME); mpz_clear (bs); mpq_clear (op1); mpq_clear (op2); tests_end (); exit (0); }