Ce ALTE schimbări în bine am mai făcut la programele numerice

S-au tot adunat, în timpul cel lung care a trecut, foarte multe schimbări și constatări că pot să transform, să îmbunătățesc asta, asta, asta la funcționarea numerelor.

Și au fost destule clipe în care gândeam că NU mai e de optimizat în cutare algoritm de cercetat numerele, că deja am făcut ceea ce trebuia ca să fie mai rapid, apoi veneau alte momente când realizam că de fapt se mai poate ceva.

La calculul sumelor de divizori pentru numere și la metodele diferite de deducere a numitorului fracției abundențiale (sau chiar mai simplu, deducerea faptului că acest numitor se încadrează în rangul dorit, adică maxim 10 la fondul 1 și, în prezent, maxim 1333333 pentru fondul 2), în clipa asta iarăși cred că am făcut ceea ce era de făcut, algoritmic vorbind. Prin noiembrie 2018 lucram de zor la niște optimizări de cod în zona asta, după aia până prin decembrie am aranjat la codul pentru Veriton (acela cu divizorii impari limitați la 64 de biți), de care însă nu sunt satisfăcut (dar nici nu este o prioritate, de asta l-am lăsat încolo până acum în 2019).

La VECUN ziceam că am scos dualismul „vecun la înmulțiri, vecun1 la împărțiri”, tot cu îmbogățirea listei de parametri la argv (ăsta în C este vectorul de parametri-șiruri de caractere din linia de comandă, în fapt o matrice bidimensională de tip char, transmisă ca pointer în antetul funcției main() ).

Și acum la VECUN se face așa:

* ./vecun 0 160 0 a dacă, de exemplu, vrem să punem într-un vector toate numerele de fond 1 de maxim 160 de cifre, cu pornire de jos de tot (10 la puterea 0), adică toate acele numere cu mărimile astea și ale căror sume de divizori naturali împărțite la ele însele dau fracții ireductibile cu numitorul maxim egal cu 10, să facem alt vector în care intră toate rezultatele împărțirilor acestor numere unele la altele (astfel, coeficienții de legătură dintre ele) care la rândul lor au un număr maxim de cifre, de data asta specificat manual undeva în cod - nu-l dau ca parametru, mai ales că variază, o să vedem cum, și să găsim numere noi, tot de fond 1, împărțind numerele inițiale, de maxim 160 de cifre, la acești coeficienți de legătură. Al doilea 0 ne spune tocmai faptul că operația aritmetică de obținere a numerelor unele dintr-altele va fi împărțirea, adică o abordare de sus în jos, iar litera a, că așa se pornește la început programul, se recompilează și parametrii se retransmit la un nou apel unde a se schimbă în b.

* ./vecun 0 160 1 a se deosebește de scenariul de mai sus prin faptul că numerele vor fi înmulțite cu acei coeficienți de legătură, care în plus vor fi mai puțini aici (mai mic numărul acela de cifre la vectorul de coeficienți, scris manual în altă zonă de cod decât puterea de 10 sub care trebuie să fie coeficienții de împărțire). Aș îngreuna linia de comandă să trec și puterea asta, așa că nu o fac.

De ce să fie mai puțini coeficienți de legătură la înmulțirea vecunică decât la împărțire? Pentru că acolo, deși sunt foarte mulți, mulți dintre ei sunt omiși pentru un număr dat pentru că NU îi are ca divizori, mai cu seamă când se ajunge ca numerele să fie mici, mai mici decât coeficienții de legătură rezultați din împărțirea unui număr mare la unul mult mai mic, și-n plus numerele oricum sunt mai mici dacă sunt rezultate din împărțiri Astfel că pot fi, să zicem, 358555 de coeficienți de maxim 40 de cifre la împărțire, dar sigur merge mai repede căutarea în jos față de cea în sus cu doar vreo 116000 de coeficienți de legătură de maxim 28 (parcă) de cifre.

