GoldilocksTestParallel.cpp
void tester(int id){

	moodycamel::ConsumerToken ctok(candq); // Consumes from candq
	moodycamel::ProducerToken ptok(countq); // Produces for countq
	int mecount = 0;
	std::tuple<lint, int, lint, int>* retvals;
	bitset<tn> F;
	// Iterate until a kill-sentry is found
	while(true){
		candq.wait_dequeue(ctok, F); // Wait for new guy in queue

		if ((F.test(0) == 1) && (F.test(1) == 0)) { // Not a positive LTF
			std::ostringstream stream;
			stream << "Tester thread " << id << " terminating after testing " << mecount << " functions.\n";
			log(stream.str());
			return;		// Stop looking (termination signal)
		}

		// Holds the number of classes of each of 4 types associated with F
		retvals = new tuple<lint, int, lint, int>(0, 0, 0, 0);
		
		/* If an LTF, generate # of goldilocks functions in its orbit */
		/* Place into retvals */
		if (issep(F)) { 
			// Get the dual
			bitset<tn> Fd;
			dual(F, Fd); 

			// Store self-dualization as double-long array
			int FSD[2 * tn];
			for (int i = 0; i < tn; i++) {
				FSD[i] = F.test(i);
				FSD[i + tn] = Fd.test(i);
			}

			// And chow parameters
			// Since self-dual, the extra zeroth chow parameter is 2^(n+1)/2 = 2^n
			// Each other chow parameter of the self-dualization is double.
			int chow[n + 1];
			chowdualup(F, chow);		// The self-dualization has parameters double these
			
			// For each distinct anti-self-dualization
			bool newantisd = true;	// If this antiselfdual is distinct from those tested
			for (int i = 0; i <= n; i++) {
				if (!newantisd) {
					if (chow[i] != chow[i - 1]) {
						newantisd = true;
					}
				}

				if (newantisd) {
					// If self-dual pair
					if (chow[i] == tn / 2) {
						// Test xi = 0 for smallness
						bool isSmall = true;
						for (int j = 1; j <= n; j++) {	// testing the singleton values
							if ((FSD[two(j)]) && (j != i)) {
								isSmall = false;
								break;
							}
						}
						if (isSmall) {
							// Sn multiplicity computation
							// reps = size of Sn orbit of generator
							static lint max = fact(n);
							lint reps = max;
							int rchow[n];			// Get reduced chow parameters
							int p = 0;
							for (int j = 0; j <= n; j++) {
								if (j != i) {
									rchow[p] = chow[j];
									p++;
								}
							}

							int pcount = 1;
							for (int j = 1; j < n; j++) {
								if (rchow[j] == rchow[j - 1]) {
									pcount++;
								}
								else {
									reps /= fact(pcount);
									pcount = 1;
								}
							}
							reps /= fact(pcount);

							// Record number of classes from this generator
							get<0>(*retvals) += reps;
							get<1>(*retvals) += 1;
							get<2>(*retvals) += reps;
							get<3>(*retvals) += 1;
						}
					}
					else { // Not self dual (distinct)
						int numberPS = 2;			// Innocent until proven guilty

						// Test xi = 0 for smallness
						for (int j = 1; j <= n; j++) {	// testing the singleton values
							if ((FSD[two(j)]) && (j != i)) {
								numberPS--;
								break;
							}
						}

						// Test xi = 1 smallness
						int ti = two(i);
						for (int j = 1; j <= n; j++) {	// testing the singleton values
							if ((FSD[two(j) + ti]) && (j != i)) {
								numberPS--;
								break;
							}
						}

						// Now compute corresponding counts
						if (numberPS > 0) {
							
							// Sn multiplicity computation
							// reps = size of Sn orbit of the generator
							static lint max = fact(n);
							lint reps = max;
							int rchow[n];			// Get reduced chow parameters
							int p = 0;
							for (int j = 0; j <= n; j++) {
								if (j != i) {
									rchow[p] = chow[j];
									p++;
								}
							}

							int pcount = 1;
							for (int j = 1; j < n; j++) {
								if (rchow[j] == rchow[j - 1]) {
									pcount++;
								}
								else {
									reps /= fact(pcount);
									pcount = 1;
								}
							}
							reps /= fact(pcount);

							// Record number of classes from this generator
							if (numberPS == 2) {
								get<0>(*retvals) += reps;
								get<1>(*retvals) += 1;
								get<2>(*retvals) += reps;
								get<2>(*retvals) += reps;
								get<3>(*retvals) += 2;
							}
							else { // = 1
								get<2>(*retvals) += reps;
								get<3>(*retvals) += 1;
							}
						}
					}
					newantisd = false;
				}
			} // End for loop
		} // End F sep/ F testing and enumerating

		// Pass number of 
		countq.enqueue(ptok, *retvals);
		mecount++;

	} // End while loop
}
// Thread function: Tests boolean functions F for separability. 
// If separable, puts (m, n, s, t) in retvals
// where m is the number of goldilocks functions associated to F 
// 		 n is the number of goldilocks LTFs up to symmetry associated to F
// 		 s is the number of positive, small LTFs associated to F
// 		 t is the number of PS LTFs up to symmetry associated to F
// Passes results into a shared queue, where they are combined
Thread function: Tests boolean functions F for separability.
If separable, puts (m, n, s, t) in retvals
where m is the number of goldilocks functions associated to F
n is the number of goldilocks LTFs up to symmetry associated to F
s is the number of positive, small LTFs associated to F
t is the number of PS LTFs up to symmetry associated to F
Passes results into a shared queue, where they are combined
Thread function : Tests boolean functions F for separability . If separable puts ( m n s t ) in retvals where m is the number of goldilocks functions associated to F n is the number of goldilocks LTFs up to symmetry associated to F s is the number of positive small LTFs associated to F t is the number of PS LTFs up to symmetry associated to F Passes results into a shared queue where they are combined
void tester(int id){
	moodycamel::ConsumerToken ctok(candq); 
	moodycamel::ProducerToken ptok(countq); 
	int mecount = 0;
	std::tuple<lint, int, lint, int>* retvals;
	bitset<tn> F;
	while(true){
		candq.wait_dequeue(ctok, F); 
		if ((F.test(0) == 1) && (F.test(1) == 0)) { 
			std::ostringstream stream;
			stream << "Tester thread " << id << " terminating after testing " << mecount << " functions.\n";
			log(stream.str());
			return;		
		}
		retvals = new tuple<lint, int, lint, int>(0, 0, 0, 0);
		if (issep(F)) { 
			bitset<tn> Fd;
			dual(F, Fd); 
			int FSD[2 * tn];
			for (int i = 0; i < tn; i++) {
				FSD[i] = F.test(i);
				FSD[i + tn] = Fd.test(i);
			}
			int chow[n + 1];
			chowdualup(F, chow);		
			bool newantisd = true;	
			for (int i = 0; i <= n; i++) {
				if (!newantisd) {
					if (chow[i] != chow[i - 1]) {
						newantisd = true;
					}
				}
				if (newantisd) {
					if (chow[i] == tn / 2) {
						bool isSmall = true;
						for (int j = 1; j <= n; j++) {	
							if ((FSD[two(j)]) && (j != i)) {
								isSmall = false;
								break;
							}
						}
						if (isSmall) {
							static lint max = fact(n);
							lint reps = max;
							int rchow[n];			
							int p = 0;
							for (int j = 0; j <= n; j++) {
								if (j != i) {
									rchow[p] = chow[j];
									p++;
								}
							}
							int pcount = 1;
							for (int j = 1; j < n; j++) {
								if (rchow[j] == rchow[j - 1]) {
									pcount++;
								}
								else {
									reps /= fact(pcount);
									pcount = 1;
								}
							}
							reps /= fact(pcount);
							get<0>(*retvals) += reps;
							get<1>(*retvals) += 1;
							get<2>(*retvals) += reps;
							get<3>(*retvals) += 1;
						}
					}
					else { 
						int numberPS = 2;			
						for (int j = 1; j <= n; j++) {	
							if ((FSD[two(j)]) && (j != i)) {
								numberPS--;
								break;
							}
						}
						int ti = two(i);
						for (int j = 1; j <= n; j++) {	
							if ((FSD[two(j) + ti]) && (j != i)) {
								numberPS--;
								break;
							}
						}
						if (numberPS > 0) {
							static lint max = fact(n);
							lint reps = max;
							int rchow[n];			
							int p = 0;
							for (int j = 0; j <= n; j++) {
								if (j != i) {
									rchow[p] = chow[j];
									p++;
								}
							}
							int pcount = 1;
							for (int j = 1; j < n; j++) {
								if (rchow[j] == rchow[j - 1]) {
									pcount++;
								}
								else {
									reps /= fact(pcount);
									pcount = 1;
								}
							}
							reps /= fact(pcount);
							if (numberPS == 2) {
								get<0>(*retvals) += reps;
								get<1>(*retvals) += 1;
								get<2>(*retvals) += reps;
								get<2>(*retvals) += reps;
								get<3>(*retvals) += 2;
							}
							else { 
								get<2>(*retvals) += reps;
								get<3>(*retvals) += 1;
							}
						}
					}
					newantisd = false;
				}
			} 
		} 
		countq.enqueue(ptok, *retvals);
		mecount++;
	} 
}
void tester ( int id ) { moodycamel :: ConsumerToken ctok ( candq ) ; moodycamel :: ProducerToken ptok ( countq ) ; int mecount = 0 ; std :: tuple < lint , int , lint , int > * retvals ; bitset < tn > F ; while ( true ) { candq . wait_dequeue ( ctok , F ) ; if ( ( F . test ( 0 ) == 1 ) && ( F . test ( 1 ) == 0 ) ) { std :: ostringstream stream ; stream << " " << id << " " << mecount << " \n " ; log ( stream . str ( ) ) ; return ; } retvals = new tuple < lint , int , lint , int > ( 0 , 0 , 0 , 0 ) ; if ( issep ( F ) ) { bitset < tn > Fd ; dual ( F , Fd ) ; int FSD [ 2 * tn ] ; for ( int i = 0 ; i < tn ; i ++ ) { FSD [ i ] = F . test ( i ) ; FSD [ i + tn ] = Fd . test ( i ) ; } int chow [ n + 1 ] ; chowdualup ( F , chow ) ; bool newantisd = true ; for ( int i = 0 ; i <= n ; i ++ ) { if ( ! newantisd ) { if ( chow [ i ] != chow [ i - 1 ] ) { newantisd = true ; } } if ( newantisd ) { if ( chow [ i ] == tn / 2 ) { bool isSmall = true ; for ( int j = 1 ; j <= n ; j ++ ) { if ( ( FSD [ two ( j ) ] ) && ( j != i ) ) { isSmall = false ; break ; } } if ( isSmall ) { static lint max = fact ( n ) ; lint reps = max ; int rchow [ n ] ; int p = 0 ; for ( int j = 0 ; j <= n ; j ++ ) { if ( j != i ) { rchow [ p ] = chow [ j ] ; p ++ ; } } int pcount = 1 ; for ( int j = 1 ; j < n ; j ++ ) { if ( rchow [ j ] == rchow [ j - 1 ] ) { pcount ++ ; } else { reps /= fact ( pcount ) ; pcount = 1 ; } } reps /= fact ( pcount ) ; get < 0 > ( * retvals ) += reps ; get < 1 > ( * retvals ) += 1 ; get < 2 > ( * retvals ) += reps ; get < 3 > ( * retvals ) += 1 ; } } else { int numberPS = 2 ; for ( int j = 1 ; j <= n ; j ++ ) { if ( ( FSD [ two ( j ) ] ) && ( j != i ) ) { numberPS -- ; break ; } } int ti = two ( i ) ; for ( int j = 1 ; j <= n ; j ++ ) { if ( ( FSD [ two ( j ) + ti ] ) && ( j != i ) ) { numberPS -- ; break ; } } if ( numberPS > 0 ) { static lint max = fact ( n ) ; lint reps = max ; int rchow [ n ] ; int p = 0 ; for ( int j = 0 ; j <= n ; j ++ ) { if ( j != i ) { rchow [ p ] = chow [ j ] ; p ++ ; } } int pcount = 1 ; for ( int j = 1 ; j < n ; j ++ ) { if ( rchow [ j ] == rchow [ j - 1 ] ) { pcount ++ ; } else { reps /= fact ( pcount ) ; pcount = 1 ; } } reps /= fact ( pcount ) ; if ( numberPS == 2 ) { get < 0 > ( * retvals ) += reps ; get < 1 > ( * retvals ) += 1 ; get < 2 > ( * retvals ) += reps ; get < 2 > ( * retvals ) += reps ; get < 3 > ( * retvals ) += 2 ; } else { get < 2 > ( * retvals ) += reps ; get < 3 > ( * retvals ) += 1 ; } } } newantisd = false ; } } } countq . enqueue ( ptok , * retvals ) ; mecount ++ ; } }
Thread function: Tests boolean functions F for separability.
Thread function : Tests boolean functions F for separability .
// Consumes from candq // Produces for countq // Iterate until a kill-sentry is found // Wait for new guy in queue // Not a positive LTF // Stop looking (termination signal) // Holds the number of classes of each of 4 types associated with F /* If an LTF, generate # of goldilocks functions in its orbit */ /* Place into retvals */ // Get the dual // Store self-dualization as double-long array // And chow parameters // Since self-dual, the extra zeroth chow parameter is 2^(n+1)/2 = 2^n // Each other chow parameter of the self-dualization is double. // The self-dualization has parameters double these // For each distinct anti-self-dualization // If this antiselfdual is distinct from those tested // If self-dual pair // Test xi = 0 for smallness // testing the singleton values // Sn multiplicity computation // reps = size of Sn orbit of generator // Get reduced chow parameters // Record number of classes from this generator // Not self dual (distinct) // Innocent until proven guilty // Test xi = 0 for smallness // testing the singleton values // Test xi = 1 smallness // testing the singleton values // Now compute corresponding counts // Sn multiplicity computation // reps = size of Sn orbit of the generator // Get reduced chow parameters // Record number of classes from this generator // = 1 // End for loop // End F sep/ F testing and enumerating // Pass number of  // End while loop