Skip to content

Commit 941041c

Browse files
committed
Implemented fmpz_mpoly partial function composition
1 parent d5e2b56 commit 941041c

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

src/flint/types/fmpz_mpoly.pyx

+35-16
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ from flint.types.fmpq cimport any_as_fmpq, fmpq_set_any_ref
1818
from flint.types.fmpq_mpoly cimport fmpq_mpoly
1919
from flint.types.fmpz_mpoly_q cimport fmpz_mpoly_q
2020

21-
2221
cimport cython
2322
cimport libc.stdlib
2423
from flint.flintlib.fmpz cimport fmpz_set
@@ -680,10 +679,13 @@ cdef class fmpz_mpoly(flint_mpoly):
680679
fmpz_struct ** V
681680
fmpz vres
682681
fmpz_mpoly_struct ** C
683-
slong i, nvars = self.ctx.nvars(), nargs = len(args)
682+
ulong *exponents
683+
slong i, prev_i, nvars = self.ctx.nvars(), nargs = len(args)
684684

685685
if args and kwargs:
686686
raise ValueError("only supply positional or keyword arguments")
687+
elif not args and not kwargs:
688+
return self
687689

688690
if kwargs:
689691
# Sort and filter the provided keyword args to only valid ones
@@ -714,8 +716,6 @@ cdef class fmpz_mpoly(flint_mpoly):
714716
args_fmpz = tuple(any_as_fmpz(v) for v in args)
715717

716718
all_fmpz = NotImplemented not in args_fmpz
717-
# if NotImplemented in args_fmpz:
718-
# raise NotImplementedError("an argument was unable to be coerced to fmpz")
719719

720720
if not partial and all_fmpz:
721721
try:
@@ -741,31 +741,50 @@ cdef class fmpz_mpoly(flint_mpoly):
741741
fmpz_mpoly_set(res2.val, res.val, self.ctx.val)
742742
return res
743743
elif not partial and not all_fmpz:
744-
res_ctx, args = coerce_fmpz_mpolys(args)
744+
res_ctx = (<fmpz_mpoly> args[0]).ctx
745+
if not all(typecheck(args[i], fmpz_mpoly) and (<fmpz_mpoly> args[i]).ctx is res_ctx for i in range(1, len(args))):
746+
raise ValueError("all arguments must share the same context")
747+
745748
C = <fmpz_mpoly_struct **> libc.stdlib.malloc(nvars * sizeof(fmpz_mpoly_struct *))
746749
try:
747750
for i in range(nvars):
748751
C[i] = &((<fmpz_mpoly> args[i]).val[0])
749752
res = fmpz_mpoly.__new__(fmpz_mpoly)
750-
res.ctx = res_ctx
751-
fmpz_mpoly_init(res.val, res.ctx.val)
752-
res._init = True
753+
init_fmpz_mpoly(res, res_ctx)
753754
if fmpz_mpoly_compose_fmpz_mpoly(res.val, self.val, C, self.ctx.val, res_ctx.val) == 0:
754755
raise ValueError("unreasonably large polynomial")
755756
return res
756757
finally:
757758
libc.stdlib.free(C)
758759
else:
759-
raise NotImplemented("partial composition not implemented")
760-
# res_ctx, new_args = coerce_fmpz_mpolys(tuple(x for _, x in args))
760+
if not all(typecheck(arg, fmpz_mpoly) and (<fmpz_mpoly> arg).ctx is self.ctx for _, arg in args):
761+
raise ValueError("the mpoly and all arguments must share the same context")
761762

762-
# polys = [None] * nvars
763-
# for (i, _), poly in zip(args, new_args):
764-
# polys[i] = poly
763+
polys = [None] * nvars
764+
for i, poly in args:
765+
polys[i] = poly
765766

766-
# for i in range(nvars):
767-
# if polys[i] is None:
768-
# polys[i] = fmpz_mpoly({ : })
767+
for i in range(nvars):
768+
if polys[i] is None:
769+
res = fmpz_mpoly.__new__(fmpz_mpoly)
770+
init_fmpz_mpoly(res, self.ctx)
771+
exponents = <ulong *> libc.stdlib.calloc(nvars, sizeof(ulong))
772+
exponents[i] = 1
773+
fmpz_mpoly_push_term_ui_ui(res.val, <ulong>1, exponents, self.ctx.val)
774+
775+
polys[i] = res
776+
777+
C = <fmpz_mpoly_struct **> libc.stdlib.malloc(nvars * sizeof(fmpz_mpoly_struct *))
778+
try:
779+
for i in range(len(polys)):
780+
C[i] = &((<fmpz_mpoly> polys[i]).val[0])
781+
res = fmpz_mpoly.__new__(fmpz_mpoly)
782+
init_fmpz_mpoly(res, self.ctx)
783+
if fmpz_mpoly_compose_fmpz_mpoly(res.val, self.val, C, self.ctx.val, self.ctx.val) == 0:
784+
raise ValueError("unreasonably large polynomial")
785+
return res
786+
finally:
787+
libc.stdlib.free(C)
769788

770789
def factor(self):
771790
"""

0 commit comments

Comments
 (0)