Vorba unui cântec:
Pentru că?
Pentru că:

La înmulțire, sunt și numere mai mari decât la împărțire, sunt și tratate absolut toate combinațiile (produsele), că NU este ca la împărțire, unde un număr nou este verificat la abundențialitate numai dacă a existat o divizibilitate între numărul inițial (de bază) și coeficientul de legătură, câtul împărțirii lor fiind numărul nou.
La înmulțire, înmulțești pur și simplu, și pentru fiecare număr dat de fond 1 din N3.TXT sunt vreo 116000 de alte numere noi, mai mari decât el, de verificat, pe când la împărțire, în medie, pentru acel număr dat, NU am făcut o medie statistică de câți factori de legătură divizibili i se găsesc, în medie, dar să zicem că sunt 1000 găsiți sau chiar mai puțini, bașca dimensiunea mai mică a numerelor-cât.

Să ne imaginăm că avem un număr de 120 de cifre din N3.TXT și-i facem 116000 de coeficienți între una și 28 de cifre, și el trebuie pe rând înmulțit cu toți (rezultă tot atâtea numere de la 120/121 până spre 149 de cifre), și toate trebuiesc puricate pentru încadrarea sub 11 a numitorului fracției ireductibile-raport dintre suma divizorilor fiecăruia și fiecare număr însuși.

Luăm același număr și-i facem 358555 de coeficienți de maxim 40 de cifre, dar poate că nu se divide decât cu vreo mie dintre ei, și numerele rezultate, mai mici decât el, pot să aibă de la 80 la 120 de cifre - și este clar că, de pildă, un număr de 90 de cifre se prelucrează mai repede decât unul de 140, plus faptul că 1 e mult mai mic decât 116, apropo de miile de numere noi verificabile.

De asta, căutarea în jos la VECUN (și în general la numere) este mai rapidă.

Dar pentru fructe numerice temeinice, ambele căutări sunt necesare, așa cum și femeile și bărbații au nevoie unii de alții în viața asta.

*
De când cu marea refiltrare din noiembrie 2018, când m-am reîncadrat în cele 5173 de numere prime din componența multiperfectelor și semiperfectelor Numericanei, OEIS-ului și-ale lui Achim Flammenkamp, iar pentru numerele sub 241 de cifre, în special, numărul de factori primi a scăzut drastic, vechile fișiere cu factori primi (CF-urile) și auxiliarele lor aferente (precum fișierele numite PUTERI52.TXT, PUTERI80.TXT și așa mai departe) au fost bine puse deoparte.

În locul lor au venit niște fișiere care au un V (de la vecun) în plus în nume, precum CFV52.TXT, și puterile (numerele prime cu care numerele de bază se divid de mai multe ori) sunt cu PUTERIV în nume acum. Fișierele erau generate chiar de către „vecun”, pe baza numerelor de fond 1 existente, așa încât ele, cele pentru care de fapt se face toată căutarea, să fie și cele care decid plajele de factori primi componenți, scăpând de adăugirile masive de numere prime în plus prin diverse locuri.

Și am văzut că pentru fondul 1 tot cele 5173 de bază au rămas definitorii, în plus la numerele mici de-abia se strâng până-n 249 de factori la cele de 100 de cifre, și 122 la maxim 52, de unde la vechile CF-uri erau deja peste 3000 de prime componente la toate numerele de două cifre.

Scriam că am făcut mai multe GIG-uri noi, 16 în total, și sunt tot atâtea rânduri de CFV-uri cu PUTERIV, VPV (astea conțin numai factorii primi multiputere, fără exponenții și rezultatele ridicărilor la putere) și, unde este cazul, VCV (cu factori primi peste 64 de biți, și ăștia mai puțini decât dincolo).

