Skip to content

Commit faa1fb2

Browse files
committed
Drop sequence-like indexing
1 parent e093ac1 commit faa1fb2

4 files changed

Lines changed: 71 additions & 82 deletions

File tree

src/flint/flint_base/flint_base.pyx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,21 @@ cdef class flint_mpoly(flint_elem):
244244
def to_dict(self):
245245
return {self.exponent_tuple(i): self.coefficient(i) for i in range(len(self))}
246246

247+
def __contains__(self, x):
248+
"""
249+
Returns True if `self` contains a term with exponent vector `x` and a non-zero coefficient.
250+
251+
>>> from flint import Ordering
252+
>>> ctx = fmpq_mpoly_ctx.get_context(2, Ordering.lex, 'x')
253+
>>> p = ctx.from_dict({(0, 1): 2, (1, 1): 3})
254+
>>> (1, 1) in p
255+
True
256+
>>> (5, 1) in p
257+
False
258+
259+
"""
260+
return bool(self[x])
261+
247262

248263
cdef class flint_series(flint_elem):
249264
"""

src/flint/test/test_all.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,10 +2746,8 @@ def quick_poly():
27462746
assert raises(lambda: p.coefficient(-1), IndexError)
27472747
assert raises(lambda: p.coefficient(10), IndexError)
27482748

2749-
assert p[0] == mpoly({(2, 2): 4})
2750-
assert p[3] == mpoly({(0, 0): 1})
2751-
assert raises(lambda: p[-1], IndexError)
2752-
assert raises(lambda: p[4], IndexError)
2749+
assert raises(lambda: p[-1], TypeError)
2750+
assert raises(lambda: p[4], TypeError)
27532751

27542752
assert p[(2, 2)] == 4
27552753
assert p[(0, 0)] == 1
@@ -2758,22 +2756,22 @@ def quick_poly():
27582756
assert raises(lambda: p["bad"], TypeError)
27592757

27602758
p = quick_poly()
2761-
p[1] = S(10)
2759+
p[(1, 0)] = S(10)
27622760
assert p == mpoly({(0, 0): 1, (0, 1): 2, (1, 0): 10, (2, 2): 4})
27632761

27642762
p = quick_poly()
2765-
p[(1, 0)] = S(10)
2766-
assert p == mpoly({(0, 0): 1, (0, 1): 2, (1, 0): 10, (2, 2): 4})
2763+
p[(1, 0)] = p[(1, 0)]
2764+
assert p == quick_poly()
2765+
assert (1, 0) in p
2766+
assert (100, 100) not in p
27672767

2768-
assert raises(lambda: p.__setitem__(-1, 1), IndexError)
2769-
assert raises(lambda: p.__setitem__(4, 1), IndexError)
2768+
assert raises(lambda: p.__setitem__((4,), 1), ValueError)
27702769

27712770
assert raises(lambda: p.__setitem__((1,), 1), ValueError)
27722771
assert raises(lambda: p.__setitem__((1, "bad"), 1), TypeError)
2773-
assert raises(lambda: p.__setitem__("bad", 1), TypeError)
2772+
assert raises(lambda: p.__setitem__(("bad", 1), 1), TypeError)
27742773

2775-
assert raises(lambda: p.__setitem__(2, None), TypeError)
2776-
assert raises(lambda: p.__setitem__(-1, 1), IndexError)
2774+
assert raises(lambda: p.__setitem__((2, 1), None), TypeError)
27772775

27782776
assert P(ctx=ctx).repr() == f"{ctx.__class__.__name__}(2, '<Ordering.lex: 0>', ('x0', 'x1')).from_dict({{}})"
27792777
assert P(1, ctx=ctx).repr() == f"{ctx.__class__.__name__}(2, '<Ordering.lex: 0>', ('x0', 'x1')).from_dict({{(0, 0): 1}})"

src/flint/types/fmpq_mpoly.pyx

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -265,69 +265,57 @@ cdef class fmpq_mpoly(flint_mpoly):
265265

266266
def __getitem__(self, x):
267267
"""
268-
Return the term at index `x` if `x` is an `int`, or the term with the exponent
269-
vector `x` if `x` is a tuple of `int`s or `fmpq`s.
268+
Return the coefficient of the term with the exponent vector `x`.
269+
Always returns a value, missing keys will return `0`.
270+
Negative exponents are made positive.
270271
271272
>>> from flint import Ordering
272273
>>> ctx = fmpq_mpoly_ctx.get_context(2, Ordering.lex, 'x')
273274
>>> p = ctx.from_dict({(0, 1): 2, (1, 1): 3})
274-
>>> p[1]
275-
2*x1
276275
>>> p[1, 1]
277276
3
278277
279278
"""
280279
cdef:
281280
slong nvars = self.ctx.nvars()
282281

283-
if isinstance(x, int):
284-
if not 0 <= x < fmpq_mpoly_length(self.val, self.ctx.val):
285-
raise IndexError("term index out of range")
286-
res = create_fmpq_mpoly(self.ctx)
287-
fmpq_mpoly_get_term((<fmpq_mpoly> res).val, self.val, x, self.ctx.val)
288-
return res
289-
elif isinstance(x, tuple):
290-
if len(x) != nvars:
291-
raise ValueError("exponent vector provided does not match number of variables")
292-
res = fmpq()
293-
exp_vec = fmpz_vec(x, double_indirect=True)
294-
fmpq_mpoly_get_coeff_fmpq_fmpz((<fmpq>res).val, self.val, exp_vec.double_indirect, self.ctx.val)
295-
return res
296-
else:
297-
raise TypeError("index is not integer or tuple")
282+
if not isinstance(x, tuple):
283+
raise TypeError("Exponent vector index is not a tuple")
284+
elif len(x) != nvars:
285+
raise ValueError("Exponent vector provided does not match number of variables")
286+
287+
res = fmpq()
288+
exp_vec = fmpz_vec(x, double_indirect=True)
289+
fmpq_mpoly_get_coeff_fmpq_fmpz((<fmpq>res).val, self.val, exp_vec.double_indirect, self.ctx.val)
290+
return res
298291

299292
def __setitem__(self, x, y):
300293
"""
301-
Set the coefficient at index `x` to `y` if `x` is an `int`, or the term with
302-
the exponent vector `x` if `x` is a tuple of `int`s or `fmpq`s.
294+
Set the coefficient of the term with the exponent vector `x` to `y`.
295+
Will always set a value, missing keys will create a new term.
296+
Negative exponents are made positive.
303297
304298
>>> from flint import Ordering
305299
>>> ctx = fmpq_mpoly_ctx.get_context(2, Ordering.lex, 'x')
306300
>>> p = ctx.from_dict({(0, 1): 2, (1, 1): 3})
307-
>>> p[1] = 10
308301
>>> p[1, 1] = 20
309302
>>> p
310-
20*x0*x1 + 10*x1
303+
20*x0*x1 + 2*x1
311304
312305
"""
313306
cdef:
314307
slong nvars = self.ctx.nvars()
315308

316309
coeff = any_as_fmpq(y)
317310
if coeff is NotImplemented:
318-
raise TypeError("provided coefficient not coercible to fmpq")
319-
320-
if isinstance(x, int):
321-
if not 0 <= x < fmpq_mpoly_length(self.val, self.ctx.val):
322-
raise IndexError("term index out of range")
323-
fmpq_mpoly_set_term_coeff_fmpq(self.val, x, (<fmpq>coeff).val, self.ctx.val)
324-
elif isinstance(x, tuple):
325-
if len(x) != nvars:
326-
raise ValueError("exponent vector provided does not match number of variables")
327-
exp_vec = fmpz_vec(x, double_indirect=True)
328-
fmpq_mpoly_set_coeff_fmpq_fmpz(self.val, (<fmpq>coeff).val, exp_vec.double_indirect, self.ctx.val)
329-
else:
330-
raise TypeError("index is not integer or tuple")
311+
raise TypeError("Provided coefficient not coercible to fmpq")
312+
elif not isinstance(x, tuple):
313+
raise TypeError("Exponent vector index is not a tuple")
314+
elif len(x) != nvars:
315+
raise ValueError("Exponent vector provided does not match number of variables")
316+
317+
exp_vec = fmpz_vec(x, double_indirect=True)
318+
fmpq_mpoly_set_coeff_fmpq_fmpz(self.val, (<fmpq>coeff).val, exp_vec.double_indirect, self.ctx.val)
331319

332320
def __pos__(self):
333321
return self

src/flint/types/fmpz_mpoly.pyx

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -245,49 +245,42 @@ cdef class fmpz_mpoly(flint_mpoly):
245245

246246
def __getitem__(self, x):
247247
"""
248-
Return the term at index `x` if `x` is an `int`, or the term with the exponent
249-
vector `x` if `x` is a tuple of `int`s or `fmpz`s.
248+
Return the coefficient of the term with the exponent vector `x`.
249+
Always returns a value, missing keys will return `0`.
250+
Negative exponents are made positive.
250251
251252
>>> from flint import Ordering
252253
>>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x')
253254
>>> p = ctx.from_dict({(0, 1): 2, (1, 1): 3})
254-
>>> p[1]
255-
2*x1
256255
>>> p[1, 1]
257256
3
258257
259258
"""
260259
cdef:
261260
slong nvars = self.ctx.nvars()
262261

263-
if isinstance(x, int):
264-
if not 0 <= x < fmpz_mpoly_length(self.val, self.ctx.val):
265-
raise IndexError("term index out of range")
266-
res = create_fmpz_mpoly(self.ctx)
267-
fmpz_mpoly_get_term((<fmpz_mpoly> res).val, self.val, x, self.ctx.val)
268-
return res
269-
elif isinstance(x, tuple):
270-
if len(x) != nvars:
271-
raise ValueError("exponent vector provided does not match number of variables")
272-
res = fmpz()
273-
exp_vec = fmpz_vec(x, double_indirect=True)
274-
fmpz_mpoly_get_coeff_fmpz_fmpz((<fmpz>res).val, self.val, exp_vec.double_indirect, self.ctx.val)
275-
return res
276-
else:
277-
raise TypeError("index is not integer or tuple")
262+
if not isinstance(x, tuple):
263+
raise TypeError("exponent vector index is not a tuple")
264+
elif len(x) != nvars:
265+
raise ValueError("exponent vector provided does not match number of variables")
266+
267+
res = fmpz()
268+
exp_vec = fmpz_vec(x, double_indirect=True)
269+
fmpz_mpoly_get_coeff_fmpz_fmpz((<fmpz>res).val, self.val, exp_vec.double_indirect, self.ctx.val)
270+
return res
278271

279272
def __setitem__(self, x, y):
280273
"""
281-
Set the coefficient at index `x` to `y` if `x` is an `int`, or the term with
282-
the exponent vector `x` if `x` is a tuple of `int`s or `fmpz`s.
274+
Set the coefficient of the term with the exponent vector `x` to `y`.
275+
Will always set a value, missing keys will create a new term.
276+
Negative exponents are made positive.
283277
284278
>>> from flint import Ordering
285279
>>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x')
286280
>>> p = ctx.from_dict({(0, 1): 2, (1, 1): 3})
287-
>>> p[1] = 10
288281
>>> p[1, 1] = 20
289282
>>> p
290-
20*x0*x1 + 10*x1
283+
20*x0*x1 + 2*x1
291284
292285
"""
293286
cdef:
@@ -296,18 +289,13 @@ cdef class fmpz_mpoly(flint_mpoly):
296289
coeff = any_as_fmpz(y)
297290
if coeff is NotImplemented:
298291
raise TypeError("provided coefficient not coercible to fmpz")
292+
elif not isinstance(x, tuple):
293+
raise TypeError("exponent vector index is not a tuple")
294+
elif len(x) != nvars:
295+
raise ValueError("exponent vector provided does not match number of variables")
299296

300-
if isinstance(x, int):
301-
if not 0 <= x < fmpz_mpoly_length(self.val, self.ctx.val):
302-
raise IndexError("term index out of range")
303-
fmpz_mpoly_set_term_coeff_fmpz(self.val, x, (<fmpz>coeff).val, self.ctx.val)
304-
elif isinstance(x, tuple):
305-
if len(x) != nvars:
306-
raise ValueError("exponent vector provided does not match number of variables")
307-
exp_vec = fmpz_vec(x, double_indirect=True)
308-
fmpz_mpoly_set_coeff_fmpz_fmpz(self.val, (<fmpz>coeff).val, exp_vec.double_indirect, self.ctx.val)
309-
else:
310-
raise TypeError("index is not integer or tuple")
297+
exp_vec = fmpz_vec(x, double_indirect=True)
298+
fmpz_mpoly_set_coeff_fmpz_fmpz(self.val, (<fmpz>coeff).val, exp_vec.double_indirect, self.ctx.val)
311299

312300
def __pos__(self):
313301
return self

0 commit comments

Comments
 (0)