Skip to content

Commit dc7c787

Browse files
committed
Add missing subs and compose docs, fix old error message and comment
1 parent 8f76c6a commit dc7c787

2 files changed

Lines changed: 44 additions & 25 deletions

File tree

src/flint/types/fmpq_mpoly.pyx

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -615,39 +615,59 @@ cdef class fmpq_mpoly(flint_mpoly):
615615

616616
def subs(self, dict_args) -> fmpq_mpoly:
617617
"""
618-
Partial evaluate this polynomial.
618+
Partial evaluate this polynomial with select constants. Keys must be generator names,
619+
all values must be fmpq.
620+
621+
>>> from flint import Ordering
622+
>>> ctx = fmpq_mpoly_ctx.get_context(2, Ordering.lex, 'x')
623+
>>> f = ctx.from_dict({(0, 0): 1, (1, 0): 2, (0, 1): 3, (1, 1): 4})
624+
>>> f.subs({"x1": 0})
625+
2*x0 + 1
626+
619627
"""
620628
cdef:
621629
fmpq_mpoly res
622630
slong i, nargs
623631

624-
partial_args = tuple((i, dict_args[x]) for i, x in enumerate(self.ctx.names()) if x in dict_args)
625-
nargs = len(partial_args)
632+
args = tuple((i, dict_args[x]) for i, x in enumerate(self.ctx.names()) if x in dict_args)
633+
nargs = len(args)
626634

627-
# If we've been provided with an invalid keyword arg then the length of our filter
635+
# If we've been provided with an invalid generator name then the length of our filter
628636
# args will be less than what we've been provided with.
629-
# If the length is equal to the number of variables then all arguments have been provided
630-
# otherwise we need to do partial application
631637
if nargs < len(dict_args):
632-
raise ValueError("Unknown keyword argument provided")
638+
raise ValueError("unknown generator name provided")
633639

634-
args_fmpq = tuple(any_as_fmpq(v) for _, v in partial_args)
640+
args_fmpq = tuple(any_as_fmpq(v) for _, v in args)
635641
for arg in args_fmpq:
636642
if arg is NotImplemented:
637-
raise TypeError(f"Cannot coerce argument ('{arg}') to fmpq")
643+
raise TypeError(f"cannot coerce argument ('{arg}') to fmpq")
638644

639-
# Partial application with args in Z. We evaluate the polynomial one variable at a time
645+
# Partial application with args in Q. We evaluate the polynomial one variable at a time
640646
res = create_fmpq_mpoly(self.ctx)
641647

642648
fmpq_mpoly_set(res.val, self.val, self.ctx.val)
643-
for (i, _), arg in zip(partial_args, args_fmpq):
649+
for (i, _), arg in zip(args, args_fmpq):
644650
if fmpq_mpoly_evaluate_one_fmpq(res.val, res.val, i, (<fmpq>arg).val, self.ctx.val) == 0:
645-
raise ValueError("Unreasonably large polynomial") # pragma: no cover
651+
raise ValueError("unreasonably large polynomial") # pragma: no cover
646652
return res
647653

648654
def compose(self, *args) -> fmpq_mpoly:
649655
"""
650-
Compose this polynomial with other fmpq_mpolys. Takes positional arguments.
656+
Compose this polynomial with other fmpq_mpolys. All arguments must share the same context, it may different
657+
from this polynomials context.
658+
659+
>>> from flint import Ordering
660+
>>> ctx = fmpq_mpoly_ctx.get_context(1, Ordering.lex, 'x')
661+
>>> ctx1 = fmpq_mpoly_ctx.get_context(2, Ordering.lex, 'y')
662+
>>> f = ctx.from_dict({(2,): 1})
663+
>>> g = ctx1.from_dict({(1, 0): 1, (0, 1): 1})
664+
>>> f
665+
x^2
666+
>>> g
667+
y0 + y1
668+
>>> f.compose(g)
669+
y0^2 + 2*y0*y1 + y1^2
670+
651671
"""
652672
cdef:
653673
fmpq_mpoly res
@@ -666,8 +686,8 @@ cdef class fmpq_mpoly(flint_mpoly):
666686
if not all((<fmpq_mpoly> args[i]).ctx is res_ctx for i in range(1, len(args))):
667687
raise IncompatibleContextError("All arguments must share the same context")
668688

669-
C = fmpq_mpoly_vec(args, self.ctx, double_indirect=True)
670-
res = create_fmpq_mpoly(self.ctx)
689+
C = fmpq_mpoly_vec(args, res_ctx, double_indirect=True)
690+
res = create_fmpq_mpoly(res_ctx)
671691
if fmpq_mpoly_compose_fmpq_mpoly(res.val, self.val, C.double_indirect, self.ctx.val, res_ctx.val) == 0:
672692
raise ValueError("Unreasonably large polynomial") # pragma: no cover
673693
return res

src/flint/types/fmpz_mpoly.pyx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,8 @@ cdef class fmpz_mpoly(flint_mpoly):
597597

598598
def subs(self, dict_args) -> fmpz_mpoly:
599599
"""
600-
Partial evaluate this polynomial with select constants. All arguments must be fmpz.
600+
Partial evaluate this polynomial with select constants. Keys must be generator names,
601+
all values must be fmpz.
601602

602603
>>> from flint import Ordering
603604
>>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x')
@@ -610,28 +611,26 @@ cdef class fmpz_mpoly(flint_mpoly):
610611
fmpz_mpoly res
611612
slong i, nargs
612613

613-
partial_args = tuple((i, dict_args[x]) for i, x in enumerate(self.ctx.names()) if x in dict_args)
614-
nargs = len(partial_args)
614+
args = tuple((i, dict_args[x]) for i, x in enumerate(self.ctx.names()) if x in dict_args)
615+
nargs = len(args)
615616

616617
# If we've been provided with an invalid keyword arg then the length of our filter
617618
# args will be less than what we've been provided with.
618-
# If the length is equal to the number of variables then all arguments have been provided
619-
# otherwise we need to do partial application
620619
if nargs < len(dict_args):
621-
raise ValueError("Unknown keyword argument provided")
620+
raise ValueError("unknown generator name provided")
622621

623-
args_fmpz = tuple(any_as_fmpz(v) for _, v in partial_args)
622+
args_fmpz = tuple(any_as_fmpz(v) for _, v in args)
624623
for arg in args_fmpz:
625624
if arg is NotImplemented:
626-
raise TypeError(f"Cannot coerce argument ('{arg}') to fmpz")
625+
raise TypeError(f"cannot coerce argument ('{arg}') to fmpz")
627626

628627
# Partial application with args in Z. We evaluate the polynomial one variable at a time
629628
res = create_fmpz_mpoly(self.ctx)
630629

631630
fmpz_mpoly_set(res.val, self.val, self.ctx.val)
632-
for (i, _), arg in zip(partial_args, args_fmpz):
631+
for (i, _), arg in zip(args, args_fmpz):
633632
if fmpz_mpoly_evaluate_one_fmpz(res.val, res.val, i, (<fmpz>arg).val, self.ctx.val) == 0:
634-
raise ValueError("Unreasonably large polynomial") # pragma: no cover
633+
raise ValueError("unreasonably large polynomial") # pragma: no cover
635634
return res
636635

637636
def compose(self, *args) -> fmpz_mpoly:

0 commit comments

Comments
 (0)