Numerico-algoritmice din prima parte a lui 2014 (Partea II)

Înmulțiri, împărțiri (=substituții): de exemplu 3 înmulțiri + 2 împărțiri: r1.IntegerC(1, 3) și r1.IntegerC(1, 2) care să dea 3, respectiv 2.
Factorii primi aleși pentru substituire pot fi luați direct din vectorul b* și puși în vectori speciali: mulInt, impInt, și puterile lor să stea în mulPut, impPut.

De exemplu, cu r1.Integer(1, 4) se aleg 3 factori de înmulțit, apoi cu r1.Integer(1, 3) sunt luați 2 factori pentru împărțit; primii 3 intră în mulInt (și puterile lor aleatorii la mulPut), iar ceilalți doi la impInt și puterile la impPut.
t=3, u=2;

La împărțire, factorii trebuie să-l dividă pe NUM, altfel nu intră în impInt. Dacă dimensiunea de lucru a lui impInt de la rândul curent de substituție este 0, nu se intră la el. Valabil și pentru mulInt.

Verificarea că elementele din impInt și mulInt sunt toate diferite: să se facă un vector de verificare (Verif) unde să intre elementele primite în impInt și mulInt, apoi dacă se repetă ceva în el (preferabil să fie sortat crescător), se reia rândul de substituție, cu goto, ori se taie duplicatele (mai greu). De preferat cu goto. Să nu se intre la vectori (la substituție) înainte de verificarea duplicatelor.

La înmulțire, factorul curent se verifică dacă este divizor al lui NUM (la împărțire se verifică chiar la construirea impInt) sau dacă nu este. Este NUM divizibil cu el? mpz_divisible_ui_p.
Dacă factorul prim de vizită, la înmulțire, nu este al numărului de bază (NUM), nu se iau în seamă divInt/sumInt, dar se văd factorul și puterea lui, de pildă mulInt[1]=7 și mulPut[1]=3, și atunci:

a devine 343 (pow(mulInt[1], mulPut[1]));
NUM *= a;
SUM *= (a + (a-1)/(mulInt[1] - 1) ), adică se înmulțește cu 400, suma divizorilor naturali ai lui 343, 1+7+49+343 = 343 + (343-1)/(7-1) = 343 + 342/6 = 343+57 = 400.

La ridicările la putere: funcție specială pentru mpir_ui. pow() este funcție suspectă. La JEDENASCIE sunt niște funcții de putere.
Parte separată pentru schimbarea puterii de 2 a lui NUM, la începutul fiecărui rând de substituție (sau spre sfârșit, dar să nu se repete pentru situațiile când impInt și mulInt trebuiesc regenerați din motivul repetării vreunui factor). 2 este număr prim special.

Vectorul de factori primi al numărului inițial trebuie sortat crescător (într-o copie), să se caute binar în el, depinde de mărime (când factorul din vectorul de factori de substituție e și în al numărului).
Alternativ: verificarea divizibilității lui NUM cu factorul.

La puterile de 2:
Pentru împărțire, puterea trebuie să fie sub mpz_scan1(NUM, 0).
Se poate condiționa și generarea puterii de 2 pentru înmulțire/împărțire, în funcție de puterea de 2 a lui NUM. Goto când nu corespunde (se reia).
mpz_tdiv_q_2exp(NUM, NUM, n) sau mpz_mul_2exp(NUM, NUM, n).


mpz_divexact_ui(SUM, SUM, sumInt[i]);
Când factorul este deja al numărului, dar la putere mai mică:
dif = intPut[i] - vec[i];

Dacă este al numărului, dar la putere mai mare:
dif = vec[i] - intPut[i];

a = (mpir_ui)pow(b[i], dif);
div *= a;//dacă trebuie împărțit
mul *= a;//dacă trebuie înmulțit
S-ar putea ca div și mul să fie prea mari pentru mpir_ui.

mpz_mul_ui(SUM, SUM, a + (a-1)/(b[i] - 1));//reforma sumei


a = (mpir_ui)pow(b[i], r1.IntegerC(vec[i]));


FACTORSUB.cc a fost făcut.

Ca principiu de lucru: MODIFSUM va modifica de acum sume de divizori unde coeficienții de legătură, impari, nu sunt numere prime, iar MODSPRIM îi va lua pe cei primi (2 nu), ca intermediar între MODIFSUM și NUMSIMPL.

La MODSPRIM: factorii primi de înmulțire/împărțire ar trebui permiși numai dintre cei H, cei care în fișierul de coeficienți primi corespunzător intervalului de căutare sunt în secțiunea dedicată factorilor primi capabili să dividă de mai multe ori un număr (de exemplu la CF240.TXT, primii 147).

A fost făcut MODSPRIM1.cc.
divInt a fost scos de la sumele MODIFSUM, iar MODSPRIM nici nu l-a avut; dar FACTORSUB are nevoie și de divInt.

Funcția INV nu are ce căuta unde se folosesc ADUNDIV, ADPRIMDIV și celelalte AD*. Nici LOTVEC*.
INV și LOTVEC* se autoexclud când sunt la SUMADIV, SUM, SM / SUMADIV1, SUM1, SM.
INV, obligatoriu prezentă la SUMADIV, SUM, SM. Se pune imediat după SCOTFACT.

(va urma)

Comentarii

Postări populare