示例#1
0
// **Test `test`**.
static char * test() {

	mpz_array in1, in2, out, array_expect;
	mpz_t b;
	mpz_pool pool;

	pool_init(&pool, 0);
	array_init(&in1, 2);
	array_init(&in2, 2);
	array_init(&out, 5);
	array_init(&array_expect, 5);

	mpz_init_set_str(b, "317", 10);
	array_add(&array_expect, b);
	mpz_set_str(b, "577", 10);
	array_add(&array_expect, b);
	mpz_set_str(b, "727", 10);
	array_add(&array_expect, b);
	mpz_set_str(b, "196463", 10);
	array_add(&array_expect, b);
	mpz_set_str(b, "346063", 10);
	array_add(&array_expect, b);

	// primes: 401, [577], 727, 863
	// `a = 727 * 577 = 419479`
	// `b = 401 * 863 = 346063`
	mpz_set_str(b, "419479", 10);
	array_add(&in1, b);

	mpz_set_str(b, "346063", 10);
	array_add(&in1, b);

	// primes: 317, 223, [577], 881
	// `a = 317 * 577 = 182909`
	// `b = 223 * 881 = 196463`
	mpz_set_str(b, "182909", 10);
	array_add(&in2, b);

	mpz_set_str(b, "196463", 10);
	array_add(&in2, b);

	cbmerge(&pool, &out, &in1, &in2);

	array_msort(&out);
	if (!array_equal(&array_expect, &out)) {
		return "out and array_expect differ!";
	}

	array_clear(&in1);
	array_clear(&in2);
	array_clear(&out);
	array_clear(&array_expect);
	mpz_clear(b);
	pool_clear(&pool);

	return 0;
}
示例#2
0
文件: copri.c 项目: jamella/copri
// This algorithm computes the natural coprime base for any finite subset of a free coid.
// It uses `cbmerge` to merge coprime bases for halves of the set.
//
// Algorithm 18.1 [PDF page 24](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [cb test](test-cb.html) for basic usage.
void cb(mpz_array *ret, mpz_t *s, size_t from, size_t to) {
	size_t n = to - from;
	mpz_array p, q;

	// If #S = 1: Find a ∈ S. Print a if a != 1. Stop.
	if (n == 0) {
		if (mpz_cmp_ui(s[from], 0) == 0) {
			fprintf(stderr, "warning adding 0 in cb\n");
		} else {
			if (mpz_cmp_ui(s[from], 1) != 0) {
				array_add(ret, s[from]);
			}
		}
		return;
	}

// ## OpenMP multithreading
// Execute both recrusive `cb` calls in parallel.
//
// `export OMP_NUM_THREADS=4` to set the maximal thread number.
	array_init(&p, n);
	array_init(&q, n);
#if USE_OPENMP
#pragma omp parallel sections
{
 #pragma omp section
 {
	cb(&p, s, from, to - n/2 - 1);
 }
 #pragma omp section
 {
	cb(&q, s, to - n/2, to);
 }
}
#else
	cb(&p, s, from, to - n/2 - 1);
	cb(&q, s, to - n/2, to);
#endif
	// Print cbmerge(P∪Q)
	if (q.used && p.used) {
		cbmerge(ret, &p, &q);
	} else if(!q.used && p.used) {
		array_copy(ret, &p);
		fprintf(stderr, "warning: q is empty in cb\n");
	} else if(q.used && !p.used) {
		array_copy(ret, &q);
		fprintf(stderr, "warning: p is empty in cb\n");
	} else {
		fprintf(stderr, "warning: p an q are empty in cb\n");
	}

	// Free the memory.
	array_clear(&p);
	array_clear(&q);
}