> On Sep 20, 2013, at 8:33 AM, Moritz Emanuel Beber <[email protected]> 
> wrote:
>
>
>> On 09/20/2013 01:31 AM, Aaron Meurer wrote:
>>> On Tue, Sep 17, 2013 at 3:41 AM, Moritz Beber <[email protected]> 
>>> wrote:
>>>
>>>> On Monday, 16 September 2013 20:09:52 UTC+2, Aaron Meurer wrote:
>>>>> On Mon, Sep 16, 2013 at 5:56 AM, Moritz Beber <[email protected]> wrote:
>>>>> Dear all,
>>>>>
>>>>> My question basically has two parts:
>>>>>
>>>>> 1.) I have a number of (a few thousand) logical expressions each
>>>>> consisting
>>>>> of a handful of symbols (in total there are several thousand symbols as
>>>>> well). Currently, I generate a dictionary (let's call it 'big_dict')
>>>>> with
>>>>> the symbols and their truth values. Then I loop through each expression
>>>>> and
>>>>> evaluate it by calling expr.subs(big_dict). This is painfully slow. I
>>>>> looked
>>>>> through the source code for 'subs' a little and saw that it roughly
>>>>> translates the dict into an iterable of old, new pairs which it then
>>>>> loops
>>>>> through in order to apply replacements. Is there a more efficient way? I
>>>>> guess what I could code but actually expect an evaluation of a boolean
>>>>> expressions to do is: using the symbols in it, extract the values and
>>>>> solve.
>>>> You can try using xreplace, or (I belive) subs(simultaneous=True),
>>>> which should only walk the expression tree once.
>>> xreplace was the best option, indeed. Here are some timings that might be
>>> informative:
>>>
>>> In [4]:
>>>
>>> from sympy.abc import a, b, c, x, y, z
>>>
>>> In [5]:
>>>
>>> expr = sympy.sympify("a & b")
>>>
>>> In [6]:
>>>
>>> variables = dict(zip(range(100), range(100)))
>>>
>>> variables[a] = True
>>>
>>> variables[b] = False
>>>
>>> In [7]:
>>>
>>> %timeit expr.subs(variables)
>>>
>>> 100 loops, best of 3: 2.22 ms per loop
>>>
>>> In [9]:
>>>
>>> %timeit expr.subs(variables, simultaneous=True)
>>>
>>> 100 loops, best of 3: 3.12 ms per loop
>> I don't understand why this one is so slow, especially when the very
>> similar version below is fast.
>>
>> Aaron Meurer
> The reason is that subs iterates through all key, value pairs in the 
> dictionary to check for substitutions whereas the code below only retrieves 
> the two values of the symbols in expr.args from the otherwise rather large 
> dictionary.

Ah I didn't notice that. In general, you would have to use
expr.atoms(Symbol). But this will walk the expression tree twice,
which is why raw xreplace will be faster. xreplace is also optimized
for having a lot of keys that are never used.

Aaron Meurer

>>
>>> In [10]:
>>>
>>> %timeit expr.subs([(var, variables[var]) for var in expr.args])
>>>
>>> 10000 loops, best of 3: 58.2 盜 per loop
>>>
>>> In [11]:
>>>
>>> %timeit expr.subs([(var, variables[var]) for var in expr.args],
>>> simultaneous=True)
>>>
>>> 1000 loops, best of 3: 957 盜 per loop
>>>
>>> In [13]:
>>>
>>> %timeit expr.xreplace([(var, variables[var]) for var in expr.args])
>>>
>>> 10000 loops, best of 3: 91.7 盜 per loop
>>>
>>> In [8]:
>>>
>>> %timeit expr.xreplace(variables)
>>>
>>> 10000 loops, best of 3: 37.2 盜 per loop
>>>
>>>
>>>>
>>>>> 2.) Since I have many such expressions, am I missing a way to solve the
>>>>> whole system?
>>>> I'm not clear what you mean by "solve", but look at simplify_logic()
>>>> and satisfiable().
>>> Sorry for being unclear. By 'solve' I meant evaluate the expressions as
>>> above with actual truth values. I can't help but thinking, "if only this
>>> were linear algebra" since I basically have a matrix with expressions and
>>> involved symbols and then want to find the result of applying a vector with
>>> a certain conditions. I just don't know if there is a representation that
>>> would allow me to map one onto the other. Either way, I'm happy with the
>>> xreplace.
>>>>
>>>> Aaron Meurer
>>>>
>>>>> Thank you for your insights,
>>>>> Moritz
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups
>>>>> "sympy" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an
>>>>> email to [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> Visit this group at http://groups.google.com/group/sympy.
>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>
>>> Cheers,
>>> Moritz
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "sympy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/sympy.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sympy.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to