-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
translate abstract functions to Sage #13476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
No travis log. I restarted the build but it doesn't show here. |
|
The plotting tests fail under Py3 with: The reason is the warning |
|
Please add a test to the sage tests. |
|
Note to whomever merges this: the sage tests are set to allowed failure in Travis, so you need to check them manually. |
|
See also https://trac.sagemath.org/ticket/20204 |
|
That should be it now. |
|
@rwst can you please resolve merge conflicts. |
|
@rwst are you still interested in this? |
|
@timokau this patch to sympy https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/sympy/default.nix#L25 in nix break with current master. @rwst still interested in this PR? |
|
@rswt Are you still interested to work on this PR? |
|
✅ Hi, I am the SymPy bot (v149). I'm here to help you write a release notes entry. Please read the guide on how to write release notes. Your release notes are in good order. Here is what the release notes will look like: This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.5. Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
Codecov Report
@@ Coverage Diff @@
## master #13476 +/- ##
=============================================
- Coverage 74.76% 61.964% -12.797%
=============================================
Files 634 634
Lines 165333 165342 +9
Branches 38857 38861 +4
=============================================
- Hits 123604 102453 -21151
- Misses 36309 57050 +20741
- Partials 5420 5839 +419 |
|
Travis-CI build with sage doesn't produce coverage reports, so the lines in coverage report are red, but those lines are tested. |
sympy/core/function.py
Outdated
| __dict__['__module__'] = None | ||
| obj = super(UndefinedFunction, mcl).__new__(mcl, name, bases, __dict__) | ||
| obj.name = name | ||
| obj._sage_ = UndefSage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a different instance for each undefined function? As far as I can tell the UndefSage class has no instance data so it can be a singleton class. In fact why isn't it just a property-method using @property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to a Singleton class.
In fact why isn't it just a property-method using
@property?
What do you mean by this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we instead define a method like this?
@property
def _sage_(self):
...It isn't normally necessary to explicitly create a descriptor object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is a class with AppliedUndef as a base and therefore its _sage_ is called instead of the method like you mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant that it's a meta class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does seem that way (I'm trying to think of an alternative...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw when I said the class could be a singleton I just meant that it could be like:
class A:
pass
a = A()
...
obj._sage_ = arather than using more metaclasses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that increase import time for sympy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why it would increase import time. Here's a quick test (module t.py):
from sympy.core.compatibility import with_metaclass
from sympy.core.singleton import Singleton
def f():
class A(with_metaclass(Singleton)):
pass
def g():
class B:
pass
b = B()Running this with timeit I get:
$ python -m timeit -s 'from t import f, g' 'f()'
1000 loops, best of 5: 222 usec per loop
$ python -m timeit -s 'from t import f, g' 'g()'
50000 loops, best of 5: 9.72 usec per loopSo normal Python classes are 20 times faster than Singleton/metaclass.
The purpose of the Singleton metaclass is to install the class in the singleton registry so it becomes available as e.g. S.Infinity which isn't what we want here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @oscarbenjamin, I've removed the use of Singleton metaclass and used the method you proposed.
|
Looks good. Thanks. |
|
Thanks @oscarbenjamin for the review |
This finally fixes the conversion of abstract functions to Sage. Reason to do it this way:
When
F=Function('abc')is called the constructor ofFunctionuses the metaclassUndefFunctionto create a new class with parentAppliedUndefnamedabc. CallingF._sage_()will NOT call the_sage_()member ofAppliedUndefbut tries to callabc._sage_()which does not exist at installation time. This, however, is not a problem because we can dynamically add a_sage_()method toabcon creation ofabcinsideUndefFunction.__new__. So converting abstract functions works.The problem is that now
F(x)._sage_()will call the sameabc._sage_()class method while previously it was referred to the superclass, i.e. theAppliedUndef._sage_()member function. But_sage_as class method does not know about the specific instance and its argumentx!This issue does not contain test code because testing Sage in Travis does not work at the moment and the PR patch is tested in Sage thoroughly, see https://trac.sagemath.org/ticket/20204