defining custom functions [again]

64 views
Skip to first unread message

Felipe Vieira

unread,
Jul 28, 2016, 11:24:09 AM7/28/16
to sympy
He all,

I've read the posts. And the tutorial. And the code.

Still I'm having trouble defining my own functions.

Let's start with the very basics: I would like to define f(x) = 2 * x:

from sympy import *
from sympy.abc import x, y
import sympy

class Double(Function):
    u"""A simple function that doubles the input."""

    @classmethod
    def eval(cls, arg):
        return None

    def fdiff(self, argindex = 1):
        return Integer(2) * self.args[0]

    def __new__(cls, *args, **kwargs):
        return super(Double, cls).__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        super(Double, self).__init__()

d = Double('d')

d(2)

When I run the code I get: 
TypeError: 'Double' object is not callable


How can I pythonically/sympythonically define a Double inheriting from function? Notice that this is just a first step in defining more 'complex' functions (so don't tell me to use Lambda).

Grea work with the project! Thank you!

Aaron Meurer

unread,
Jul 28, 2016, 11:28:01 AM7/28/16
to sy...@googlegroups.com
Function is a bit confusing, because Function('f') creates a subclass
called f, but this property is not inherited when you inherit from
Function. So your object just works like

Double(2)

Also, your overriding of __new__ and __init__ is unnecessary, since
they don't do anything (and in general, anything you'd want to do in
those methods for subclasses of Function you should do in eval()).

Aaron Meurer
> --
> 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 sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/7cdffc27-8187-43af-a6be-68b15fbe9197%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Felipe Vieira

unread,
Jul 29, 2016, 7:04:59 AM7/29/16
to sympy
Let me try again:
class Double(Function):
    u"""A simple function that doubles the input."""

    nargs = 1

    @classmethod
    def eval(cls, arg):
        pass
        if arg.is_Number:
            return sympy.Mul(2, arg)

    def fdiff(self, argindex = 1):
        return sympy.Integer(2)
This generates:
In [47]: Double(x)
Out[47]: Double(x)

In [48]: Double(2*x)
Out[48]: Double(2*x)

In [49]: Double(2*x).fdiff()
Out[49]: 2

In [50]: Double(2*x).diff()
Out[50]: 4

So now it looks like it is working as expected.
I thought the same way I could do: f = Function('f') I could also do d = Double('d') then d(2).

As mentioned above, is this the expected way of doing things?

Aaron Meurer

unread,
Jul 29, 2016, 11:20:35 AM7/29/16
to sy...@googlegroups.com
Yes, this implementation looks correct.

Aaron Meurer
> --
> 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 sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/ac199e4a-62cf-4635-80fb-d45a5a828613%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages