elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Calculo de pi en alta precisión (aporte)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] 3 Ir Abajo Respuesta Imprimir
Autor Tema: Calculo de pi en alta precisión (aporte)  (Leído 13,837 veces)
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #10 en: 10 Abril 2014, 00:06 am »

¡Buenas!

Si te interesa el tema de pi, hay por ahí una formula de Ramanujan que calcula 8 decimales por iteración (era un fiera).

¡Saludos!


En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #11 en: 10 Abril 2014, 01:25 am »

gracias do-while! :P vamos con esa! voy a extender el programa... ya llegué a mi casa, tengo 1,5l de te negro listos y 250g de maní japonés! ese código sale en un rato! :P


En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
1mpuls0


Desconectado Desconectado

Mensajes: 1.186


Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #12 en: 10 Abril 2014, 01:39 am »

próximo a probar:salida concatenada a archivo, tiempo de ejecución, alguna sugerencia?

No sé mucho de c++, apenas estoy en pañales pero tal vez esto te pueda servir.
De hecho la idea viene de un programa que hice en otro lenguaje pero tratando de implementarlo en c++, aunque tal vez necesitas algo más "exacto" (microsegundos, aunque creo que los ordenadores no trabajan a ese nivel)

Además parece haber un fallo en mi método xD

Código
  1. #include <iostream>
  2. #include <ctime>
  3.  
  4. using namespace std;
  5.  
  6. int main() {
  7.  
  8.    clock_t tiempo_inicial = clock();
  9.  
  10.    //Alguna función
  11.    for(int indice=0;indice<=10000;indice=indice+1) {
  12.        std::cout << indice << endl;
  13.    }
  14.    clock_t tiempo_final = clock();
  15.  
  16.    std::cout << float( tiempo_final - tiempo_inicial ) /  CLOCKS_PER_SEC << " segundos";
  17.  
  18.    return 0;
  19. }
  20.  

Lo que me causa intriga es lo siguiente:  :¬¬
Citar
....
10000
1.283 segundos
Process returned 0 (0x0)   execution time : 1.323 s
En línea

abc
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #13 en: 10 Abril 2014, 04:51 am »

la  ecuación de Ramanujan es una locura @.@ es un poco dificil de aplicar... sin embargo dudo de su eficiencia al momento de procesar, ya que a diferencia de la de euler es muy compleja, tiene 2 factoriales diferentes (y el de arriba es grande, con k = 3 el valor es de 479.001.600) la de abajo tiene 2 potencias y la segunda es de 4*k, haciéndola sin funciones matemáticas precompiladas sería

Código
  1. for(i=1;i<precision;i++){
  2. for(j=1;j<=4*i;j++){
  3.  factorial1*=j;
  4. }
  5. for(j=1;j<=i;j++){
  6.  factorial2*=j;
  7. }
  8. for(j=1;j<=4;j++){
  9.  factorial2*=factorial2;
  10. }
  11. for(j=1;j<=4*i;j++){
  12.  divisor*=396;
  13. }
  14. sumatoria+=(factorial1*(1103+26390*i))/(factorial2*divisor)
  15.  
  16. }
  17. sumatoria=1/sumatoria
  18.  

el código sobre eso se puede optimizar pero igual son muchos ciclos dentro de cada ciclo (cuando precision = 1.000; tendrá que hacer por lo menos 4.000.000 de ciclos secundarios los cuales multiplicarán valores muy grandes, esto sin contar que sería solo para obtener 8.000 dígitos teóricos...)


la de euler es simple y hasta bonita XD solo requiere en ciclo principal y unas pocas operaciones

aqui la formula de Ramanujan


cambié un poco el programa para hacerlo más modular...

ya se me hizo tarde... así que ni argumentos (más que ramanujan), ni corrida silenciosa, ni salida a archivo! :P sorry por ahora... estoy cansado  :(

agregado por ahora, ramanujan (no da pi... si alguien me ayuda con esto, sobre donde me equivoco...), tiempo de calculo e impresion


por cierto amchacon sobre el tiempo de impresión incluso a 40.000 decimales la diferencia es instrumental, no llega al medio segundo de diferencia :P

aquí el código... se está tornando largo D:
Código
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <string>
  4. #include <gmp.h>
  5. #include <gmpxx.h>
  6. #include <time.h>
  7. #include <sstream>
  8.  
  9. using namespace std;
  10. string metodo_euler(unsigned long int digitos, mp_exp_t &exponente);
  11. string metodo_ramanujan(unsigned long int digitos, mp_exp_t &exponente);
  12. void imprimir_pi_aux(string pi, mp_exp_t exponente, int digitos);
  13.  
  14. int main(int argc, char **argv) {
  15.  
  16.    unsigned long int digitos = strtol(argv[1], NULL, 10); //argv a int
  17.    mpf_set_default_prec(32 * 10 * (digitos / 100) * 1.11); //precision + 10%
  18.    long exponente;
  19.    clock_t start = clock();
  20.    string pi;
  21.    if(argc>2 && argv[2]=="ramanujan"){
  22.        pi = metodo_ramanujan(digitos, exponente);
  23.    }else{
  24.        pi = metodo_euler(digitos, exponente);
  25.    }
  26.    clock_t end = clock();
  27.    imprimir_pi_aux(pi, exponente, digitos);
  28.    cout << "\ntiempo total de ejecucion: " << (float) (end - start) / CLOCKS_PER_SEC << "\n";
  29.    cout << "tiempo total de impresion: " << (float) (clock() - end) / CLOCKS_PER_SEC << "\n\n";
  30.    return 0;
  31. }
  32.  
  33. void imprimir_pi_aux(string pi, long exponente, int digitos) {
  34.    cout << "PI: ";
  35.    stringstream aux;
  36.    unsigned long int i;
  37.    if (exponente < 0) {
  38.        cout << "0.";
  39.        while (exponente < 0) {
  40.            cout << 0;
  41.            exponente++;
  42.        }
  43.    } else {
  44.        for (i = 0; i < exponente; i++) {
  45.            cout << pi[i];
  46.        }
  47.        cout << ".\n\n1:\t";
  48.    }
  49.    for (i = exponente; i < digitos + 1; i++) {
  50.        aux << pi[i];
  51.        if (i % 10 == 0) aux << ' ';
  52.        if (i % 500 == 0) aux << endl;
  53.        if (i % 50 == 0 && i < digitos) aux << endl << i + 1 << ":\t";
  54.    }
  55.    aux << endl;
  56.    cout << aux.str();
  57. }
  58. string metodo_euler(unsigned long int digitos, long &exponente) {
  59.    digitos /= 100; //trabaja con lotes de 100
  60.    unsigned long int precision = digitos * 100 * 3 * 1.12;
  61.    unsigned long int x, i;
  62.    mpf_t factorial, sumatoria, buff_factorial; //variables GMP
  63.    mpf_init_set_ui(factorial, 1); //factorial=1
  64.    mpf_init_set_ui(sumatoria, 1); //sumatoria=1
  65.    mpf_init_set_ui(buff_factorial, 1); //buff_factorial=1
  66.  
  67.    for (x = 1; x < precision; x++) {
  68.        i = 2 * x + 1;
  69.        mpf_set_ui(buff_factorial, x); //buff_factorial=x
  70.        mpf_div_ui(buff_factorial, buff_factorial, i); //buff_factorial*=i
  71.        mpf_mul(factorial, factorial, buff_factorial); //factorial*=buff_factorial
  72.        mpf_add(sumatoria, sumatoria, factorial); //sumatoria+=factorial
  73.    }
  74.    mpf_mul_ui(sumatoria, sumatoria, 2); //sumatoria*=2
  75.    return mpf_get_str(NULL, &exponente, 10, 0, sumatoria);
  76. }
  77.  
  78. string metodo_ramanujan(unsigned long int digitos, long &exponente) {
  79.    unsigned long int i, j;
  80.    mpf_t sumatoria, buff_sumatoria, buff_ciclo_superior, buff_ciclo_inferior, primera_parte,
  81.            buff_ciclo_inferior2, factorial_superior, factorial_inferior;
  82.    mpf_init_set_ui(sumatoria, 1103); //sumatoria=0
  83.    mpf_init_set_ui(buff_sumatoria, 0); //buff_sumatoria=0
  84.    mpf_init_set_ui(buff_ciclo_superior, 0); //buff_ciclo_superior=0
  85.    mpf_init_set_ui(buff_ciclo_inferior, 0); //buff_ciclo_inferior=0
  86.    mpf_init_set_ui(primera_parte, 0); //primera_parte=0
  87.    mpf_init_set_ui(buff_ciclo_inferior2, 0); //buff_ciclo_inferior2=0
  88.    mpf_init_set_ui(factorial_superior, 1); //factorial_superior=1
  89.    mpf_init_set_ui(factorial_inferior, 1); //factorial_inferior=1
  90.    mpf_sqrt_ui(primera_parte, 2); //primera_parte=sqrt(2)
  91.    mpf_mul_ui(primera_parte, primera_parte, 2); //primera_parte*=2
  92.    mpf_div_ui(primera_parte, primera_parte, 9801); //primera_parte/=9801
  93.  
  94.    for (i = 1; i <= digitos; i++) {
  95.        mpf_set_ui(factorial_superior, 1);
  96.        for (j = 2; j <= i * 4; j++) {
  97.            mpf_mul_ui(factorial_superior, factorial_superior, j);
  98.        }
  99.        mpf_set_ui(buff_ciclo_superior, 26390);
  100.        mpf_mul_ui(buff_ciclo_superior, buff_ciclo_superior, i);
  101.        mpf_add_ui(buff_ciclo_superior, buff_ciclo_superior, 1103);
  102.        mpf_mul(buff_ciclo_superior, buff_ciclo_superior, factorial_superior);
  103.  
  104.        mpf_mul_ui(factorial_inferior, factorial_inferior, i);
  105.        mpf_pow_ui(buff_ciclo_inferior, factorial_inferior, 4);
  106.        mpf_set_ui(buff_ciclo_inferior2, 396);
  107.        mpf_pow_ui(buff_ciclo_inferior2, buff_ciclo_inferior2, 4 * i);
  108.        mpf_mul(buff_ciclo_inferior, buff_ciclo_inferior, buff_ciclo_inferior2);
  109.  
  110.        mpf_div(buff_sumatoria, buff_ciclo_superior, buff_ciclo_inferior);
  111.        mpf_add(sumatoria, sumatoria, buff_sumatoria);  
  112.    }
  113.    mpf_mul(sumatoria, sumatoria, primera_parte);
  114.    mpf_ui_div(sumatoria, 1, sumatoria);
  115.    return mpf_get_str(NULL, &exponente, 10, 0, sumatoria);
  116. }
« Última modificación: 10 Abril 2014, 04:55 am por engel lex » En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #14 en: 10 Abril 2014, 11:22 am »

¡Buenas!

Te ha faltado calcular el factorial inferior:
Tu código:
Código
  1.        mpf_mul_ui(factorial_inferior, factorial_inferior, i); //linea 104
  2.       mpf_pow_ui(buff_ciclo_inferior, factorial_inferior, 4);
  3.  

Corregido:
Código
  1.        mpf_set_ui(factorial_inferior, 1);
  2.       for (j = 2; j <= i ; j++) {
  3.           mpf_mul_ui(factorial_inferior, factorial_inferior, j);
  4.       }
  5.       mpf_pow_ui(buff_ciclo_inferior, factorial_inferior, 4);
  6.  

Creo que eso era todo.

¡Saludos!
En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #15 en: 10 Abril 2014, 14:17 pm »

no, el factorial inferior si se calcula, lo hago igual que el de euler, es decir como es un factorial que crece de 1 en 1 uso el ciclo principal para evitar hacer más ciclos

fíjate que el factorial superior inicia reasignándose y el inferior no... pero me diste una idea para hacer algo similar con el superior
En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #16 en: 10 Abril 2014, 14:44 pm »

no, el factorial inferior si se calcula, lo hago igual que el de euler, es decir como es un factorial que crece de 1 en 1 uso el ciclo principal para evitar hacer más ciclos


El factorial inferior lo tienes que recalcular en cada iteracion. No es el factorial de n, siendo n el numero de iteraciones. Para cada iteración k es el factorial de k. Si dices que no te da el resultado, en algún punto tiene que haber un error. ¿No?

Además, de la forma en la que lo haces no estas calculando el factorial de nada. Estas multiplicando un acumulador por el numero de ciclo y luego lo elevas a 4, lo multiplicas por el siguiente contador de ciclo y lo vuelves a elevar a 4. Eso no es lo que indica la fórmula...
« Última modificación: 10 Abril 2014, 14:47 pm por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #17 en: 10 Abril 2014, 14:59 pm »

mira como lo hice en euler :P

si tengo un error, pero hice ya el debug porque justamente se que esa es la principal posible primera falla :P


factorial_inferior = 1 // 0!
ciclo 1:
factorial_inferior *=1 //1*1 = 1
ciclo 2:
factorial_inferior *=2 //2*1*1 = 2
ciclo 3:
factorial_inferior *=3 //3*2*1*1 = 6
ciclo 4:
factorial_inferior *=4 //4*3*2*1*1 = 24
ciclo 5:
factorial_inferior *=5 //5*4*3*2*1*1 = 120

el arrastra el valor del factorial y lo multiplica cada vez, por eso no le reasigno un valor entero :P (así evito hacer un ciclo extra con una variable de 1kb o más) el superior lo voy a hacer similar corriéndolo solo de i*4 y x< (i+1)*4 así solo hace 4 ciclos por ciclo :P pero esa parte si está funcionando... comprobado (hace 15 segundos XD)

sospecho que tendré que hacer debug con buena calma ver los valores con lápiz en mano... porque en donde sospecho que puede salir el error es en uno de esos números grandes
« Última modificación: 10 Abril 2014, 15:24 pm por engel lex » En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
Gh057


Desconectado Desconectado

Mensajes: 1.190



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #18 en: 11 Abril 2014, 06:37 am »

buenas! entré un segundo justo antes de ir a dormir, ando complicado con los tiempos jejej y recién veo el tema! pero no quería dejar el sitio sin antes felicitarte engel lx por el post, es muy interesante!

tan solo a titulo informativo, el excelente algoritmo de Ramanujan ha sido modificado ligeramente obteniéndose el algoritmo de Chudnovsky, que permite algo así como 15 decimales de exactitud creo, luego de cada término XD una locura!



pd: acabo de buscarlo, son 14 decimales; de 9 que se obtenía con el anterior. tengo entendido que los últimos records que indicaban más arriba fueron con dicha implementación. saludos
En línea

4 d0nd3 1r4 3l gh057? l4 r3d 3s 74n v4s74 3 1nf1n1t4...
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Calculo de pi en alta precisión (aporte)
« Respuesta #19 en: 11 Abril 2014, 07:26 am »

do-while: lo que es la arrogancia! XD al final si era el factorial el error! XD (eso creo)
XD pero ahorita está más feo aún pero funciona! y es increiblemente eficiente!

de ahora en adelante publicaré el codigo en el post inicial...  no lo publicaré como un gran bloque sino, cada sección... olvidense de imprimir en archivo y de la modularidad! XD eso aún lo postergo

Gh057: lo había visto! XD pero me tomará otro dia adaptarlo, aunque como tiene similaridad con Ramanujan no se me debría ser tan difícil...


alguna vez vi algo de comentario de código cómicos... este merece uno que vi

Código
  1. //cuando empeze a hacer esto solo dios y yo sabiamos lo que hacia, en este momento solo dios lo sabe

aqui la correccion de Ramanujan

Código
  1. string metodo_ramanujan(unsigned long int digitos, long &exponente) {
  2.    digitos/=8;
  3.    digitos*=1.01;
  4.    unsigned long int i, j;
  5.    mpf_t sumatoria, buff_sumatoria, buff_ciclo_superior, buff_ciclo_inferior, primera_parte,
  6.            buff_ciclo_inferior2, factorial_superior, factorial_inferior;
  7.    mpf_init_set_ui(sumatoria, 1103); //sumatoria=0
  8.    mpf_init_set_ui(buff_sumatoria, 0); //buff_sumatoria=0
  9.    mpf_init_set_ui(buff_ciclo_superior, 0); //buff_ciclo_superior=0
  10.    mpf_init_set_ui(buff_ciclo_inferior, 0); //buff_ciclo_inferior=0
  11.    mpf_init_set_ui(primera_parte, 0); //primera_parte=0
  12.    mpf_init_set_ui(buff_ciclo_inferior2, 0); //buff_ciclo_inferior2=0
  13.    mpf_init_set_ui(factorial_superior, 1); //factorial_superior=1
  14.    mpf_init_set_ui(factorial_inferior, 1); //factorial_inferior=1
  15.    mpf_sqrt_ui(primera_parte, 2); //primera_parte=sqrt(2)
  16.    mpf_mul_ui(primera_parte, primera_parte, 2); //primera_parte*=2
  17.    mpf_div_ui(primera_parte, primera_parte, 9801); //primera_parte/=9801
  18.  
  19.    for (i = 1; i <= digitos; i++) {
  20.        for (j = (i - 1)*4 + 1; j <= i * 4; j++) {
  21.            mpf_mul_ui(factorial_superior, factorial_superior, j);
  22.        }
  23.        mpf_set_ui(buff_ciclo_superior, 26390);
  24.        mpf_mul_ui(buff_ciclo_superior, buff_ciclo_superior, i);
  25.        mpf_add_ui(buff_ciclo_superior, buff_ciclo_superior, 1103);
  26.        mpf_mul(buff_ciclo_superior, buff_ciclo_superior, factorial_superior);
  27.        mpf_mul_ui(factorial_inferior, factorial_inferior, i);
  28.        mpf_pow_ui(buff_ciclo_inferior, factorial_inferior, 4);
  29.        mpf_set_ui(buff_ciclo_inferior2, 396);
  30.        mpf_pow_ui(buff_ciclo_inferior2, buff_ciclo_inferior2, 4 * i);
  31.        mpf_mul(buff_ciclo_inferior, buff_ciclo_inferior, buff_ciclo_inferior2);
  32.        mpf_div(buff_sumatoria, buff_ciclo_superior, buff_ciclo_inferior);
  33.        mpf_add(sumatoria, sumatoria, buff_sumatoria);
  34.  
  35.    }
  36.    mpf_mul(sumatoria, sumatoria, primera_parte);
  37.    mpf_ui_div(sumatoria, 1, sumatoria);
  38.    return mpf_get_str(NULL, &exponente, 10, 0, sumatoria);
  39. }

si no fuera tan flojo (y estuviera claro en el tema), intentara hacer operator overload para usar los operadores normales! D:

a partir de ahora modifico el post principal
« Última modificación: 11 Abril 2014, 08:17 am por engel lex » En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
Páginas: 1 [2] 3 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Bitrate + Motion Search Precision
Multimedia
G3N3S1S 2 2,325 Último mensaje 13 Enero 2005, 23:23 pm
por fanny
pequeño aporte(proxy),pero aporte al fin.:D
Programación Visual Basic
Tengu 0 2,394 Último mensaje 22 Julio 2007, 17:33 pm
por Tengu
Obtener más precisión que long double en C?¿?
Programación C/C++
jhonsc 3 3,346 Último mensaje 4 Febrero 2012, 13:48 pm
por Xandrete
Problema con la precisión del double
Java
danielo- 4 5,228 Último mensaje 27 Marzo 2012, 21:07 pm
por danielo-
Prueban en Atapuerca una tecnología inalámbrica de alta precisión pionera en...
Noticias
wolfbcn 0 1,190 Último mensaje 27 Junio 2012, 21:21 pm
por wolfbcn
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines