Re: [Python] numeri primi

2011-08-27 Per discussione Daniele Zambelli
Scusate se intervengo molto in ritardo, ma propongo un paio di algoritmi
che, hanno tempi paragonabili a quelli migliori, ma risultano molto più
semplici.

Questo cerca di ottimizzare l'algoritmo:

def crivello7(n):

if n = 2:

return []

c = list(range(3, n, 2))

top=len(c)

for primo in c:

if primo:

base = (primo*primo - 3) // 2

if base = top:

break

for j in range(base, top, primo):

c[j]=0

return [2] + list(filter(None, c))


Questo usa le capacità di Python:

def sieveOfEratostenes2(n):

if n = 2:

return []

sieve = list(range(3, n, 2))

top = len(sieve)

for si in sieve:

if si:

bottom = (si*si - 3) // 2

if bottom = top:

break

sieve[bottom::si] = [None] * -((bottom - top) // si)

return [2] + list(filter(None, sieve))


Come il precedente ma usa numpy:

def sieveOfEratostenes3(n):

if n = 2:

return []

sieve = numpy.arange(3, n, 2, dtype = int)

top = len(sieve)

for si in sieve:

if si:

bottom = (si*si - 3) // 2

if bottom = top:

break

sieve[bottom::si] = 0

return [2] + list(filter(None, sieve))


Sono algoritmi suggeriti, se non sbaglio da Bearophile

Ciao

-- 

Daniele

www.fugamatematica.blogspot.com

giusto!
nel verso
forse è perché non guardiamo le cose
Quando non ci capiamo,
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-27 Per discussione Daniele Zambelli
Scusate, ho sbagliato a ricostruire l'indentazione:

def sieveOfEratostenes2(n):

if n = 2:

return []

sieve = list(range(3, n, 2))

top = len(sieve)

for si in sieve:

if si:

bottom = (si*si - 3) // 2

if bottom = top:

break

sieve[bottom::si] = [None] * -((bottom - top) // si)

return [2] + list(filter(None, sieve))


def sieveOfEratostenes3(n):

if n = 2:

return []

sieve = numpy.arange(3, n, 2, dtype = int)

top = len(sieve)

for si in sieve:

if si:

bottom = (si*si - 3) // 2

if bottom = top:

break

sieve[bottom::si] = 0

return [2] + list(filter(None, sieve))


Ciao

-- 

Daniele

www.fugamatematica.blogspot.com

giusto!
nel verso
forse è perché non guardiamo le cose
Quando non ci capiamo,
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Mauro Casini
Enrico Franchi enrico.fran...@gmail.com writes:

 A me piace barare:

 % time python erat_matrix.py 1000
 (array([  2,   3,   5, ..., 971, 973, 991]),)
 python erat_matrix.py 1000  0.61s user 0.12s system 38% cpu 1.930 total

Ho fatto anche di peggio.
Programma per trovare il maggior numero di cifre di pi, con tempo
massimo di esecuzione brevissimo e dimensione massima del file di 4kB
(mi pare fosse una sfida di SPOJ):

v=0
for c in'M31A  ...  Q\\]cEv:O{o]1y.(g':v=v*95+ord(c)-32
print'3.%d725253'%v

al posto dei puntini ci sono altri ~4000 caratteri della
rappresentazione in base 95 della parte decimale di pi.

7866 cifre calcolate in una frazione di secondo.

E non sono stato l'unico ad avere questa idea, c'erano altri programmi
con risultati simili (però quelli che arrivavano intorno ai 4000 erano
molti di più).

ciao,
Mauro
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Marco Beri
Fabrizio (in cc) sta per mettere tutte le sue librerie aggiornate su
Bitbucket [tra parentesi le ha (abbiamo) usate per risolvere un tot di
problemi di Project Eulero].

Qui metto solo il suo sieve.py che ritengo uno dei più veloci esistenti,
Rabin e/o Miller compresi.

Ciao.
Marco.

-- 
http://beri.it/ - Un blog
http://beri.it/i-miei-libri/ - Qualche libro
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 
# LICENCE INFORMATIONS:
# 
#
# THIS SOFTWARE** IS DISTRIBUTED UNDER THE MIT LICENSE:
# http://opensource.org/licenses/mit-license.php
#
# Copyright (c) 2011 Fabrizio Romano sfab...@gmail.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the Software), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from __future__ import division, print_function
from math import ceil, sqrt
from itertools import takewhile


The functions defined in this module assume the input they are passed is
correct. This is done because we need this library to be as fast as possible.
Checking the type of the input during one call to is_prime() wouldn't make that
big difference, but doing that on 10**7 calls would sure be significantly
slower. If you need to check the input for these functions, either do it in your
code before calling them or modify them.


# small primes array
_smallp = ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
   67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
   139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
   223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
   293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
   383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
   463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,
   569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643,
   647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739,
   743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
   839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
   941, 947, 953, 967, 971, 977, 983, 991, 997)

def sieve(N):
Return a list of primes = N.
Exploit wheel criterion (dim: 30) and bit masks.

 sieve(min(200, _smallp[-1]))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199]
 sieve(10**4)[:30]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113]
 sieve(10**4)[-30:]
