-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
more gr_poly division: basecase divexact, series divconquer
- Loading branch information
1 parent
43779d1
commit 53e0f22
Showing
9 changed files
with
374 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
Copyright (C) 2010 Sebastian Pancratz | ||
Copyright (C) 2019 William Hart | ||
Copyright (C) 2014, 2021, 2023 Fredrik Johansson | ||
This file is part of FLINT. | ||
FLINT is free software: you can redistribute it and/or modify it under | ||
the terms of the GNU Lesser General Public License (LGPL) as published | ||
by the Free Software Foundation; either version 2.1 of the License, or | ||
(at your option) any later version. See <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "gr_vec.h" | ||
#include "gr_poly.h" | ||
|
||
int | ||
_gr_poly_div_series_divconquer(gr_ptr res, gr_srcptr A, slong Alen, gr_srcptr B, slong Blen, slong len, slong cutoff, gr_ctx_t ctx) | ||
{ | ||
gr_ptr Arev, Brev; | ||
slong Arevlen; | ||
int status = GR_SUCCESS; | ||
|
||
Alen = FLINT_MIN(Alen, len); | ||
Blen = FLINT_MIN(Blen, len); | ||
|
||
Arevlen = Blen + len - 1; | ||
|
||
/* todo: algorithm without zero padding */ | ||
/* todo: shallow reversals */ | ||
GR_TMP_INIT_VEC(Arev, Arevlen, ctx); | ||
GR_TMP_INIT_VEC(Brev, Blen, ctx); | ||
|
||
status |= _gr_poly_reverse(Arev, A, Alen, Arevlen, ctx); | ||
status |= _gr_poly_reverse(Brev, B, Blen, Blen, ctx); | ||
status |= _gr_poly_div_divconquer(res, Arev, Arevlen, Brev, Blen, cutoff, ctx); | ||
status |= _gr_poly_reverse(res, res, len, len, ctx); | ||
|
||
GR_TMP_CLEAR_VEC(Arev, Arevlen, ctx); | ||
GR_TMP_CLEAR_VEC(Brev, Blen, ctx); | ||
|
||
return status; | ||
} | ||
|
||
int | ||
gr_poly_div_series_divconquer(gr_poly_t Q, const gr_poly_t A, const gr_poly_t B, slong len, slong cutoff, gr_ctx_t ctx) | ||
{ | ||
int status = GR_SUCCESS; | ||
|
||
if (len == 0) | ||
return gr_poly_zero(Q, ctx); | ||
|
||
if (B->length == 0) | ||
return GR_DOMAIN; | ||
|
||
if (A->length == 0) | ||
{ | ||
truth_t is_zero = gr_poly_is_zero(B, ctx); | ||
|
||
if (is_zero == T_FALSE) | ||
return gr_poly_zero(Q, ctx); | ||
|
||
return GR_UNABLE; | ||
} | ||
|
||
if (Q == A || Q == B) | ||
{ | ||
gr_poly_t t; | ||
gr_poly_init(t, ctx); | ||
status = gr_poly_div_series_divconquer(t, A, B, len, cutoff, ctx); | ||
gr_poly_swap(Q, t, ctx); | ||
gr_poly_clear(t, ctx); | ||
return status; | ||
} | ||
|
||
gr_poly_fit_length(Q, len, ctx); | ||
status = _gr_poly_div_series_divconquer(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, len, cutoff, ctx); | ||
_gr_poly_set_length(Q, len, ctx); | ||
_gr_poly_normalise(Q, ctx); | ||
return status; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
Copyright (C) 2023 Fredrik Johansson | ||
This file is part of FLINT. | ||
FLINT is free software: you can redistribute it and/or modify it under | ||
the terms of the GNU Lesser General Public License (LGPL) as published | ||
by the Free Software Foundation; either version 2.1 of the License, or | ||
(at your option) any later version. See <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "gr_vec.h" | ||
#include "gr_poly.h" | ||
|
||
int | ||
_gr_poly_divexact_basecase_noinv(gr_ptr Q, | ||
gr_srcptr A, slong Alen, | ||
gr_srcptr B, slong Blen, gr_ctx_t ctx) | ||
{ | ||
int status = GR_SUCCESS; | ||
slong sz = ctx->sizeof_elem; | ||
slong Qlen; | ||
slong i, l; | ||
|
||
if (Blen == 1) | ||
return _gr_vec_div_scalar(Q, A, Alen, B, ctx); | ||
|
||
Qlen = Alen - Blen + 1; | ||
status = gr_divexact(GR_ENTRY(Q, Qlen - 1, sz), GR_ENTRY(A, Alen - 1, sz), GR_ENTRY(B, Blen - 1, sz), ctx); | ||
|
||
for (i = 1; status == GR_SUCCESS && i < Qlen; i++) | ||
{ | ||
l = FLINT_MIN(i, Blen - 1); | ||
status |= _gr_vec_dot_rev(GR_ENTRY(Q, Qlen - 1 - i, sz), GR_ENTRY(A, Alen - 1 - i, sz), 1, | ||
GR_ENTRY(B, Blen - 1 - l, sz), GR_ENTRY(Q, Qlen - i, sz), l, ctx); | ||
status |= gr_divexact(GR_ENTRY(Q, Qlen - 1 - i, sz), GR_ENTRY(Q, Qlen - 1 - i, sz), GR_ENTRY(B, Blen - 1, sz), ctx); | ||
} | ||
|
||
return status; | ||
} | ||
|
||
int | ||
_gr_poly_divexact_basecase(gr_ptr Q, | ||
gr_srcptr A, slong Alen, | ||
gr_srcptr B, slong Blen, gr_ctx_t ctx) | ||
{ | ||
int status = GR_SUCCESS; | ||
slong sz = ctx->sizeof_elem; | ||
gr_ptr invB; | ||
|
||
GR_TMP_INIT(invB, ctx); | ||
|
||
/* todo: we sometimes want to keep dividing, e.g. over RR with small coefficient */ | ||
status = gr_inv(invB, GR_ENTRY(B, Blen - 1, sz), ctx); | ||
|
||
/* constant is a unit; can multiply by inverse */ | ||
if (status == GR_SUCCESS) | ||
status = _gr_poly_div_basecase_preinv1(Q, A, Alen, B, Blen, invB, ctx); | ||
else | ||
status = _gr_poly_divexact_basecase_noinv(Q, A, Alen, B, Blen, ctx); | ||
|
||
GR_TMP_CLEAR(invB, ctx); | ||
|
||
return status; | ||
} | ||
|
||
int | ||
gr_poly_divexact_basecase(gr_poly_t Q, const gr_poly_t A, const gr_poly_t B, gr_ctx_t ctx) | ||
{ | ||
slong Alen, Blen, Qlen; | ||
int status = GR_SUCCESS; | ||
slong sz = ctx->sizeof_elem; | ||
|
||
Alen = A->length; | ||
Blen = B->length; | ||
|
||
if (Blen == 0) | ||
return GR_DOMAIN; | ||
|
||
if (gr_is_zero(GR_ENTRY(B->coeffs, Blen - 1, sz), ctx) != T_FALSE) | ||
return GR_UNABLE; | ||
|
||
if (Alen < Blen) | ||
return gr_poly_zero(Q, ctx); | ||
|
||
Qlen = Alen - Blen + 1; | ||
|
||
if (Q == A || Q == B) | ||
{ | ||
gr_poly_t t; | ||
gr_poly_init2(t, Qlen, ctx); | ||
status = _gr_poly_divexact_basecase(t->coeffs, A->coeffs, A->length, B->coeffs, B->length, ctx); | ||
gr_poly_swap(Q, t, ctx); | ||
gr_poly_clear(t, ctx); | ||
} | ||
else | ||
{ | ||
gr_poly_fit_length(Q, Qlen, ctx); | ||
status = _gr_poly_divexact_basecase(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, ctx); | ||
} | ||
|
||
_gr_poly_set_length(Q, Qlen, ctx); | ||
_gr_poly_normalise(Q, ctx); | ||
return status; | ||
} |
Oops, something went wrong.