@@ -18,7 +18,6 @@ from flint.types.fmpq cimport any_as_fmpq, fmpq_set_any_ref
18
18
from flint.types.fmpq_mpoly cimport fmpq_mpoly
19
19
from flint.types.fmpz_mpoly_q cimport fmpz_mpoly_q
20
20
21
-
22
21
cimport cython
23
22
cimport libc.stdlib
24
23
from flint.flintlib.fmpz cimport fmpz_set
@@ -680,10 +679,13 @@ cdef class fmpz_mpoly(flint_mpoly):
680
679
fmpz_struct ** V
681
680
fmpz vres
682
681
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)
684
684
685
685
if args and kwargs:
686
686
raise ValueError (" only supply positional or keyword arguments" )
687
+ elif not args and not kwargs:
688
+ return self
687
689
688
690
if kwargs:
689
691
# Sort and filter the provided keyword args to only valid ones
@@ -714,8 +716,6 @@ cdef class fmpz_mpoly(flint_mpoly):
714
716
args_fmpz = tuple (any_as_fmpz(v) for v in args)
715
717
716
718
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")
719
719
720
720
if not partial and all_fmpz:
721
721
try :
@@ -741,31 +741,50 @@ cdef class fmpz_mpoly(flint_mpoly):
741
741
fmpz_mpoly_set(res2.val, res.val, self .ctx.val)
742
742
return res
743
743
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
+
745
748
C = < fmpz_mpoly_struct ** > libc.stdlib.malloc(nvars * sizeof(fmpz_mpoly_struct * ))
746
749
try :
747
750
for i in range (nvars):
748
751
C[i] = & ((< fmpz_mpoly> args[i]).val[0 ])
749
752
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)
753
754
if fmpz_mpoly_compose_fmpz_mpoly(res.val, self .val, C, self .ctx.val, res_ctx.val) == 0 :
754
755
raise ValueError (" unreasonably large polynomial" )
755
756
return res
756
757
finally :
757
758
libc.stdlib.free(C)
758
759
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 " )
761
762
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
765
766
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)
769
788
770
789
def factor (self ):
771
790
"""
0 commit comments