Skip to content

Commit 368565e

Browse files
author
Shai Halevi
committed
allow candidate generators w/o order in PAlgebra constructor
1 parent 2a2670c commit 368565e

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

src/NumbTh.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ static bool gtAbsVal(long a, long b)
314314

315315
// Returns in gens a generating set for Zm* /<p>, and in ords the
316316
// order of these generators. Return value is the order of p in Zm*.
317-
long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p)
317+
long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p,
318+
const vector<long>& candidates)
318319
{
319320
gens.clear();
320321
ords.clear();
@@ -333,20 +334,28 @@ long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p)
333334
// The order of p is the size of the equivalence class of 1
334335
#if 0
335336
long ordP = std::count(classes.begin(), classes.end(), 1);
336-
// count(from,to,val) returns # of elements in (from,to) with value=val
337+
// count(from,to,val) returns # of elements in (from,to) with value=val
337338
#else
338-
long ordP = 0;
339-
for (long i = 0; i < lsize(classes); i++)
340-
if (classes[i] == 1) ordP++;
339+
long ordP = 0;
340+
for (long i = 0; i < lsize(classes); i++)
341+
if (classes[i] == 1) ordP++;
341342
#endif
342343

343-
// Compute orders in (Z/mZ)^*/<p> while comparing to (Z/mZ)^*
344+
// Compute orders in (Z/mZ)^* /<p> while comparing to (Z/mZ)^*
345+
long candIdx=0;
344346
while (true) {
345347
compOrder(orders,classes,true,m);
346348
// if the orders of i in Zm* /<p> and Zm* are not the same, then
347349
// order[i] contains the order in Zm* /<p> with negative sign
348350

349-
long idx = argmax(orders, &gtAbsVal); // find the element with largest order
351+
long idx=0;
352+
if (candIdx<lsize(candidates)) { // try next candidate
353+
idx = candidates[candIdx++];
354+
if (abs(orders[idx])<=1)
355+
idx=0;
356+
}
357+
if (idx==0) // no viable candidates supplied externally
358+
idx = argmax(orders, &gtAbsVal);// find the element with largest order
350359
long largest = orders[idx];
351360

352361
if (abs(largest) == 1) break; // Trivial group, we are done

src/NumbTh.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ long phi_N(long N);
342342

343343
//! Returns in gens a generating set for Zm* /<p>, and in ords the
344344
//! order of these generators. Return value is the order of p in Zm*.
345-
long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p);
345+
long findGenerators(vector<long>& gens, vector<long>& ords, long m, long p,
346+
const vector<long>& candidates=vector<long>());
346347

347348
//! Find e-th root of unity modulo the current modulus.
348349
void FindPrimitiveRoot(zz_p &r, unsigned long e);

src/PAlgebra.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,24 @@ PAlgebra::PAlgebra(unsigned long mm, unsigned long pp,
127127
// Compute the generators for (Z/mZ)^* (defined in NumbTh.cpp)
128128

129129
std::vector<long> tmpOrds;
130-
if (_gens.size() == 0 || isDryRun())
131-
this->ordP = findGenerators(this->gens, tmpOrds, mm, pp);
132-
else {
133-
assert(_gens.size() == _ords.size());
130+
if (_gens.size() == _ords.size() && !isDryRun()) {
131+
// externally supplied generator,orders
134132
tmpOrds = _ords;
135133
this->gens = _gens;
136134
this->ordP = multOrd(pp, mm);
137135
}
136+
else
137+
// treat externally supplied generators (if any) as candidates
138+
this->ordP = findGenerators(this->gens, tmpOrds, mm, pp, _gens);
139+
140+
// Record for each generator gi whether it has the same order in
141+
// ZM* as in Zm* /(p,g1,...,g_{i-1})
138142
resize(native, lsize(tmpOrds));
139143
for (long j=0; j<lsize(tmpOrds); j++) {
140144
native[j] = (tmpOrds[j]>0);
141145
tmpOrds[j] = abs(tmpOrds[j]);
142146
}
143-
cube.initSignature(tmpOrds);
147+
cube.initSignature(tmpOrds); // set hypercume with these dimensions
144148

145149
phiM = ordP * getNSlots();
146150

0 commit comments

Comments
 (0)