/* r = sqrt(x) */ void my_sqrt_ui(mpf_t r, unsigned long x) { unsigned long prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0<=DOUBLE_PREC) { mpf_set_d(r, sqrt(x)); return; } bits = 0; for (prec=prec0; prec>DOUBLE_PREC;) { int bit = prec&1; prec = (prec+bit)/2; bits = bits*2+bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_set_d(t1, 1/sqrt(x)); while (prec<prec0) { prec *=2; if (prec<prec0) { /* t1 = t1+t1*(1-x*t1*t1)/2; */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, t1, t1); /* half x half -> full */ mpf_mul_ui(t2, t2, x); mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_div_2exp(t2, t2, 1); mpf_mul(t2, t2, t1); /* half x half -> half */ mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { break; } prec -= (bits&1); bits /=2; } /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */ mpf_set_prec_raw(t2, prec0/2); mpf_mul_ui(t2, t1, x); mpf_mul(r, t2, t2); /* half x half -> full */ mpf_ui_sub(r, x, r); mpf_mul(t1, t1, r); /* half x half -> half */ mpf_div_2exp(t1, t1, 1); mpf_add(r, t1, t2); }
void *calc_y(thr_gmpf_t *vars) { /*vars.y1 = (1-sqrt(sqrt((1-pow(vars.y0,4))))) / (1+sqrt(sqrt(1-pow(vars.y0,4))));*/ /*b = sqrt(sqrt(1-y0^4))*/ mpf_pow_ui(vars->y1,vars->y0,4); /*y1 = pow(y0,4)*/ mpf_ui_sub(vars->y1,1,vars->y1); /*y1 = 1 - y1*/ mpf_sqrt(vars->y1,vars->y1); mpf_sqrt(vars->y1,vars->y1); /*y1 = 1-b/1+b*/ mpf_ui_sub(vars->aux_y1,1,vars->y1); mpf_add_ui(vars->aux_y2,vars->y1,1); mpf_div(vars->y1,vars->aux_y1,vars->aux_y2); pthread_exit(NULL); return NULL; }
void correction_factor_Q(mpf_t Q, int N,mpf_t rho,int k){ unsigned long int f; mpf_t tmp,tmp1,tmp2; /* if (PNK_N_1_rho_1_PN == 0) cout << "Algun factor es 0 N = " << N << " rho = " << rho << " k = " << k << " P__0 = " << P__0 << " P__N = " << P__N << endl; */ mpf_init(tmp); mpf_init_set_d(tmp1,pow(N,k-1)); // N^(k-1) f = 1; mpf_set_ui(Q,0); for (unsigned long int j = k;j < N;j++) { /*Q += (N - j) * pow(N,j) * pow(rho,j - k) * P__0 * N_k_1 / (factorial(j - k) * PNK_N_1_rho_1_PN); */ /* Q += [(N - j) * N^j * rho^(j - k) / (j - k)!] * P__0 * N_k_1 / PNK_N_1_rho_1_PN; */ mpf_mul_ui(tmp1,tmp1,N); // * N if (j - k > 1) mpf_div_ui(tmp1,tmp1,j - k); // / (j - k) mpf_mul_ui(tmp,tmp1,N - j); // * (N - j) mpf_add(Q,Q,tmp); // Q += (N - j) * N^j * rho^(j - k) / (j - k)! mpf_mul(tmp1,tmp1,rho); // * rho } mpf_init(tmp2); mpf_ui_sub(tmp2,1,P__N); // 1 - P__N mpf_pow_ui(tmp1,tmp2,k); // (1 - P__N)^k mpf_mul(tmp2,tmp2,rho); // rho * (1 - P__N) mpf_ui_sub(tmp2,1,tmp2); // 1 - rho * (1 - P__N) mpf_mul(Q,Q,P__0); // * P__0 mpf_mul_ui(Q,Q,factorial(N-k-1)); // * (N - k - 1)! /* pow(1 - P__N,k) * factorial(N) * (1 - rho * (1 - P__N)) */ mpf_mul(tmp2,tmp1,tmp2); // (1 - P__N)^k * (1 - rho * (1 - P__N)) mpf_mul_ui(tmp2,tmp2,factorial(N)); // (1 - P__N)^k * (1 - rho * (1 - P__N)) * N! mpf_div(Q,Q,tmp2); // / [(1 - P__N)^k * (1 - rho * (1 - P__N)) * N!] mpf_clear(tmp); mpf_clear(tmp1); mpf_clear(tmp2); }
// r = sqrt(x) void my_sqrt(mpf_t r, mpf_t x) { unsigned prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0 <= DOUBLE_PREC) { mpf_set_d(r, sqrt(mpf_get_d(x))); return; } bits = 0; for (prec = prec0; prec > DOUBLE_PREC;) { int bit = prec & 1; prec = (prec + bit) / 2; bits = bits * 2 + bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_set_d(t1, 1 / sqrt(mpf_get_d(x))); while (prec < prec0) { prec *= 2; /*printf("prec=%d, prec0=%d\n", prec, prec0); */ if (prec < prec0) { /* t1 = t1+t1*(1-x*t1*t1)/2; */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, t1, t1); mpf_set_prec_raw(x, prec/2); mpf_mul(t2, t2, x); mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_div_2exp(t2, t2, 1); mpf_mul(t2, t2, t1); mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { prec = prec0; /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */ mpf_set_prec_raw(t2, prec/2); mpf_set_prec_raw(x, prec/2); mpf_mul(t2, t1, x); mpf_mul(r, t2, t2); mpf_set_prec_raw(x, prec); mpf_sub(r, x, r); mpf_mul(t1, t1, r); mpf_div_2exp(t1, t1, 1); mpf_add(r, t1, t2); break; } prec -= (bits & 1); bits /= 2; } }
void ks_table (mpf_t p, mpf_t val, const unsigned int n) { /* We use Eq. (27), Knuth p.58, skipping O(1/n) for simplicity. This shortcut will result in too high probabilities, especially when n is small. Pr(Kp(n) <= s) = 1 - pow(e, -2*s^2) * (1 - 2/3*s/sqrt(n) + O(1/n)) */ /* We have 's' in variable VAL and store the result in P. */ mpf_t t1, t2; mpf_init (t1); mpf_init (t2); /* t1 = 1 - 2/3 * s/sqrt(n) */ mpf_sqrt_ui (t1, n); mpf_div (t1, val, t1); mpf_mul_ui (t1, t1, 2); mpf_div_ui (t1, t1, 3); mpf_ui_sub (t1, 1, t1); /* t2 = pow(e, -2*s^2) */ #ifndef OLDGMP mpf_pow_ui (t2, val, 2); /* t2 = s^2 */ mpf_set_d (t2, exp (-(2.0 * mpf_get_d (t2)))); #else /* hmmm, gmp doesn't have pow() for floats. use doubles. */ mpf_set_d (t2, pow (M_E, -(2 * pow (mpf_get_d (val), 2)))); #endif /* p = 1 - t1 * t2 */ mpf_mul (t1, t1, t2); mpf_ui_sub (p, 1, t1); mpf_clear (t1); mpf_clear (t2); }
static void Pks (mpf_t p, mpf_t x) { double dt; /* temp double */ mpf_set (p, x); mpf_mul (p, p, p); /* p = x^2 */ mpf_mul_ui (p, p, 2); /* p = 2*x^2 */ mpf_neg (p, p); /* p = -2*x^2 */ /* No pow() in gmp. Use doubles. */ /* FIXME: Use exp()? */ dt = pow (M_E, mpf_get_d (p)); mpf_set_d (p, dt); mpf_ui_sub (p, 1, p); }
// r = y/x WARNING: r cannot be the same as y. void my_div(mpf_t r, mpf_t y, mpf_t x) { unsigned long prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0<=DOUBLE_PREC) { mpf_set_d(r, mpf_get_d(y)/mpf_get_d(x)); return; } bits = 0; for (prec=prec0; prec>DOUBLE_PREC;) { int bit = prec&1; prec = (prec+bit)/2; bits = bits*2+bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_ui_div(t1, 1, x); while (prec<prec0) { prec *=2; if (prec<prec0) { /* t1 = t1+t1*(1-x*t1); */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, x, t1); // full x half -> full mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t2, t1); // half x half -> half mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { prec = prec0; /* t2=y*t1, t1 = t2+t1*(y-x*t2); */ mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t1, y); // half x half -> half mpf_mul(r, x, t2); // full x half -> full mpf_sub(r, y, r); mpf_mul(t1, t1, r); // half x half -> half mpf_add(r, t1, t2); break; } prec -= (bits&1); bits /=2; } }
// The Brent-Salamin algorithm int main(int argc, char* argv[]) { if (argc < 2) return -1; int n = (int)strtol(argv[1], NULL, 10); mpf_set_default_prec(1000); mpf_t a, b, t, c, sum; // a=1 mpf_init_set_ui(a, 1); mpf_init_set_ui(sum, 0); mpf_init(b); mpf_init(t); mpf_init(c); mpf_init(sum); // b=1/sqrt(2) mpf_sqrt_ui(b, 2); mpf_ui_div(b, 1, b); // n次迭代的误差小于\frac{2^{n+9}}{20^{2n+1}} for (int i = 1; i <= n; ++i) { // t=(a+b)/2 mpf_add(t, a, b); mpf_div_ui(t, t, 2); // b=sqrt(a*b); mpf_mul(b, a, b); mpf_sqrt(b, b); // a=t mpf_swap(t, a); mpf_mul(t, a, a); mpf_mul(c, b, b); mpf_sub(c, t, c); mpf_mul_2exp(c, c, i + 1); mpf_add(sum, sum, c); } mpf_mul(t, a, a); mpf_mul_ui(t, t, 4); mpf_ui_sub(sum, 1, sum); mpf_div(t, t, sum); mpf_out_str(stdout, 10, 0, t); printf("\n"); mpf_clear(a); mpf_clear(b); mpf_clear(t); mpf_clear(c); mpf_clear(sum); return 0; }
int main() { pthread_t thread_a, thread_b; /* My threads*/ int i; FILE *filePi, *fileTime; clock_t start, end; double cpu_time_used; mpf_set_default_prec(BITS_PER_DIGIT * 11000000); /* Borwein Variable Initialization */ for(i=0; i<2; i++) for(j=0; j<2; j++) mpf_init(params[i][j]); mpf_init(real_pi); mpf_init(y0Aux); mpf_init(y0Aux2); mpf_init(a0Aux); mpf_init(a0Aux2); mpf_init(pi[0]); mpf_init(pi[1]); mpf_init_set_str(error, "1e-10000000", 10); /* Initial value setting */ mpf_sqrt_ui(params[A][0], 2.0); /* a0 = sqrt(2)*/ mpf_mul_ui(params[A][0], params[A][0], 4.0); /* a0 = 4 * sqrt(2) */ mpf_ui_sub(params[A][0], 6.0, params[A][0]); /* a0 = 6 - 4 * sqrt(2) */ mpf_sqrt_ui(params[Y][0], 2.0); /* y0 = sqrt(2) */ mpf_sub_ui(params[Y][0], params[Y][0], 1.0); /* y0 = sqrt(2) - 1 */ mpf_set_ui(pi[0], 0); mpf_set_ui(pi[1], 0); i = 1; j = 1; iteracoes = 0; x = 0; /* Load the reals digits of pi */ filePi = fopen("pi.txt", "r"); gmp_fscanf(filePi, "%Ff", real_pi); fclose(filePi); start = clock(); while(1){ /* y = ( 1 - (1 - y0 ^ 4) ^ 0.25 ) / ( 1 + ( 1 - y0 ^ 4) ^ 0.25 ) */ mpf_pow_ui(y0Aux, params[Y][0], 4); mpf_ui_sub(y0Aux, 1.0, y0Aux); mpf_sqrt(y0Aux, y0Aux); mpf_sqrt(y0Aux, y0Aux); mpf_add_ui(y0Aux2, y0Aux, 1.0); mpf_ui_sub(y0Aux, 1.0, y0Aux); mpf_div(params[Y][1], y0Aux, y0Aux2); /* a = a0 * ( 1 + params[Y][1] ) ^ 4 - 2 ^ ( 2 * i + 3 ) * params[Y][1] * ( 1 + params[Y][1] + params[Y][1] ^ 2 ) */ /* Threads creation */ pthread_create(&thread_a, NULL, calc_a, NULL); pthread_create(&thread_b, NULL, calc_b, NULL); pthread_join(thread_a, NULL); pthread_join(thread_b, NULL); /* 2 ^ ( 2 * i + 3 ) * params[Y][1] * ( 1 + params[Y][1] + params[Y][1] ^ 2 ) */ mpf_mul(a0Aux, a0Aux, a0Aux2); /*a0 * ( 1 + params[Y][1] ) ^ 4*/ mpf_add_ui(a0Aux2, params[Y][1], 1); mpf_pow_ui(a0Aux2, a0Aux2, 4); mpf_mul(a0Aux2, params[A][0], a0Aux2); /* form the entire expression */ mpf_sub(params[A][1], a0Aux2, a0Aux); mpf_set(params[A][0], params[A][1]); mpf_set(params[Y][0], params[Y][1]); mpf_ui_div(pi[j], 1, params[A][0]); gmp_printf("\nIteracao %d | pi = %.25Ff", iteracoes, pi[j]); /* Calculate the error */ mpf_sub(pi[(j+1)%2], real_pi, pi[j]); mpf_abs(pi[(j+1) % 2], pi[(j+1) % 2]); if(mpf_cmp(pi[(j+1)%2], error) < 0){ printf("\n%d iteracoes para alcancar 10 milhoes de digitos de corretos.", iteracoes); break; } j = (j+1) % 2; iteracoes++; i++; } end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; fileTime = fopen("execution_time.txt", "w"); fprintf(fileTime, "Execution time: %f\n", cpu_time_used); fclose(fileTime); /* Clean up*/ for(i=0; i<2; i++) for(j=0; j<2; j++) mpf_clear(params[i][j]); mpf_clear(pi[0]); mpf_clear(pi[1]); mpf_clear(real_pi); mpf_clear(error); return 0; }
void jarvis_hypercube_approximation (int C, /* Number of types of customers*/ int N, /* Number of servers */ mpf_t *lambda, /* arrive rate according to a Poisson process per type */ mpf_t **Tao, /* expected service time for service i and customer of node m */ int **a, /* for customers of type m, the list of preferred servers */ mpf_t **f) { mpf_t Lambda; mpf_t Rho; mpf_t tao; mpf_t *rho; mpf_t *new_rho; mpf_t *Q_N_rho; mpf_t max_change; mpf_t tmp; mpf_init(Lambda); rho = new mpf_t [N]; for (int i = 0; i < N;i++) mpf_init(rho[i]); mpf_init(tao); mpf_init_set_ui(P__0,1); mpf_init_set_ui(P__N,1); Q_N_rho = new mpf_t [N]; for (int i = 0;i < N;i++) mpf_init(Q_N_rho[i]); new_rho = new mpf_t [N]; for (int i = 0;i < N;i++) mpf_init(new_rho[i]); mpf_init(Rho); mpf_init(max_change); mpf_init(tmp); /* INITIALIZE: */ for (int m = 0;m < C;m++) mpf_add(Lambda,Lambda,lambda[m]); /* Busy probability rho_i */ for (int i = 0; i < N;i++) { for (int m = 0; m < C;m++) { if (a[m][0] == i) { mpf_mul(tmp,lambda[m],Tao[i][m]); mpf_add(rho[i],rho[i],tmp); } } } /* mean service time 'tao' */ for (int m = 0;m < C;m++) { mpf_mul(tmp,lambda[m],Tao[a[m][0]][m]); mpf_add(tao,tao,tmp); } mpf_div(tao,tao,Lambda); /* Define intial values for P__0 and P__N */ for (int i = 0;i < N;i++) { mpf_ui_sub(tmp,1,rho[i]); mpf_mul(P__0,P__0,tmp); } for (int i = 0;i < N;i++) mpf_mul(P__N,P__N,rho[i]); /* ITERATION: */ do { /* cout << "'rho_i':"; for (int i = 0;i < N;i++) cout << " " << mpf_get_d(rho[i]); cout << endl; */ /* traffic intensity */ mpf_mul(Rho,Lambda,tao); mpf_div_ui(Rho,Rho,N); /* Compute Q(N,'rho',k) */ for (int k = 0;k < N;k++) correction_factor_Q(Q_N_rho[k],N,Rho,k); /* Compute f_{im} */ mpf_t rho_a_ml; mpf_init(rho_a_ml); for (int i = 0;i < N;i++) { for (int m = 0;m < C;m++) { mpf_set_ui(rho_a_ml,1); for (int k = 0;k < N;k++) { if (a[m][k] == i) { mpf_ui_sub(tmp,1,rho[i]); mpf_mul(tmp,tmp,rho_a_ml); mpf_mul(f[i][m],tmp,Q_N_rho[k]); break; } mpf_mul(rho_a_ml,rho_a_ml,rho[a[m][k]]); } } } mpf_clear(rho_a_ml); /* Aproximation of 'rho'_i */ mpf_t Vi; mpf_init(Vi); mpf_init(rho_a_ml); for (int i = 0;i < N;i++) { mpf_set_ui(Vi,0); for (int m = 0;m < C;m++) { mpf_set_ui(rho_a_ml,1); for (int k = 0;k < N;k++) { if (a[m][k] == i) { mpf_mul(tmp,lambda[m],Tao[i][m]); mpf_mul(tmp,tmp,Q_N_rho[k]); mpf_mul(tmp,tmp,rho_a_ml); mpf_add(Vi,Vi,tmp); /* Vi += lambda[m] * Tao[i][m] * Q_N_rho[k] * rho_a_ml */ break; } mpf_mul(rho_a_ml,rho_a_ml,rho[a[m][k]]); } } mpf_add_ui(tmp,Vi,1); mpf_div(new_rho[i],Vi,tmp); } mpf_clear(rho_a_ml); mpf_clear(Vi); /* Convergence criterion */ mpf_set_ui(max_change,0); for (int i = 0;i < N;i++) { mpf_sub(tmp,rho[i],new_rho[i]); mpf_abs(tmp,tmp); if (mpf_cmp(tmp,max_change) > 0) mpf_set(max_change,tmp); } /* cout << "max change = " << mpf_get_d(max_change); if (mpf_cmp_d(max_change,JARVIS_EPSILON) < 0) cout << " **STOP**" << endl; else cout << "\r"; */ if (mpf_cmp_d(max_change,JARVIS_EPSILON) < 0) break; /* STOP */ for (int i = 0;i < N;i++) mpf_set(rho[i],new_rho[i]); /* Compute P__0 */ mpf_set_ui(P__0,1); for (int i = 0;i < N;i++) { mpf_ui_sub(tmp,1,rho[i]); mpf_mul(P__0,P__0,tmp); } /* Compute P__N */ mpf_t s_rho; mpf_init(s_rho); for (int i = 0;i < N;i++) mpf_add(s_rho,s_rho,rho[i]); mpf_div_ui(tmp,s_rho,N); mpf_div(tmp,tmp,Rho); mpf_ui_sub(P__N,1,tmp); /* Compute mean service time 'tao' */ mpf_t aux; mpf_set_ui(tao,0); mpf_init(aux); for (int m = 0;m < C;m++) { mpf_set_ui(tmp,0); for (int i = 0;i < N;i++) { mpf_mul(aux,Tao[i][m],f[i][m]); mpf_add(tmp,tmp,aux); } mpf_mul(tmp,lambda[m],tmp); mpf_add(tao,tao,tmp); } mpf_div(tao,tao,Lambda); // / Lambda mpf_ui_sub(aux,1,P__N); // 1 - P__N mpf_div(tao,tao,aux); // / (1 - P__N) mpf_clear(aux); } while (1); /* cout << "finsh jarvis" << endl; for (int i = 0;i < N;i++) { for (int m = 0;m < C;m++) { cout << mpf_get_d(f[i][m]) << " "; } cout << endl; } */ mpf_clear(tmp); mpf_clear(max_change); mpf_clear(Rho); for (int i = 0;i < N;i++) mpf_clear(new_rho[i]); delete [] new_rho; for (int i = 0;i < N;i++) mpf_clear(Q_N_rho[i]); delete [] Q_N_rho; mpf_clear(P__N); mpf_clear(P__0); mpf_clear(tao); for (int i = 0;i < N;i++) mpf_clear(rho[i]); delete [] rho; mpf_clear(Lambda); }
/** * Algoritmo de Borwein * * a1 se aproxima do valor de 1/PI. * Cada iteração quadruplica o número de dígitos corretos. * */ void gmp_borwein() { /*variáveis para calculo com respectivos valores iniciais*/ mpf_t a0, a1, y0, y1, aux1, aux2; /*contador de iterações*/ long unsigned int k=0; //mpf_set_default_prec(33220); /*define a precisao do float em bits*/ mpf_set_default_prec(33219280);//(33219280); /*define a precisao do float em bits*/ mpf_init(a0),mpf_init(a1),mpf_init(y0),mpf_init(y1),mpf_init(aux1),mpf_init(aux2); /*Inicializa as variáveis em 0*/ /*seta os valores inicias das váriaveis de precisão variável*/ /*a0 = 6-4*sqrt(2)*/ mpf_set_ui(aux1,2); mpf_sqrt(aux1,aux1); /*sqrt(2)*/ mpf_mul_ui(a0,aux1,4); mpf_ui_sub(a0,6,a0); //mpf_set_d(a0, 6-4*sqrt(2)); mpf_sub_ui(y0,aux1,1); /*y0 = sqrt(2)-1*/ while(k<12) { /*y1 = (1-sqrt(sqrt((1-pow(y0,4))))) / (1+sqrt(sqrt(1-pow(y0,4))));*/ mpf_pow_ui(y1,y0,4); /*y1 = pow(y0,4)*/ mpf_ui_sub(y1,1,y1); /*y1 = 1 - y1*/ mpf_sqrt(y1,y1); mpf_sqrt(y1,y1); mpf_ui_sub(aux1,1,y1); mpf_add_ui(aux2,y1,1); mpf_div(y1,aux1,aux2); /*a1 = a0*pow(1 + y1,4) - pow(2,2*k+3)*y1*(1+y1+pow(y1,2));*/ mpf_add_ui(a1,y1,1); /*a1 = y1+1*/ mpf_pow_ui(a1,a1,4); /*a1 = a1^4*/ mpf_mul(a1,a0,a1); /*a1 = a0*a1*/ mpf_pow_ui(aux2,y1,2); /*aux2 = pow(y1,2)*/ mpf_add(aux2,aux2,y1); /*aux2 += y1*/ mpf_add_ui(aux2,aux2,1); /*aux2++*/ mpf_mul(aux2,aux2,y1); /*aux2 *= y1*/ mpf_set_ui(aux1,2); /* aux1=2 */ mpf_pow_ui(aux1,aux1,2*k+3); /* aux1 = pow(aux1,2*k+3)*/ mpf_mul(aux1,aux1,aux2); /*aux1 = aux1*aux2*/ mpf_sub(a1,a1,aux1); /*troca os valores das variáveis de maneira eficiente*/ mpf_swap(a0,a1); mpf_swap(y0,y1); k++; /*gmp_printf("k=%ld, y1=%.*Ff, 1/PI=%.*Ff\n", k, 20, y1, 20, a1); gmp_printf("a0=%.*Ff, y0=%.*Ff\n", 20, a0, 20, y0);*/ } mpf_ui_div(a1,1,a1); /*PI=1/a1*/ gmp_printf("%.*Ff\n",10000000,a1); mpf_clear(a0),mpf_clear(a1),mpf_clear(y0),mpf_clear(y1),mpf_clear(aux1),mpf_clear(aux2); /*Limpa as variáveis da memória*/ }
int main () { int i = 0; /*Contador de iterações*/ int k = 8; /*Fator de multiplicação*/ mpf_t pi_pas, pi_novo; mpf_t a_pas, a_novo; mpf_t y_pas, y_novo; mpf_t temp1, temp2; mpf_t e; FILE *fileTime; /*Ponteiro do arquivo de saída*/ clock_t start, end; double cpu_time_used; mpf_set_default_prec(BITS_PER_DIGIT * 11000000); /*Precisão default*/ /*Inicialização das variáveis*/ mpf_init(pi_pas); mpf_init(pi_novo); mpf_init(a_pas); mpf_init(y_pas); mpf_init(temp1); mpf_init(temp2); mpf_init_set_d(a_novo, 32.0); mpf_sqrt(a_novo, a_novo); mpf_ui_sub(a_novo, 6, a_novo); mpf_init_set_d(y_novo, 2.0); mpf_sqrt(y_novo, y_novo); mpf_sub_ui(y_novo, y_novo, 1); mpf_init_set_str(e, "1e-10000000", 10); mpf_ui_div(pi_novo, 1, a_novo); start = clock(); /*Calcula as iterações*/ do { mpf_swap(pi_pas, pi_novo); mpf_swap(a_pas, a_novo); mpf_swap(y_pas, y_novo); mpf_pow_ui(y_pas, y_pas, 4); mpf_ui_sub(y_pas, 1, y_pas); mpf_sqrt(y_pas, y_pas); mpf_sqrt(y_pas, y_pas); mpf_add_ui(temp1, y_pas, 1); mpf_ui_sub(y_novo, 1, y_pas); mpf_div(y_novo, y_novo, temp1); mpf_add_ui(temp1, y_novo, 1); mpf_pow_ui(temp2, y_novo, 2); mpf_add(temp2, temp2, temp1); mpf_mul(temp2, temp2, y_novo); mpf_mul_ui(temp2, temp2, k); k *= 4; mpf_pow_ui(temp1, temp1, 4); mpf_mul(temp1, temp1, a_pas); mpf_sub(a_novo, temp1, temp2); mpf_ui_div(pi_novo, 1, a_novo); mpf_sub(pi_pas, pi_novo, pi_pas); mpf_abs(pi_pas, pi_pas); gmp_printf("\nIteracao %d | pi = %.25Ff", i, pi_novo); i++; } while ( mpf_cmp(e, pi_pas) < 0 ); end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; fileTime = fopen("execution_time.txt", "w"); fprintf(fileTime, "Execution time: %f\n", cpu_time_used); fclose(fileTime); /*Libera espaço de memória*/ mpf_clear(pi_pas); mpf_clear(pi_novo); mpf_clear(a_pas); mpf_clear(a_novo); mpf_clear(y_pas); mpf_clear(y_novo); mpf_clear(temp1); mpf_clear(temp2); mpf_clear(e); return 0; }
/** * Algoritmo de Borwein * * vars.a1 se aproxima do valor de 1/PI. * Cada iteração quadruplica o número de dígitos corretos. * */ void gmp_borwein_par() { /*threads*/ pthread_t init[9], calc[4]; /*variáveis para calculos*/ thr_gmpf_t vars; mpf_set_default_prec(33219280);//(33219280); /*define a precisao do float em bits*/ vars.k = 0; /*Seta o valor inicial do iterador*/ calc[1] = 0; calc[3] = 0; /*Inicializa as variáveis em 0*/ pthread_create(&init[0],NULL,(void *)&mpf_init,(void *)&vars.a0); pthread_create(&init[1],NULL,(void *)&mpf_init,(void *)&vars.a1); pthread_create(&init[2],NULL,(void *)&mpf_init,(void *)&vars.y0); pthread_create(&init[3],NULL,(void *)&mpf_init,(void *)&vars.y1); pthread_create(&init[4],NULL,(void *)&mpf_init,(void *)&vars.aux_y1); pthread_create(&init[5],NULL,(void *)&mpf_init,(void *)&vars.aux_y2); pthread_create(&init[6],NULL,(void *)&mpf_init,(void *)&vars.aux_a1); pthread_create(&init[7],NULL,(void *)&mpf_init,(void *)&vars.aux_a2); pthread_create(&init[8],NULL,(void *)&mpf_init,(void *)&vars.y_valoratual); /*A função espera as variáveis serem atualizadas*/ pthread_join(init[0],NULL); pthread_join(init[1],NULL); pthread_join(init[2],NULL); pthread_join(init[3],NULL); pthread_join(init[4],NULL); pthread_join(init[5],NULL); pthread_join(init[6],NULL); pthread_join(init[7],NULL); pthread_join(init[8],NULL); /*TODO: verificar se é possível fazer os cálculos abaixo assim que a variável for inicializada acima*/ /*seta os valores inicias das váriaveis de precisão variável*/ /*d = sqrt(2)*/ mpf_set_ui(vars.aux_y1,2); mpf_sqrt(vars.aux_y1,vars.aux_y1); /*a0 = 6-4*d*/ mpf_mul_ui(vars.a0,vars.aux_y1,4); mpf_ui_sub(vars.a0,6,vars.a0); mpf_set(vars.a1,vars.a0); //a1=a0 /*y0 = d-1*/ mpf_sub_ui(vars.y0,vars.aux_y1,1); /*vars.y0 = sqrt(2)-1*/ while(vars.k<12) { /*Certifica que o valor de y está atualizado antes de calcular o próximo valor de y*/ if(calc[3] != 0) pthread_join(calc[3],NULL); pthread_create(&calc[0], NULL, (void *) &calc_y, (void *)&vars); //calcula valor de y-> nao depende de a nem de k, só do y anterior /*Certifica que a já foi calculado antes de fazer a0=a1*/ if(calc[1] != 0) pthread_join(calc[1],NULL); pthread_create(&calc[2], NULL, (void *) &mpf_seta_thread, (void *)&vars); //troca o valor de a pthread_join(calc[0],NULL); mpf_set(vars.y_valoratual,vars.y1); //seta o valor de y que será usado para calcular a /*Troca o valor de y0=y1*/ pthread_create(&calc[3], NULL, (void *) &mpf_sety_thread, (void *)&vars); pthread_join(calc[2],NULL); /*Calcula o novo valor de a*/ pthread_create(&calc[1], NULL, (void *) &calc_a, (void *)&vars); } mpf_ui_div(vars.a1,1,vars.a1); /*PI=1/vars.a1*/ gmp_printf("%.*Ff\n",10000000,vars.a1); /*Limpa as variáveis da memória*/ mpf_clear(vars.a0),mpf_clear(vars.a1),mpf_clear(vars.y0),mpf_clear(vars.y1); mpf_clear(vars.aux_y1),mpf_clear(vars.aux_y2),mpf_clear(vars.aux_a1),mpf_clear(vars.aux_a2); mpf_clear(vars.y_valoratual); }