OK, I figured out the vector initialization stuff; docs need to be corrected|updated.
Here's the Rust nextp_init version, with test suite.
So now have translated and tested modInv, sozpg, and nextp_init.
// Global variables
static modpg: i32 = 30;
static rescnt: i32 = 8;
static residues: [i32; 8] = [7, 11, 13, 17, 19, 23, 29, 31];
static resinvrs: [i32; 8] = [13, 11, 7, 23, 19, 17, 29, 1];
static pos: [i32; 30] = [0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,3,0,4,0,0,0,5,0,0,0,0,0,6,0,7];
static primes: [i32; 6] = [7, 11, 13, 17, 19, 23];
static restwins: [i32; 3] = [13, 19, 31];
fn nextp_init(indx: i32, prims: Vec<i32>) -> Vec<u64> {
// Init|return 'nextp' array for given twin pair at 'indx' in 'restwins'.
// Set each row[j] w/1st prime multiple resgroup for each prime r1..sqrt(N).
let pcnt = prims.len(); // size for each row in nextp
let mut nextp = vec![0; pcnt * 2]; // 1st mults array for this twin pair
let r_hi = restwins[indx as usize]; // upper twin pair residue value
let r_lo = r_hi - 2; // lower twin pair residue value
let (row_lo, row_hi) = (0, pcnt); // nextp addr for lo|hi twin pair
for (j, prime) in prims.iter().enumerate() { // for each prime r1..sqrt(N)
let k = (prime - 2) / modpg; // find the resgroup it's in
let r = (prime - 2) % modpg + 2; // and its residue value
let r_inv = resinvrs[pos[(r - 2) as usize] as usize]; // and residue inverse
let mut ri = (r_lo * r_inv - 2) % modpg + 2; // compute the ri for r
nextp[row_lo + j] = (k * (prime + ri) + (r * ri - 2) / modpg) as u64;
ri = (r_hi * r_inv - 2) % modpg + 2; // compute the ri for r
nextp[row_hi + j] = (k * (prime + ri) + (r * ri - 2) / modpg) as u64;
}
nextp
}
fn main() {
println!("{:?}", nextp_init(0, primes.to_vec()) );
println!("{:?}", nextp_init(1, primes.to_vec()) );
println!("{:?}", nextp_init(2, primes.to_vec()) );
}
And output.
$ ./nextp_init
[5, 11, 7, 7, 18, 5, 4, 8, 13, 16, 4, 8]
[2, 2, 12, 17, 14, 14, 1, 10, 5, 9, 19, 17]
[3, 6, 9, 3, 6, 9, 2, 3, 2, 12, 11, 12]