types::list<types::ndarray<T, N>> split(types::ndarray<T, N> const &a, long nb_split) { if (a.flat_size() % nb_split != 0) throw types::ValueError( "array split does not result in an equal division"); return array_split(a, nb_split); }
// This algorithm finds cb(P∪{b}) when P is coprime. // // Algorithm 16.2 [PDF page 21](http://cr.yp.to/lineartime/dcba-20040404.pdf) // // See [cbextend test](test-cbextend.html) for basic usage. void cbextend(mpz_array *ret, mpz_array *p, const mpz_t b) { size_t i; mpz_t x, a, r; mpz_array s; // **Sep 1** // // If P = {}: Print b if b != 1. Stop. if (!p->used) { if (mpz_cmp_ui(b, 1) != 0) { array_add(ret, b); } } // **Sep 2** // // Compute x ← prod P mpz_init(x); array_prod(p, x); // **Sep 3** // // Compute (a,r) ← (ppi,ppo)(b, x) b mpz_init(a); mpz_init(r); ppi_ppo(a, r, b, x); // **Sep 4** // // Print r if r != 1. if (mpz_cmp_ui(r, 1) != 0) { array_add(ret, r); } // **Sep 5** // // Compute S ← split(a,P) array_init(&s, p->used); array_split(&s, a, p); // **Sep 6** // // For each (p, c) ∈ S: Apply append_cb(p, c). if (p->used != s.used) { fprintf(stderr, "logic error in cbextend: p.used != s.used"); } else { for (i = 0; i < p->used; i++) { append_cb(ret, p->array[i], s.array[i]); } } // Free the memory. array_clear(&s); mpz_clear(a); mpz_clear(r); mpz_clear(x); }
// This algorithm factors each element a ∈ S over P if P is a base for S; otherwise it proclaims failure. // // Algorithm 21.2 [PDF page 27](http://cr.yp.to/lineartime/dcba-20040404.pdf) // // See [findfactors test](test-findfactors.html) for basic usage. void find_factors(mpz_array *out, mpz_t *s, size_t from, size_t to, mpz_array *p) { mpz_t x, y, z; mpz_array d, q; size_t i, n = to - from; mpz_init(x); array_prod(p, x); mpz_init(y); prod(y, s, from, to); mpz_init(z); ppi(z, x, y); array_init(&d, p->size); array_split(&d, z, p); array_init(&q, p->size); for (i = 0; i < p->used; i++) { if (mpz_cmp(d.array[i], p->array[i]) == 0) array_add(&q, p->array[i]); } if (n == 0) { array_find_factor(out, y, &q); } else { find_factors(out, s, from, to - n/2 - 1, &q); find_factors(out, s, to - n/2, to, &q); } mpz_clear(x); mpz_clear(y); mpz_clear(z); array_clear(&d); array_clear(&q); }
typename std::enable_if<types::is_iterable<I>::value, types::list<types::ndarray<T, N>>>::type split(types::ndarray<T, N> const &a, I const &split_mask) { return array_split(a, split_mask); }