[9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817,
9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923,
9929, 9931, 9941, 9949, 9967, 9973]



const = 30 # wheel: 2*3*5
if N  2:
# no primes smaller than 2
return []
if N = _smallp[-1]:
# no need to calculate, we just use a part of _smallp
return list(takewhile(lambda p: p=N, _smallp))
# offsets list:
# if you write a number as 30k + c, foreach k there are only 8 numbers that
# could be primes: c = 1, 7, 11, 13, ...
offsets = (1, 7, 11, 13, 17, 19, 23, 29)
# prepare the prime list
p = [2, 3, 5]
dim = 1 + N // const # we need about 1/30 of the original dimension
# To be Parsed list
tp  = [0b] * dim
m1,m7,m11,m13,m17,m19,m23,m29=1,11,12,13,14,15,16,17
tp[0] = ~m1
# help dictionary d
# d[a , b] = c  == if we want to find the smallest useful multiple of
# (30*pos)+a on tpc, we need the index given by the product of
# [(30*pos)+a][(30*pos)+b] in general.
# If b  a, we need [(30*pos)+a][(30*(pos+1))+b]
d = {}

Re: [Python] numeri primi

2011-08-03 Per discussione Matteo Presutto

Il 03/08/2011 11:15, Filadelfo Fiamma ha scritto:

come complessità computazionale credo sì... ma non vorrei dire caxxate :D

Il 03 agosto 2011 11:10, Marco Marianibir...@gmail.com  ha scritto:

2011/8/3 Filadelfo Fiammaphilosga...@gmail.com


http://it.wikipedia.org/wiki/Crivello_di_Atkin

quest'algoritmo dovrebbe essere uno tra i più rapidi, magari può
tornarvi comodo :)

ah, dici?

http://www.enrico-franchi.org/2011/07/atkin-for-everyone-benchmark.html



___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python





ma secondo me piu che questione di computazione, qua è questione di 
interpretazione, mi spiego meglio, python è un linguaggio interpretato, 
e ha bisogno di troppi passaggi prima della compilazione... a mio 
parere, se si vuole fare un programma davvero veloce per trovare i 
numeri primi, conviene farlo direttamente in assembly

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Marco Beri
2011/8/3 matteo matteo.we...@gmail.com

 Marco, siccome sto sviluppando un codice per risolvere i sistemi lineari a
 qualsiasi numero di incognite, posso usare il codice di Fabrizio per
 semplificare i sistemi?
 P.S.: era per questo che stavo preparando quell'algoritmo sui primi


Dovresti chiedere a lui (che ho rimesso in cc).

Comunque mi ha appena segnalato di aver pubblicato la sua libreria:
https://bitbucket.org/sfabriz/karma

Ciao.
Marco.

-- 
http://beri.it/ - Un blog
http://beri.it/i-miei-libri/ - Qualche libro
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Daniele Varrazzo
On Wed, 03 Aug 2011 20:07:34 +0200, Matteo Presutto
matteo.we...@gmail.com wrote:
 carissimi pythoniani, esiste un modo per sapere in che punto della 
 memoria si trova il valore di una variabile? per dare un idea: come in 
 c++ per i puntatori, così posso collegare due programmi diversi per 
 svolgere una stessa funzione ;)

