Is there a Python library for handling complicated mathematical sets (constructed using mathematical set-builder notation)?

StackOverflow https://stackoverflow.com/questions/11110595

Question

I often work with multidimensional arrays whose array indices are generated from a complicated user-specified set.

I'm looking for a library with classes for representing complicated sets with an arbitrary number of indices, and arbitrarily complicated predicates. Given a set description, the desired output would be a generator. This generator would in turn produce either dicts or tuples which correspond to the multidimensional array indices.

Does such a library exist?


Example

Suppose we had the following user-specified set (in set-builder notation), which represents the indices of some array variable x[i][j]:

{i in 1..100, j in 1..50: i >= 20, j >= 21, 2*(i + j) <= 100}

I'd like to put this into some sort of a lazy class (a generator expression perhaps) that will allow me to lazily evaluate the elements of the set to generate the indices for my array. Suppose this class were called lazyset; this would be the desired behavior:

>>> S = lazyset("{i in 1..100, j in 1..50: i >= 20, j >= 21, 2*(i+j) <= 100}")
>>> S
<generator object <genexpr> at 0x1f3e7d0>
>>> next(S)
{'i': 20, 'j': 21}
>>> next(S)
{'i': 20, 'j': 22}

I'm thinking I could roll my own using generator expressions, but this almost seems like a solved problem. So I thought I'd asked if anyone's come across an established library that handles this (to some extent, at least). Does such a library exist?

Was it helpful?

Solution

This looks more like a constraint-solver problem to me:

import constraint as c

p = c.Problem()
p.addVariable(0, range(1,101))
p.addVariable(1, range(1,51))
p.addConstraint(lambda i: i >= 20, [0])
p.addConstraint(lambda j: j >= 21, [1])
p.addConstraint(c.MaxSumConstraint(50))

indices = ((s[0], s[1]) for s in p.getSolutionIter())  # convert to tuple generator

then if you do

for ij in indices:
    print ij

you get

(29, 21)
(28, 22)
(28, 21)
(27, 23)
(27, 22)
(27, 21)

...

(20, 25)
(20, 24)
(20, 23)
(20, 22)
(20, 21)

OTHER TIPS

Although I am not certain if this specifically (the set-builder notation) is supported by scipy. I think scipy is your best bet regardless.

There is support for sparse arrays/sets in scipy so you can easily let it handle the allocation of those without actually allocating the space :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top