Python "Sympy"

di il
11 risposte

Python "Sympy"

Sono un paio d’anni che mi sono messo a seguire Python, da prima come un semplice strumento di calcolo per dare sfogo a una mia curiosità sui numeri primi, per poi scoprire quanto questo linguaggio è completo e versatile. Naturalmente tutto a livello amatoriale e autodidatta in quanto all’età di 66 anni non ho l’esigenza di diventare un programmatore . Continuo a creare per me e per le mie curiosità su alcune cose matematiche legate ai numeri.

Ultimamente mi sono imbattuto in SYMPY questo incredibile pacchetto di cui si parla molto poco.

In particolare di questo pacchetto ho apprezzato molto questi tre moduli

list(primerange(a,b)) tutti i numeri primi tra a e b

isprime(a) verifica se a è un numero primo

divisors(a) tutti i divisori di a

primerange e isprime si potrebbero paragonare all’algoritmo di Rabin-Miller che individuano

con una certa precisione e velocità quei numeri composti escludendoli dai numeri primi.

Ma la cosa che più mi ha colpito è divisors(a). Questa funzione trova tutti i divisori del numero dato in un tempo a dir poco fantastico. Trovare i divisori non è come stabilire se un dato numero è composto o no, vuol dire trovare tutti quei numeri che dividono il numero dato!!

Dove sta la meraviglia? Sta nella dimensione del numero… Provate a inserire un numero a 3 cifre e uno a 30 cifre. Il tempo è il medesimo, e questo io lo trovo veramente fantastico.

Buona serata

