//Refer to apps_sfdl_gen/fannkuch_cons.h for constants to use in this exogenous //check. bool fannkuchProverExo::exogenous_check(const mpz_t* input, const mpq_t* input_q, int input_size, const mpz_t* output, const mpq_t* output_q, int output_size, mpz_t prime) { bool success = true; #ifdef ENABLE_EXOGENOUS_CHECKING mpq_t *output_recomputed; alloc_init_vec(&output_recomputed, 1); baseline(input_q, input_size, output_recomputed, output_size); success = mpq_class(output_recomputed[0]) == mpq_class(output_q[0]); clear_vec(1, output_recomputed); #else gmp_printf("Exogeneous checking disabled"); #endif return success; };
mpq_class getConvergent(int n) const { if (n == 0) return mpq_class((*this)[0], 1); if (n == 1) return mpq_class((*this)[0] * (*this)[1] + 1, (*this)[1]); mpq_class beforeLast, last((*this)[0], 1); mpq_class current((*this)[0] * (*this)[1] + 1, (*this)[1]); for (int i = 2; i <= n; ++i) { beforeLast = last; last = current; current = getNextConvergent(i, beforeLast, last); } return current; }
expression_tree GCD(const expression_tree::operands_t& ops, enviroment& env) { if ( ops.size() == 0 ) { env.raise_error("GCD", "called without arguments"); return expression_tree::make_operator("GCD", ops); } /*else if ( ops.size() == 1 ) { return ops[0]; }*/ else { bool all_integer = std::find_if( ops.begin(), ops.end(), [](const expression_tree& expr) { return expr.get_type() != expression_tree::EXACT_NUMBER || !is_mpq_integer(expr.get_exact_number()); } ) == ops.end(); if ( all_integer ) { std::vector<mpz_class> integers(ops.size()); for ( unsigned i = 0; i < ops.size(); ++i ) { integers[i] = ops[i].get_exact_number().get_num(); } return expression_tree::make_exact_number( mpq_class( integer_gcd(integers) ) ); } else { return expression_tree::make_operator("GCD", ops); } } }
void fannkuchProverExo::baseline(const mpq_t* input_q, int num_inputs, mpq_t* output_recomputed, int num_outputs) { int L = fannkuch_cons::L; std::vector<mpq_class> Xa(num_inputs); for(int j = 0; j < num_inputs; j++) { Xa[j] = mpq_class(input_q[j]); } int max_flips = 0; for(int i = 0; i < L; i++) { std::vector<mpq_class> stack = Xa; int flips = 0; while(stack[0] != 1) { std::reverse(stack.begin(), stack.begin() + (int)(stack[0].get_d())); flips++; } if (flips > max_flips) { max_flips = flips; } //Advance Xa to the next permutation std::next_permutation(Xa.begin(), Xa.end()); } mpz_set_ui(mpq_numref(output_recomputed[0]), max_flips); }
//----------------------------------------------------------------------------- // utility functions //----------------------------------------------------------------------------- mpq_class MpqFromRational(const Rational &ratio) { mpq_t num; ::mpq_init(num); ::mpz_set_si(mpq_numref(num), ratio.numer); ::mpz_set_si(mpq_denref(num), ratio.denom); return mpq_class(num); }
void insertion_sort_qProverExo::baseline(const mpq_t* input_q, int num_inputs, mpq_t* output_recomputed, int num_outputs) { for (int i=0; i<num_inputs; i++) { mpq_set(output_recomputed[i], input_q[i]); } std::vector<mpq_class> sorted_input(num_inputs); for(int j = 0; j < num_inputs; j++) { sorted_input[j] = mpq_class(output_recomputed[j]); } std::sort(sorted_input.begin(), sorted_input.end()); for(int j = 0; j < num_inputs; j++) mpq_set(output_recomputed[j], sorted_input[j].get_mpq_t()); /*mpq_t temp; alloc_init_scalar(temp); int hole_pos; for (int i=0; i<num_inputs; i++) { mpq_set(temp, output_recomputed[i]); hole_pos = i; while (hole_pos > 0) { int ret = mpq_cmp(temp, output_recomputed[hole_pos - 1]); if (ret < 0) hole_pos = hole_pos - 1; else break; } for (int j=i; j>hole_pos; j--) mpq_set(output_recomputed[j], output_recomputed[j-1]); mpq_set(output_recomputed[hole_pos], temp); } clear_scalar(temp); */ }
expression_tree Power(const expression_tree::operands_t& ops_to_copy, enviroment& env) { expression_tree::operands_t ops(ops_to_copy); if ( ops.size() == 0 ) { return expression_tree::make_exact_number( mpq_class(1) ); } if ( ops.size() == 1 ) { return expression_tree( ops[0] ); } assert( ops.size() == 2 ); assert( ops[0].get_type() != expression_tree::APPROXIMATE_NUMBER ); assert( ops[1].get_type() != expression_tree::APPROXIMATE_NUMBER ); //if exponent is an integer, then there are possible simplifications if ( ops[1].is_integer() ) { //(a^b)^c == a^(bc) if c is an integer if ( ops[0].is_operator("Power") ) { const expression_tree::operands_t& power_ops = ops[0].get_operands(); assert( power_ops.size() == 2 ); ops[1] = expression_tree::make_operator("Times", power_ops[1], ops[1]).evaluate(env); ops[0] = power_ops[0]; } } //x^0 == 0 //x^1 == x //But 0^0 is Indeterminate, TODO!!?? DEBUG : Expand[Det[{{n,n,n},{n+1,n+1,n+2},{n+3,n+2,n+1}}]] if ( ops[1].get_type() == expression_tree::EXACT_NUMBER ) { if ( ops[1].get_exact_number() == 0 ) { if ( ops[0].get_type() == expression_tree::EXACT_NUMBER ) { env.raise_error( "Power", "Indeterminate expression 0^0 encountered." ); return expression_tree::make_symbol( "Indeterminate" ); } else { return expression_tree::make_exact_number( 1 ); } } else if ( ops[1].get_exact_number() == 1 ) { return ops[0]; } } if ( ops[0].get_type() != expression_tree::EXACT_NUMBER || ops[1].get_type() != expression_tree::EXACT_NUMBER ) { return expression_tree::make_operator( "Power", ops ); //nonnumber nonpowering } //TODO check if fits //If the don't fit into these, then why bother calculating? long exponent = 0; unsigned long inverse_exponent = 0; bool exponent_conversion_success = mpz_get_si_checked(exponent, ops[1].get_exact_number().get_num()); bool inverse_exponent_conversion_success = mpz_get_ui_checked(inverse_exponent, ops[1].get_exact_number().get_den()); if ( !exponent_conversion_success || !inverse_exponent_conversion_success ) { env.raise_error( "Power", "exponent overflow" ); return expression_tree::make_operator( "Power", ops ); } if ( ops[0].get_exact_number() < 0 ) { if ( inverse_exponent != 1 ) { env.raise_error( "Power", "can't raise a negative base to a rational exponent" ); return expression_tree::make_symbol( "Indeterminate" ); } } else if ( ops[0].get_exact_number() == 0 ) { if ( exponent > 0 ) { return expression_tree( ops[0] ); // mpq_class(0) why reconstruct? } else if ( exponent == 0 ) { env.raise_error( "Power", "Indeterminate 0^0" ); return expression_tree::make_symbol( "Indeterminate" ); } else { //exponent < 0 env.raise_error( "Power", "Infinite expression 0^-exp" ); return expression_tree::make_symbol( "Infinity" ); } } else { //ops[0].get_exact_number() > 0 //everything is mathOK here } //shortcut for Power[a, -1] if ( exponent == -1 && inverse_exponent == 1 ) { mpq_class result = mpq_class(1) / ops[0].get_exact_number(); return expression_tree::make_exact_number( result ); } bool negative_exponent = false; if ( exponent < 0 ) { negative_exponent = true; exponent = -exponent; } mpq_class resultq = mpq_pow_ui_class( ops[0].get_exact_number(), exponent ); if (negative_exponent) { resultq = mpq_class(1) / resultq; } if ( inverse_exponent == 1 ) { return expression_tree::make_exact_number( resultq ); } else { //ops[1] is now equals 1/d. We did the numerator's job above. //ops[1] = mpq_class( mpz_class(1), ops[1].get_exact_number().get_den() ); //implicit constructor //TODO check if fits //unsigned long inverse_exponent = ops[1].get_exact_number().get_den().get_ui(); mpz_class numerator_result; mpz_class denominator_result; bool numerator_success = mpz_root_class( numerator_result, resultq.get_num(), inverse_exponent); bool denominator_success = mpz_root_class( denominator_result, resultq.get_den(), inverse_exponent); if ( numerator_success && denominator_success ) { mpq_class result( numerator_result, denominator_result ); return expression_tree::make_exact_number( result ); } else if ( numerator_success ) { //&& !denominator_success /* Creating : Times[numerator_result, Power[resultq.get_den(), -1/inverse_exponent]] */ expression_tree::operands_t ops_power; expression_tree::operands_t ops_times; mpq_class negated_exponent( mpq_class(-1)*mpq_class(1, inverse_exponent) ); ops_power.push_back( expression_tree::make_exact_number( mpq_class(resultq.get_den()) ) ); ops_power.push_back( expression_tree::make_exact_number( negated_exponent ) ); //could use 1/inverse_exponent also expression_tree power_expr = expression_tree::make_operator( "Power", ops_power ); //don't have to evaulate, can't do anything anyway if ( numerator_result == 1 ) { return power_expr; } else { ops_times.push_back( expression_tree::make_exact_number( mpq_class(numerator_result) ) ); ops_times.push_back( power_expr ); return expression_tree::make_operator("Times", ops_times)/*.evaluate()*/; } } else if ( denominator_success ) { //&& !numerator_success /* Creating : Times[Power[resultq.get_num(), 1/inverse_exponent], 1/denominator_result] */ expression_tree::operands_t ops_powerlhs; expression_tree::operands_t ops_times; ops_powerlhs.push_back( expression_tree::make_exact_number( mpq_class(resultq.get_num()) ) ); ops_powerlhs.push_back( expression_tree::make_exact_number( mpq_class(1, inverse_exponent) ) ); expression_tree powerlhs_tree = expression_tree::make_operator("Power", ops_powerlhs); if ( denominator_result == 1 ) { return powerlhs_tree; } else { ops_times.push_back( powerlhs_tree ); ops_times.push_back( expression_tree::make_exact_number(mpq_class( mpz_class(1), denominator_result )) ); return expression_tree::make_operator("Times", ops_times)/*.evaluate()*/; //FIXME might evaulate this? no... } } else { //!denominator_success && !numerator_success /* Creating : Power[resultq, exponent/inverse_exponent] */ expression_tree::operands_t ops_power; ops_power.push_back( expression_tree::make_exact_number( resultq ) ); ops_power.push_back( expression_tree::make_exact_number( mpq_class(1, inverse_exponent) ) ); return expression_tree::make_operator("Power", ops_power); } } }
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; } }
AlkValue::AlkValue(const int num, const unsigned int denom) : d(new Private) { d->m_val = mpq_class(num, denom); d->m_val.canonicalize(); }
int main(int argc, char** argv) { std::cin.sync_with_stdio(false); //2^16 = 65536 -> from spec //TODO: check if this value need to be multiplied [base(10) or base(2)] ?? mpf_set_default_prec(65536); if (argc != 2) { std::cout << "Wrong number of parameters!" << std::endl; return -1; } int d = atoi(argv[1]); if (is_debug) { std::cout << "d: " << d << std::endl; } // 1 <= n <= 2^24 (16777216) int n = 0; std::vector<mpq_class> xn; mpq_class tmp; std::string str; while (std::cin >> str) { try { xn.push_back(mpq_class(str)); } catch (...) { std::cout << "Failed with string: " << str << std::endl; } n++; } if (n < 1) { std::cout << "No arguments have been read!" << std::endl; return -1; } if (is_debug) { std::cout << "n: " << n << std::endl; } // Mean value mpq_class sum; for (int i = 0; i < n; ++i) { sum += xn[i]; } mpq_class mean = sum / n; mpf_class f_mean(mean); std::cout << fixTrailingZeros(f_mean, d) << std::endl; // Variance mpq_class first; mpq_class second; for (int i = 0; i < n; ++i) { first += (xn[i] * xn[i]); second += xn[i]; } first /= n; second /= n; second *= second; mpq_class variance = first - second; mpf_class f_variance(variance); std::cout << fixTrailingZeros(f_variance, d) << std::endl; // Period int p = 0; int p_min = n; while (++p) { bool is_valid = true; for (int i = 0; i < n - p; ++i) { if (xn[i] != xn[i+p]) { is_valid = false; break; } } if (is_valid) { p_min = p; break; } } std::cout << p_min << std::endl; return 0; }
mpq_class getNextConvergent(int n, mpq_class c1, mpq_class c2) const { int a = (*this)[n]; return mpq_class(c1.get_num() + a * c2.get_num(), c1.get_den() + a * c2.get_den()); }
// Mul (t**exp) to the dict "d" void Mul::dict_add_term_new(const Ptr<RCP<const Number>> &coef, map_basic_basic &d, const RCP<const Basic> &exp, const RCP<const Basic> &t) { auto it = d.find(t); if (it == d.end()) { // Don't check for `exp = 0` here // `pow` for Complex is not expanded by default if (is_a<Integer>(*t) || is_a<Rational>(*t)) { if (is_a<Integer>(*exp)) { imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(exp))); } else if (is_a<Rational>(*exp)) { // Here we make the exponent postive and a fraction between // 0 and 1. mpz_class q, r, num, den; num = rcp_static_cast<const Rational>(exp)->i.get_num(); den = rcp_static_cast<const Rational>(exp)->i.get_den(); mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(), den.get_mpz_t()); insert(d, t, Rational::from_mpq(mpq_class(r, den))); imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(integer(q)))); } else { insert(d, t, exp); } } else if (is_a<Integer>(*exp) && is_a<Complex>(*t)) { if (rcp_static_cast<const Integer>(exp)->is_one()) { imulnum(outArg(*coef), rcp_static_cast<const Number>(t)); } else if (rcp_static_cast<const Integer>(exp)->is_minus_one()) { idivnum(outArg(*coef), rcp_static_cast<const Number>(t)); } else { insert(d, t, exp); } } else { insert(d, t, exp); } } else { // Very common case, needs to be fast: if (is_a_Number(*exp) && is_a_Number(*it->second)) { RCP<const Number> tmp = rcp_static_cast<const Number>(it->second); iaddnum(outArg(tmp), rcp_static_cast<const Number>(exp)); it->second = tmp; } else it->second = add(it->second, exp); if (is_a<Integer>(*it->second)) { // `pow` for Complex is not expanded by default if (is_a<Integer>(*t) || is_a<Rational>(*t)) { if (!rcp_static_cast<const Integer>(it->second)->is_zero()) { imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(it->second))); } d.erase(it); } else if (rcp_static_cast<const Integer>(it->second)->is_zero()) { d.erase(it); } else if (is_a<Complex>(*t)) { if (rcp_static_cast<const Integer>(it->second)->is_one()) { imulnum(outArg(*coef), rcp_static_cast<const Number>(t)); d.erase(it); } else if (rcp_static_cast<const Integer>(it->second)->is_minus_one()) { idivnum(outArg(*coef), rcp_static_cast<const Number>(t)); d.erase(it); } } } else if (is_a<Rational>(*it->second)) { if (is_a_Number(*t)) { mpz_class q, r, num, den; num = rcp_static_cast<const Rational>(it->second)->i.get_num(); den = rcp_static_cast<const Rational>(it->second)->i.get_den(); // Here we make the exponent postive and a fraction between // 0 and 1. if (num > den || num < 0) { mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(), den.get_mpz_t()); it->second = Rational::from_mpq(mpq_class(r, den)); imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(integer(q)))); } } } } }
QString MyMoneyMoney::formatMoney(const QString& currency, const int prec, bool showThousandSeparator) const { QString res; QString tmpCurrency = currency; int tmpPrec = prec; mpz_class denom = 1; mpz_class value; // if prec == -1 we want the maximum possible but w/o trailing zeroes if (tmpPrec > -1) { while (tmpPrec--) { denom *= 10; } } else { // fix it to a max of 9 digits on the right side for now denom = 1000000000; } // as long as AlkValue::convertDenominator() does not take an // mpz_class as the denominator, we need to use a signed int // and limit the precision to 9 digits (the max we can // present with 31 bits #if 1 signed int d; if (mpz_fits_sint_p(denom.get_mpz_t())) { d = mpz_get_si(denom.get_mpz_t()); } else { d = 1000000000; } value = static_cast<const MyMoneyMoney>(convertDenominator(d)).valueRef().get_num(); #else value = static_cast<const MyMoneyMoney>(convertDenominator(denom)).valueRef().get_num(); #endif // Once we really support multiple currencies then this method will // be much better than using KGlobal::locale()->formatMoney. bool bNegative = false; mpz_class left = value / static_cast<MyMoneyMoney>(convertDenominator(d)).valueRef().get_den(); mpz_class right = mpz_class((valueRef() - mpq_class(left)) * denom); if (right < 0) { right = -right; bNegative = true; } if (left < 0) { left = -left; bNegative = true; } // convert the integer (left) part to a string res.append(left.get_str().c_str()); // if requested, insert thousand separators every three digits if (showThousandSeparator) { int pos = res.length(); while ((0 < (pos -= 3)) && thousandSeparator() != 0) res.insert(pos, thousandSeparator()); } // take care of the fractional part if (prec > 0 || (prec == -1 && right != 0)) { if (decimalSeparator() != 0) res += decimalSeparator(); QString rs = QString("%1").arg(right.get_str().c_str()); if (prec != -1) rs = rs.rightJustified(prec, '0', true); else { rs = rs.rightJustified(9, '0', true); // no trailing zeroes or decimal separators while (rs.endsWith('0')) rs.truncate(rs.length() - 1); while (rs.endsWith(QChar(decimalSeparator()))) rs.truncate(rs.length() - 1); } res += rs; } signPosition signpos = bNegative ? _negativeMonetarySignPosition : _positiveMonetarySignPosition; QString sign = bNegative ? "-" : ""; switch (signpos) { case ParensAround: res.prepend('('); res.append(')'); break; case BeforeQuantityMoney: res.prepend(sign); break; case AfterQuantityMoney: res.append(sign); break; case BeforeMoney: tmpCurrency.prepend(sign); break; case AfterMoney: tmpCurrency.append(sign); break; } if (!tmpCurrency.isEmpty()) { if (bNegative ? _negativePrefixCurrencySymbol : _positivePrefixCurrencySymbol) { res.prepend(' '); res.prepend(tmpCurrency); } else { res.append(' '); res.append(tmpCurrency); } } return res; }