Thanks for the suggestions.
I ended up with
class deferred_gcd(Function):
nargs = 2
def doit(self, **hints):
if hints.get('deep', True):
return sympy.gcd(self.args[0].doit(**hints),
self.args[1].doit(**hints))
else:
return sympy.gcd(self.args[0], self.args[1])
Using this same idea, I was able to create a deferred min/max, though I
limited it to two arguments, as I'm not sure how to use map to apply .doit
to all arguments.
class deferred_max(Function):
nargs = 2
def doit(self, **hints):
if hints.get('deep',True):
return max(self.args[0].doit(**hints),
self.args[1].doit(**hints))
else:
return max(self.args[0], self.args[1])
It doesn't seem like sympy consistently employs the "deep" hint. For
example, I couldn't get the sympy sign function to propagate doit to its
argument as it doesn't have the **hints argument. I wanted to use
sign(max(a,b)) and have sign pass .doit to the deferred max. Since I
couldn't get it to work, I just made a deferred_sign function of the above
form. It seems to work fine.
Thanks,
Duane
On Tuesday, March 26, 2013 3:18:13 PM UTC-5, Mateusz Paprocki wrote:
>
> Hi,
>
> On 26 March 2013 21:00, Duane Nykamp <[email protected] <javascript:>>
> wrote:
> > I'd like to delay evaluation of functions like gcd so that I can have
> users
> > enter an expression like gcd(a,b), where a and b will be replaced by
> > numbers. If I just enter gcd(a,b), it finds the gcd of the polynomials
> a
> > and b, which is one. Based on earlier feedback I receive here and by
> trial
> > and error, I came up with this method to delay evaluation, and I'm just
> > wondering if this is a reasonable way to do it. I can't say I really
> > understand the difference between subs and replace. I just messed
> around
> > until I found a method that worked.
> >
> > For example, if a and b are eventually going to be 3 and 9, the
> following
> > seems to work correctly, giving 3. I'm using parse_expr, as the
> expressions
> > are entered in a web page.
> >
> > In [170]: parse_expr('gcd(a,b)',local_dict={'gcd':
> >
> Function('gcd')}).subs([(Symbol('a'),3),(Symbol('b'),9)]).replace(Function('gcd'),gcd)
>
>
> > Out[170]: 3
> >
> > Is this a reasonable approach? Or is there a better method?
> >
>
> You can use this:
>
> In [4]: class gcd(Function):
> ...: @classmethod
> ...: def eval(cls, x, y):
> ...: if x.is_Number and y.is_Number:
> ...: return x.gcd(y)
> ...: else:
> ...: return None
> ...:
>
> In [5]:
>
> In [5]: var('a,b')
> Out[5]: (a, b)
>
> In [6]: gcd(a, b)
> Out[6]: gcd(a, b)
>
> In [7]: _.subs(a, 12)
> Out[7]: gcd(12, b)
>
> In [8]: _.subs(b, 6)
> Out[8]: 6
>
> > Thanks,
> > Duane
> >
> > --
> > 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] <javascript:>.
> > To post to this group, send email to [email protected]<javascript:>.
>
> > Visit this group at http://groups.google.com/group/sympy?hl=en-US.
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> >
>
> Mateusz
>
--
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?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.