11 Risposte

  • Re: Python "Sympy"

    25/01/2023 - claugoit ha scritto:


    Dove sta la meraviglia? Sta nella dimensione del numero…

    Ok ma… qual è il problema di cui discutere?

    Se non c'è, che senso ha aprire una discussione di questo tipo su un forum?
    Bastava un post sulla propria pagina social… :)

  • Re: Python "Sympy"

    25/01/2023 - Alka ha scritto:


    25/01/2023 - claugoit ha scritto:


    Dove sta la meraviglia? Sta nella dimensione del numero…

    Ok ma… qual è il problema di cui discutere?

    Se non c'è, che senso ha aprire una discussione di questo tipo su un forum?
    Bastava un post sulla propria pagina social… :)

    Hai perfettamente ragione e una domanda l'avrei. Sarei curioso di vedere quale algoritmo usa ma quando eseguo il Debug su VScode mi dice che non riesce ad eseguirlo e di cambiare da true a false "justMyCode": false. Naturalmente sto parlando del launcher.json.

    Naturalmente anche così non funziona

    Se qualcuno potesse illuminarmi… Grazie mille

  • Re: Python "Sympy"

    30 cifre (decimali) non e' un gran numero di cifre: e' circa 2^100

    cioe' due interi a 64 bit

    si inizia a ‘ragionare’ con numeri nell'ordine di 2^1024, 2^2048, 2^512. 

    QUI si che ti ‘siedi’ ;-) 

    sono questi gli ordini di grandezza della crittografia in chiave pubblica. 

    2^128 sono le chiavi usate nella crittografia a chiave simmetrica (AES), ma qui si usa un intero qualunque non uno con certe proprieta'

    Come algo per la fattorizzazione: con la tabellina dei primi fino a 100_000, fattorizzi numeri a 32 bit

    con quella fino a 1_000_000 numeri a 40 bit.

    il tutto a velocita stratosferica.

    Anche facendo il debugging del codice, stai tranquillo che non ci capiresti nulla, se non sai GIÀ quello che dovrebbe fare. E questo non c'entra NULLA con l'età, MA con la ‘conoscenza’. 

    acquistati qualche bel libro introduttivo di teoria dei numeri: trovi argomenti decisamente curiosi.

    Ad esempio la funzione toziente, il teorema cinese del resto, le congruenza, le funzioni diofantee, …

    .

    Per il calcolo con  gli interi, si appoggia a gmp (GNU Multi Precision  library, robbbba binaria)

    'sympy' e' una libreria per il calcolo simbolico.

    Il ‘programmaore quadratico medio’ di simbolico vede solo lo stipendio ;-)

  • Re: Python "Sympy"

    26/01/2023 - migliorabile ha scritto:


    30 cifre (decimali) non e' un gran numero di cifre: e' circa 2^100

    cioe' due interi a 64 bit…..

    Sono d'accordo sulla mia ignoranza in materia di numeri e forse non dovrei neanche parlarne di certe coe. Di articoli sulla teoria dei numeri ne ho letti tanti, per la stragrande maggioranza in inglese perchè in Italiano si trova veramente poco. Tutti però convergono sul fatto che la fattorizzazione è ad oggi molto complicata e impossibile da attuare sui grandi numeri. Certo per grandi forse si intende 2^512 etc… ma comunque si parla di elaboratori che secondo i nuovi parametri di velocità possono raggiungere oltre di 200 PFlop/s. 

    Un numero a 30 cifre, e sono daccordissimo che è un numero molto piccolo se paragonato ai grandi numeri da te citati, è comunque un numero che ha una radice quadrata di 15 cifre. 

    Utilizzando anche solo 8 divisori su 30 e mettendoli in un ciclo while per raggiungere il quadrato ci impiegherebbe comunque qualche minuto, almeno sul mio pc. E non posso pensare che ci siano delle scorciatoie saltando anche un solo divisore di questi in quanto richiederebbe comunque un calcolo che allungherebbe il tempo di esecuzione del processo. In poche parole questo risultato di velocità del modulo Divisors mi incuriosisce e mi piacerebbe vederlo all'opera. Purtroppo la documentazione su questo pacchetto e in particolare su questo modulo non la si trova, se non in inglese, e comunque non specifica a Divisors.

    Grazie per la risposta

  • Re: Python "Sympy"

    Mi sfugge l'incredulita sull'identificazione dei divisori. 

    I divisori si ‘cercano’ spazzolandosi liste di numeri primi. Quando la lista non basta piu', i primi vanno ‘cercati’  con i vari algoritmi di test di primalita'.

    Poi va fatta la divisione e qui' ci sono diversi modi ‘furbi’ per farla, su numeri con precisione arbitria.

    Fonti ‘autorevoli’ su questi algoritmi c'e' ne sono diverse. 

    La prima e' “The Art of Computer Programming” (TAOCP per gli amici)  di Donald E Knuth. Volume 2 (Seminumerical Algorithms) capitolo 4.

    La ‘Bibbia’ ;-) 

    Poi puoi cercare “Hanbook of Applied Cryptography” trovi il pdf perché il libro non e' piu' in vendita

    https://cacr.uwaterloo.ca/hac/

    La documentazione di GMP contiene l'indicazione degli algo usati (appena controllato).

    Le implementazioni delle op tra interi vengono fatte sfruttando le op in assembler disponibili sulle varie CPU. E' ovvio che sia ‘stra veloce’ ;-) 

    Noni c'e' nulla di ‘miracoloso’ ;-) 

  • Re: Python "Sympy"

    Arrivi ai 200 PetaFlop o anche agli ExaFlop, ma NON su singolo computer ma su qualche migliaio di rack e qualche milione di thread. Guardati Top500. 

    https://www.top500.org/lists/top500/2022/11/

    il primo ha raggiunto 1.1 Exaflop ;-) con 8.7 MILIONI di thread, consumando 21 MW.
    Mi sa che non riesci a collegarlo alla presa di casa, nemmeno se usi la Schuko ;-)

    Il singolo computer e' stupidino con una (quasi) normale CPU intel o AMD o IBM a frequenza di 1 o 2 GHz

  • Re: Python "Sympy"

    Non so cosa faccia questa libreria ma penso che si appoggi a C o C++ come detto. Da quanto avevo visto all'epoca, mi ricordo che fino a quando la radice quadrata sta sotto i 64 bit (quindi 19 cifre) i calcoli sono abbastanza immediati con tabelle opportune.

  • Re: Python "Sympy"

    Curiosita':

    https://www.youmath.it/gioca-con-la-matematica/indovinelli/1437-i-chicchi-di-grano-di-sessa-indovinello.html

    La leggenda narra che il bramino di Sessa, avendo inventato il gioco degli scacchi, si vide offrire dal sovrano, che voleva ringraziarlo di un così piacevole gioco, qualunque cosa desiderasse. Sessa espresse il desiderio di ricevere 1 chicco di grano per la prima casella, 2 per la seconda, 4 per la terza, 8 per la quarta, e così via, andando avanti a potenze di 2, fino alla 64° casella. Il re accettò di esaudire "questa modesta richiesta". Secondo voi ci riuscì?

    2^64 = 18446744073709551616

    supponiamo 25 chicchi per grammo, sono 2^64/25 grammi, cioe' 

    produzione 2^64:     737,870,000,000 ton    (738 MILIARDI di to)
    produzione Mondiale:     760,000,000 ton    (760 MILIONI di ton)
    produzione Europea:      126,658,950 ton
    produzione Italiana:       6,716,180 ton
    

    Opps ;-) 
    Solo 1000 anni o 1000 pianeti !

    Per un stupidino 2^64

  • Re: Python "Sympy"

    26/01/2023 - migliorabile ha scritto:


    I divisori si ‘cercano’ spazzolandosi liste di numeri primi. Quando la lista non basta piu', i primi vanno ‘cercati’  con i vari algoritmi di test di primalita'.

    Esatto è proprio quello che succede.

    Volevo postare il listato di sympy con tanto di spiegazione ma il sistema mi risponde che per motivi di sicurezza mi ha bloccato la risposta, boh?

    Comunque, a parte tutto, è possibile visualizzare un modulo esterno nel debug? Da quello che ho letto in giro parrebbe di si ma a me non da.

  • Re: Python "Sympy"

    26/01/2023 - Weierstrass ha scritto:


    Non so cosa faccia questa libreria ma penso che si appoggi a C o C++ come detto. Da quanto avevo visto all'epoca, mi ricordo che fino a quando la radice quadrata sta sotto i 64 bit (quindi 19 cifre) i calcoli sono abbastanza immediati con tabelle opportune.

    La difficoltà del c++ sta proprio nella grandezza dei numeri. Nel programma che ho cercato di fare per la ricerca di numeri primi ho trovato parecchie difficoltà che mi hanno bloccato alla ventesima cifra. Impossibile calcolare oltre la diciannovesima cifra. Con un espediente un po' roccambolesco sono riuscito a elaborare fino a 26 cifre e nonostante tutto è risultato velocissimo nei calcoli.

  • Re: Python "Sympy"

    26/01/2023 - migliorabile ha scritto:


    30 cifre (decimali) non e' un gran numero di cifre: e' circa 2^100

    cioe' due interi a 64 bit

    si inizia a ‘ragionare’ con numeri nell'ordine di 2^1024, 2^2048, 2^512. 

    QUI si che ti ‘siedi’  ……. 

    30750788930784052141961861920805916103932967295178766486232675904563738880488373075752592173385037

    335955677262580553574888172359106512134725420919513785664647701815130144933436892777895761785936242

    219197749793058911484260325701737819419297192227501970384697339

    Questo numero di 260 cifre viene fattorizzato in meno di un secondo nonostante abbia due divisori Primi della portata di (2**x-1)*(2**x-a)

     con x>400 e "a" che non deve superare 10**7+1

    In questa condizione tutti i numeri composti sono numeri deboli a prescindere dalla grandezza.

    I divisori di questo numero sono

    5545339388241629719156828368286167406872874150751633150340959161229242615611251246079948812208279

    156194782421922807143657948315821

    x

    554533938824162971915682836828616740687287415075163315034095916122924261561125124607994881220827915

    6194782421922807143657948325959

    Non occorre per tanto arrivare al divisore per fattorizzare questo numero ma si segue una strada di confronto con MCD all'interno del numero composto fino a trovare due numeri con MCD diverso 1. A quel punto hai trovato il divisore.

Devi accedere o registrarti per scrivere nel forum
11 risposte