Se ci provi il sistema operativo ti taglia le manine :) Il puntatore in
memoria di una variabile ce l'hai con la funzione id(), ma processi diversi
non possono accedere alla stessa area di memoria normale. Quello che
serve e' la shared memory (in python credo vi si acceda usando il modulo
mmap). 

Questo modo di far collaborare piu' processi tra loro e' causa di morte e
distruzione piu' delle guerre, delle carestie e delle religioni. Buona
fortuna a coordinare i processi tra loro!


-- 
Daniele Varrazzo - Develer S.r.l. 
http://www.develer.com
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Carlo Miron
Fermi restanti i sacrosanti[0] avvertimenti di piro,

2011/8/3 Daniele Varrazzo p...@develer.com:
 Se ci provi il sistema operativo ti taglia le manine :) Il puntatore in
 memoria di una variabile ce l'hai con la funzione id(), ma processi diversi
 non possono accedere alla stessa area di memoria normale. Quello che
 serve e' la shared memory (in python credo vi si acceda usando il modulo
 mmap).
 Questo modo di far collaborare piu' processi tra loro e' causa di morte e
 distruzione piu' delle guerre, delle carestie e delle religioni. Buona
 fortuna a coordinare i processi tra loro!

credo che il modo moderno e sano di fare in python quello che vuoi tu
sia attraverso il package standard `multiprocessing`[1].  Ti consiglio
di leggere bene tutta la documentazione del package, in particolare le
note[2], e a meditare attentamente sopra la possibilta` di usare un
modello di IPC basato su Queue o Pipe.  O alla peggio, su Proxy.  In
tutti questi casi ci guadagni la possibilita` di distribuire
l'elaborazione al di fuori del boundary del singolo server.

[0]  ramen a Sua Spaghettosita` FSM
[1]  
http://docs.python.org/dev/library/multiprocessing#sharing-state-between-processes
[2] http://docs.python.org/dev/library/multiprocessing#programming-guidelines

Cheers,
©
-- 
Carlo Miron
FSM Bless Ya Solution Architect™
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-03 Per discussione Massimiliano della Rovere
se vuoi far comunicare due processi davvero indipendenti o che devono
restare tali, ti consiglio di dare una occhiata a zeromq oppure a dbus.
Il giorno 03/ago/2011 22:03, Carlo Miron ca...@miron.it ha scritto:
 Fermi restanti i sacrosanti[0] avvertimenti di piro,

 2011/8/3 Daniele Varrazzo p...@develer.com:
 Se ci provi il sistema operativo ti taglia le manine :) Il puntatore in
 memoria di una variabile ce l'hai con la funzione id(), ma processi
diversi
 non possono accedere alla stessa area di memoria normale. Quello che
 serve e' la shared memory (in python credo vi si acceda usando il modulo
 mmap).
 Questo modo di far collaborare piu' processi tra loro e' causa di morte e
 distruzione piu' delle guerre, delle carestie e delle religioni. Buona
 fortuna a coordinare i processi tra loro!

 credo che il modo moderno e sano di fare in python quello che vuoi tu
 sia attraverso il package standard `multiprocessing`[1]. Ti consiglio
 di leggere bene tutta la documentazione del package, in particolare le
 note[2], e a meditare attentamente sopra la possibilta` di usare un
 modello di IPC basato su Queue o Pipe. O alla peggio, su Proxy. In
 tutti questi casi ci guadagni la possibilita` di distribuire
 l'elaborazione al di fuori del boundary del singolo server.

 [0] ramen a Sua Spaghettosita` FSM
 [1] 
http://docs.python.org/dev/library/multiprocessing#sharing-state-between-processes

 [2] 
http://docs.python.org/dev/library/multiprocessing#programming-guidelines

 Cheers,
 ©
 --
 Carlo Miron
 FSM Bless Ya Solution Architect™
 ___
 Python mailing list
 Python@lists.python.it
 http://lists.python.it/mailman/listinfo/python
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Marco Beri
2011/8/2 Marco Mariani bir...@gmail.com

 2011/8/2 matteo matteo.we...@gmail.com


 non me ne intendo molto di programmazione, sono alle prime armi, ma
 secondo voi è buono un codice che riesce in 5 secondi a trovare tutti i
 numeri primi da 1 a 100? (ho un intel i3 da 3 ghz)


 in assoluto? dipende :-)

 marco@aigor:~$ time primes 1 100  /dev/null

 real0m0.018s
 user0m0.016s
 sys0m0.000s


Usando un algoritmo scritto (in Python) da un amico:

 timeit.timeit(import km;km.sieve(100), number=1)
0.12970614433288574
 timeit.timeit(import km;km.sieve(1000), number=1)
1.3863430023193359
 timeit.timeit(import km;km.sieve(1), number=1)
14.972478151321411

Bravo il mio amico, eh? :-)

Ciao.
Marco.

-- 
http://beri.it/ - Un blog
http://beri.it/i-miei-libri/ - Qualche libro
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Simone Federici
senza entrare in merito ai tempi, perche come qualcuno ha detto dipende da
quello che fai con i numeri, di solito la print su standard output impiega
più tempo del trovare i numeri

direi che puoi ottimizzare questa linea

2011/8/2 matteo matteo.we...@gmail.com

 for divi in primes[:int(math.sqrt(x))]:


ad esempio per il 101 devi provare per i numeri primi fino a 10 quindi 2, 3,
5, 7
ossia i primi 4 non i primi 10

ciao
S
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Enrico Franchi

Marco Beri wrote:

Bravo il mio amico, eh? :-)


Chi e'? Lo conosco...

A me piace barare:

% time python erat_matrix.py 1000
(array([  2,   3,   5, ..., 971, 973, 991]),)
python erat_matrix.py 1000  0.61s user 0.12s system 38% cpu 1.930 total


--
.
..: -enrico-

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Carlo Miron
2011/8/2 matteo matteo.we...@gmail.com:
 Il 02/08/2011 21:15, Mauro Casini ha scritto:
 Marco Berimarcob...@gmail.com  writes:
 Usando un algoritmo scritto (in Python) da un amico:
 timeit.timeit(import km;km.sieve(100), number=1)
 0.12970614433288574
[...]
 Si può fare di meglio:
 In [25]: timeit.timeit('num.primes(100)', 'import num', number=1)
 Out[25]: 1.2874603271484375e-05
[...]
 come hai fatto :O , io non riesco neanche a migliorare i miei 3,8 secondi
 per 100 :/

Ha barato ;)
Rileggi bene il suo mail.
©
-- 
Carlo Miron
More Cheater Than Rik0 Solution Architect™
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Enrico Franchi

Carlo Miron wrote:


Ha barato;)
Rileggi bene il suo mail.


Beh, in confronto io *non* ho barato... ;)



--
.
..: -enrico-

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] numeri primi

2011-08-02 Per discussione Marco Beri
2011/8/2 Mauro Casini ma...@iperbole.bologna.it


  timeit.timeit(import km;km.sieve(100), number=1)
  0.12970614433288574
  timeit.timeit(import km;km.sieve(1000), number=1)
  1.3863430023193359
  timeit.timeit(import km;km.sieve(1), number=1)
  14.972478151321411




 In [29]: num.primes(100)
 Out[29]: generator object primes at 0x4cb9dfa0

 In [31]: timeit.timeit('list(num.primes(100))', 'import num', number=1)
 Out[31]: 1.0322129726409912

 In [32]: timeit.timeit('list(num.primes(1000))', 'import num',
 number=1)
 Out[32]: 4.1961090564727783


 In [33]: timeit.timeit('list(num.primes(1))', 'import num',
 number=1)
 Out[33]: 35.926841974258423


Beh, visto che le funzioni del mio amico (si chiama Fabrizio Romano per la
cronaca) ritornano delle liste di primi, direi che ti battono 2.5 a 1

:-)

Scherzi a parte, ora gli chiedo se posso postarvi il codice della sua
funzione (è un crivello bello tosto).

Ciao.
Marco.

-- 
http://beri.it/ - Un blog
http://beri.it/i-miei-libri/ - Qualche libro
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python