long sigma(long k, long* primes) { long* factors = pfactors(k, primes); long prod = 1; long i; for(i = 0; factors[i] != 0; i += 2) { long num = ipow(factors[i], factors[i+1]+1)-1; long den = factors[i]-1; prod *= num/den; } free(factors); return prod; }
// Generate a random LCG "multiplier" which will give a full period for a // "modulus" of `m`. // // http://en.wikipedia.org/wiki/Linear_congruential_generator // > [...] the LCG will have a full period for all seed values if and only if: // > [...] // > 2. `a` - 1 is divisible by all prime factors of `m`, // > 3. `a` - 1 is a multiple of 4 if `m` is a multiple of 4. // // This function generates a sufficient `a`. int mul(int m) { int a = m * 0.75; bool sufficient = false; bool m_divis_4 = m % 4 == 0; while (!sufficient) { a = (a + 1) % (m - 1) + 1; // skip a == 0 sufficient = true; unsigned int* factors = pfactors(m); int i; for (i = 1; sufficient && i < factors[i]; i++) { sufficient = (a - 1) % factors[i] == 0; } free(factors); sufficient = sufficient && (!m_divis_4 || (a - 1) % 4 == 0); } return a; }