Totuși, între timp am mai folosit MODIFSUM pentru creșterea numărului de factori primi multiputere din fișiere, sperând ca așa să contribui la găsirea de numere noi, fără să mai infuzez multe numere prime noi în fișiere (că pe la CFV100 au venit șapte numere prime noi, pesemne de mai sus de la CFV110, când de acolo se caută în jos și ies numere de maxim 100 de cifre cu factori primi pe care VECUN NU îi găsește la maxim 100 de cifre).
Apropo de asta, chiar mai trebuie să fac carontizare de frontieră pe la GIG-uri, să văd dacă-i rost de numere prime componente noi de la „numerele marginale” ale GIG-urilor superioare, venite din căutările în jos.

Rămânând la creșterea numărului de prime multiputernice dintr-un CFV, totuși când dau vecun în sus sau în jos cu numere al căror număr maxim de cifre ar fi cumva 52 sau se divide cu 10 și coincide cu unul dintre numerele 70-160 (din 10 în 10), 180, 200, 240, 420 și 1910 (nu  și la 1910 în sus, că acolo vecun NU mai caută în sus, ci face fișiere speciale cu numere de fond 1), trebuie să am grijă să nu suprascrie CFV-urile astea existente, că vecunul NU aduce datele așa cum am aranjat CFV-urile, ba la căutarea în jos le și trunchiază serios, pentru că acolo nu se mai încarcă toate numerele de la una la maxim Ț cifre o dată, ci se abordează segmentat, vectorii de prime componente fiind generați succesiv și fiind mai mici decât dacă ar fi toate numerele o dată - ceea ce, iar, trebuie cumulativ să ducă la un plus de rapiditate la căutarea în jos, special la vecun).

Așa că o schimbare recentă pe care am făcut-o vecunului a fost să adaug al doilea V în fișierele de numere prime componente pentru numerele de fond 1, generate de vecuni: CFVV, PUTERIVV, VPVV, VCVV.

Și dacă e rost prin ele (la întâlnirile cu 52 și cu zeciurile de mai sus, care numesc cele șaisprezece fișiere GIG) de ceva număr prim care NU este și prin CFV-uri, știu eu cum să-l pun la CFV-uri, care acum nu mai sunt nici ele ca la VECUN (ca după 25 noiembrie), avându-și deja îmbogățeala lor; poate așa se îmbogățește și VECUN-ul dacă noile numere de fond 1 găsite vor avea ceva din multiputerile nou-puse și numerele prime luate „de mai sus” din GIG, dar tot din cele pe care VECUN le găsește dacă luăm tot fondul 1 (5173).

Când eram cu CF-urile, P2.TXT, echivalentul lui CF1910, avea 5815 numere, dar exista și o variantă extinsă, GIG.TXT, cu 8762 de numere prime, 1533 dintre ele peste 64 de biți (față de maxim 421 la CFV-urile 1910 dinspre VECUN, și chiar și la P2 tot 421).

Este foarte important să nu se facă gafe numerice care să strice fișierele de numere prime (orice gafe, de fapt).

*

Iar la căutarea de numere noi se preferă, cu anumite excepții, să fie făcută căutarea nu pe baza tuturor fișierelor din GIG, ci din niște fișiere mai mici, speciale, cu extensia .LIT, care conțin numai numerele complet noi care au venit la GIG-uri, prin ermetizare (la mine asta înseamnă ERMETE sau ERMETE2, care declanșează, respectiv, subsecvențele vecungul - șiruri de caractere - sau vecung - mpz_t), am mai zis că este pentru ca să nu caute noutăți decât din noutăți, nu și din alte numere deja folosite la căutat mai înainte - că ar fi redundanță, apă în piuă.

Dar dacă vreun LIT a fost șters din greșeală sau este insuficient de mare, se mai fac și căutări direct pe GIG, însă acolo vectorii cu factori de legătură (primi sau neprimi, am mai dezbătut povestea asta) trebuie categoric să fie mai mici, atent aleși, pentru că volumul de lucru este cumplit de mare și rezultatele trebuie să fie fructuoase și în acest caz, dar fără un timp groaznic de lung.

Comentarii

Postări populare