Advertisement
Guest User

Untitled

a guest
Jun 9th, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cstdlib>
  2. #include <string>
  3. #include <iostream>
  4. #include <boost/cstdint.hpp>
  5. #include <boost/integer.hpp>
  6. #include <gmp.h>
  7.  
  8. using namespace std;
  9. using namespace boost;
  10.  
  11. typedef struct sol {
  12.     mpz_t p;
  13.     mpz_t q;
  14. } sol_t;
  15.  
  16. // Left classifier
  17. void lc(mpz_t * l, const mpz_t * x1, const mpz_t * x2) {
  18.     mpz_t sub1, div1;
  19.     /* Apply l = (((x2-x1)*0.25) + x1 )^2 */
  20.  
  21.     /* Substract low bound from high bound */
  22.     mpz_sub(sub1, *x2, *x1);
  23.     /* Divide by 4 */
  24.     mpz_tdiv_q_2exp(div1, sub1, 2);
  25.     /* Add low bound */
  26.     mpz_add(*l, div1, *x1);
  27.     /* Powerize to 2 */
  28.     mpz_pow_ui(*l, *l, 2);
  29. }
  30.  
  31. void rc(mpz_t * r, const mpz_t * x1, const mpz_t * x2) {
  32.     mpz_t sub1, tmp1, tmp2, sum1, div1;
  33.     /* Apply: ((0.75 * (x2-x1)) + x1)^2 +
  34.               ((2*(0.5  * (x2-x1)) + x1)^2) - lc(x1, x2) -
  35.               ((0.75 * (x2-x1)) + x1)^2 */
  36.     /* Substract low bound from high bound */
  37.     mpz_sub(sub1, *x2, *x1);
  38.     /* Divide by 2 */
  39.     mpz_tdiv_q_2exp(div1, sub1, 1);
  40.     /* Add low bound */
  41.     mpz_add(sum1, div1, *x1);
  42.     /* Powerize to 2 */
  43.     mpz_pow_ui(tmp1, sum1, 2);
  44.     /* Multiply by 2 */
  45.     mpz_mul_2exp(tmp1, tmp1, 1);
  46.     /* Left classifier */
  47.     lc(&tmp2, x1, x2);
  48.     /* Add low bound */
  49.     mpz_sub(*r, tmp1, tmp2);
  50. }
  51.  
  52. void factImpl(const mpz_t * k, mpz_t * l, mpz_t * h) {
  53.     // Continue until granularity is not unity
  54.     mpz_t sub1, div1, tmp1, tmp2;
  55.     while ( mpz_cmp(*h, *l) >= 0 ) {
  56.         /* h - l */
  57.         mpz_sub(sub1, *h, *l);
  58.         /* Divide by 2 */
  59.         mpz_tdiv_q_2exp(div1, sub1, 1);
  60.         /* euclidian left part */
  61.         lc(&tmp1, l, h);
  62.         mpz_sub(tmp1, *k, tmp1);
  63.         mpz_abs(tmp1, tmp1);
  64.         rc(&tmp2, l, h);
  65.         mpz_sub(tmp2, *k, tmp2);
  66.         mpz_abs(tmp2, tmp2);
  67.         if ( mpz_cmp(tmp2, tmp1) > 0 ) {
  68.             mpz_sub(*h, *h, div1);
  69.             if ( mpz_cmp(*l, *h) > 0 ) {
  70.                 mpz_add_ui(*h, *l, 1);
  71.             }
  72.         } else {
  73.             mpz_add_ui(*l, *l, 1);
  74.         }
  75.     }
  76. }
  77.  
  78. void follow_impl(const mpz_t * k,
  79.                  mpz_t * x, mpz_t * y,
  80.                  const int dx, const int dy,
  81.                  const mpz_t * w, const mpz_t * h) {
  82.     mpz_t c, lh, hh, hl, ll, xi, yi, xy, xiy, xyi, xiyi, iix, iiy;
  83.     /* Initial warmup */
  84.     lc(&c, x, y);
  85.     mpz_set_si(iix, dx);
  86.     mpz_set_si(iiy, dy);
  87.     mpz_add(xi, *x, iix);
  88.     mpz_add(yi, *y, iiy);
  89.     mpz_mul(xy, *x, *y);
  90.     mpz_mul(xiy, xi, *y);
  91.     mpz_mul(xyi, *x, yi);
  92.     mpz_mul(xiyi, xi, yi);
  93.  
  94.     do {
  95.         /* compute ll */
  96.         mpz_sub(ll, xy, *k);
  97.         mpz_abs(ll, ll);
  98.         /* compute hl */
  99.         mpz_sub(hl, xyi, c);
  100.         mpz_abs(hl, hl);
  101.         /* compute lh */
  102.         mpz_sub(lh, xiy, c);
  103.         mpz_abs(lh, lh);
  104.         /* compute hh */
  105.         mpz_sub(hh, xiyi, c);
  106.         mpz_abs(hh, hh);
  107.  
  108.         /* Check if found */
  109.         if ( mpz_sgn(ll) == 0 ) {
  110.             break;
  111.         } else if ( mpz_cmp(hl, hh) > 0 && mpz_cmp(lh, hh) > 0) {
  112.             mpz_add(*x, *x, iix);
  113.             mpz_add(*y, *y, iiy);
  114.         } else if ( mpz_cmp(hl, lh) > 0 ) {
  115.             mpz_add(*x, *x, iix);
  116.         } else {
  117.             mpz_add(*y, *y, iiy);
  118.         }
  119.         mpz_add(xi, *x, iix);
  120.         mpz_add(yi, *y, iiy);
  121.         mpz_mul(xy, *x, *y);
  122.         mpz_mul(xiy, xi, *y);
  123.         mpz_mul(xyi, *x, yi);
  124.         mpz_mul(xiyi, xi, yi);
  125.     } while( mpz_cmp(*w, xi) > 0 && mpz_cmp_ui(xi, 1) > 0 &&
  126.             mpz_cmp(*h, yi) > 0 && mpz_cmp_ui(yi, 1) > 0);
  127. }
  128. void
  129. resolve(const mpz_t * product, sol *prims) {
  130.     mpz_t hl, hh, x, y, pq;   // Hyperbol bounds (low bound and high bound)
  131.  
  132.     mpz_set_ui(prims->p, 0);
  133.     mpz_set_ui(prims->q, 0);
  134.  
  135.     mpz_set(hh, *product);
  136.     factImpl(product, &hl, &hh);
  137.     mpz_set(x, hl);
  138.     mpz_set(y, hh);
  139.     std::cerr << "Analysis hyperbol direction: up-right" << std::endl;
  140.     follow_impl( product, &x, &y, 1, -1, product, product );
  141.     mpz_mul(pq, x, y);
  142.     mpz_set(x, hl);
  143.     mpz_set(y, hh);
  144.     if ( mpz_cmp(pq, *product) != 0) {
  145.         std::cerr << "Analysis hyperbol direction: down-left" << std::endl;
  146.         follow_impl( product, &x, &y, -1, 1, product, product );
  147.         mpz_mul(pq, x, y);
  148.     }
  149.     if ( mpz_cmp(pq, *product) != 0) {
  150.         mpz_set(prims->p, x);
  151.         mpz_set(prims->p, y);
  152.     }
  153. }
  154.  
  155. int main(int argc, char *argv[]) {
  156.     typedef mpz_t bigint_t;
  157.     if(2 == argc) {
  158.         bigint_t pq;
  159.         sol_t res;
  160.         mpz_set_ui(res.p, 0);
  161.         mpz_set_ui(res.q, 0);
  162.         mpz_init_set_str(pq, argv[1], 10);
  163.         resolve(&pq, &res);
  164.         printf("solution: pq = (p*q) =\n");
  165.         mpz_out_str(stdout, 10, res.p);
  166.         printf("\n*\n");
  167.         mpz_out_str(stdout, 10, res.q);
  168.     } else {
  169.         printf("Usage: %s <p*q>\n", argv[0]);
  170.         return -1;
  171.     }
  172.     return 0;
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement