aktelle Werte in einer while schleife ausgeben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
plotxy
User
Beiträge: 20
Registriert: Dienstag 7. Oktober 2014, 18:04

Code: Alles auswählen

from mpmath import mp
from math import log10, factorial
import time
from multiprocessing import Process, Queue

  
def get_p(n, queue):
    print("get_p ...")
    p = 1
    for i in range(1, n+1):
        p = i*p + 1
    queue.put(p)
    print("get_p done!")
     
def get_q(n, queue):
    print("get_q ...")
    q = factorial(n)
    queue.put(q)
    print("get_q done!")
  
def get_p_q_multiprocess(n):
    p_queue = Queue()
    q_queue = Queue()

    p_process = Process(target=get_p, args=(n, p_queue))
    q_process = Process(target=get_q, args=(n, q_queue))

    p_process.start()
    q_process.start()

    q = q_queue.get()
    p = p_queue.get()

    q_process.join()
    p_process.join()
    
    return p, q
    
def main():
    
    n = 1*10**4
    
    t1 = time.time()
    p, q = get_p_q_multiprocess(n)
    t2 = time.time()
    
    print("calc p and q in"(t2-t1))

    p_mag_10 = int(log10(p))+1
    prec = p_mag_10
    print("precicion:", prec)
    

    mp.dps = prec + 10
    
    time3 = time.time()
    euler = mp.fdiv(p, q)
    time4 = time.time()
    print(time4 - time3)


    s = str(euler)[:prec+1]
    print(s[3])    

main()
plotxy
User
Beiträge: 20
Registriert: Dienstag 7. Oktober 2014, 18:04

@EyDu wenn ich den prozess starte passiert nichts. der prozess ist zwar unter taksmaneger zu finden. Doch nur mit einer auslastung von max 00.03. woran liegt das ? bei meinem bruder funktioniert es auch.
BlackJack

@plotxy: Das Modul mit dem das Programm gestartet wird muss zumindest unter Windows importiert werden können ohne das dabei irgendwas ”passiert”. Sonst funktioniert `multiprocessing` nicht. Du musst den `main()`-Aufruf also mit einem ``if __name__ == '__main__':`` schützen.
plotxy
User
Beiträge: 20
Registriert: Dienstag 7. Oktober 2014, 18:04

@EyDu viel dank! jetzt läuft es echt schön. (:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hmm, das habe ich jetzt schnell hingehackt aber von der Performance ist der Code recht unterirdisch :?

Code: Alles auswählen

let one = Gmp.F.from_int 1
let prec = 1_000_000
let fmul = Gmp.F.mul_prec_ui ~prec
let fdiv = Gmp.F.div_prec ~prec
let fadd = Gmp.F.add_prec ~prec
let to_string = Gmp.F.to_string_base_digits ~base:10 ~digits:1000

let f () =
  let x = ref one in
  let euler = ref one in
  for n = 1 to 205_211 do
    x := fmul !x n;
    euler := fadd !euler @@ fdiv one !x;
  done;
  print_endline @@ to_string !euler

let _ =
  f ()
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Leonidas: warum gehst Du nur bis 20000! ?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sirius3 hat geschrieben:@Leonidas: warum gehst Du nur bis 20000! ?
Versehen, hab das von hier übernommen und eine Null übersehen. In dem Fall ist die Performance noch viel schlimmer, was ja eigentlich gar nicht sein kann. Frag mich ob das Gmp-Binding so unterirdisch ist oder mein Code. Vielleicht mal Profiler anwerfen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich tippe mal auf deinen Code ;-) Die Berechnung mit Floats sollte eine Ecke langsamer sein als mit Integern und die ganzen rechenintensiven Divisionen ziehen das ganze wahrscheinlich so richtig runter. Es reicht eine Division ganz am Ende. Hinzu kommt dann noch das Problem der Genauigkeit. Du rechnest zwar mit einer Millionen Stellen Genauigkeit pro Operation, das garantiert aber keine korrekten eine Millionen Stellen im Endergebnis.
Das Leben ist wie ein Tennisball.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

In 20 Sekunden kann man sich ja nicht mal mehr einen Kaffee holen :-(

Code: Alles auswählen

#include <iostream>
#include <fstream>
#include <thread>

#include <boost/multiprecision/gmp.hpp>


typedef boost::multiprecision::mpf_float Float;
typedef boost::multiprecision::mpz_int Int;
typedef boost::multiprecision::mpq_rational Rational;


void numerator_thread(
    const unsigned int n,
    Int & numerator)
{
    numerator = 1;
    
    for(unsigned int i=1; i<n; ++i) {
        numerator = numerator*i + 1;
    }
}


void denominator_thread(
    const unsigned int n,
    Int & denominator)
{
    denominator = 1;
    
    for(unsigned int i=1; i<n; ++i) {
        denominator *= i;
    }
}


Rational euler_parallel(
    const unsigned int n)
{
    Int numerator = 1;
    Int denominator = 1;
    
    std::thread nt(&numerator_thread, n, std::ref(numerator));
    std::thread dt(&denominator_thread, n, std::ref(denominator));
    
    nt.join();
    dt.join();
    
    return Rational(numerator, denominator);
}


int main(
    int argc,
    char **argv)
{
    static const unsigned int PRECISION = 1000000;
    static const unsigned int N = 205211;
    
    Float::default_precision(PRECISION);
    
    std::ofstream stream(argv[1]);
    stream.precision(PRECISION);
    stream << Float(euler_parallel(N));
    stream.close();
    
    return 0;
}
Das Leben ist wie ein Tennisball.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

EyDu hat geschrieben:Ich tippe mal auf deinen Code ;-)
Da hast du durchaus recht, das war aber auch eine runde missverstehen dabei. Hatte den Eindruck dass

Code: Alles auswählen

from mpmath import mp

mp.dps = 1000000
euler = 1
x = 1
n = 1

while n < 205211:
    x = mp.fmul(x,n)
    euler = euler + mp.fdiv(1,x)
    n = n + 1

print(euler)
in 40 Sekunden abläuft.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

EyDu hat geschrieben:In 20 Sekunden kann man sich ja nicht mal mehr einen Kaffee holen :-(
Bin bei 30 Sekunden angekommen

Code: Alles auswählen

let prec = 1_000_000
let max_n = 205_211
let to_string = Gmp.F.to_string_base_digits ~base:10 ~digits:0

let euler_fraction n =
  let open Z in
  let numerator = ref one in
  let denominator = ref one in
  for i = 1 to n do
    numerator := succ (!numerator * (of_int i));
    denominator := (of_int i) * !denominator;
  done;
  (!numerator, !denominator)

let f () =
  let (num, den) = euler_fraction max_n in
  let znum = Gmp.F.from_string (Z.to_string num) in
  let zden = Gmp.F.from_string (Z.to_string den) in
  let euler = Gmp.F.div_prec ~prec znum zden in
  print_endline @@ to_string euler

let () = f ()
(Das Hauptproblem ist das printen, weil die Gmp-Bindings so bescheiden sind)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten