ghpythonremote
ghpythonremote copied to clipboard
GH Python remote with Sympy
Hello,
I have a problem while import sympy in the GH Python through GH Python remote. The code is as below:
import rhinoscriptsyntax as rs import scriptcontext as sc import ghpythonremote sp = sc.sticky['sympy']
x = sp.symbols('x') q = sp.symbols('q', cls=Function) Mq = sp.symbols('Mq', cls=Function) Vq = sp.symbols('Vq', cls=Function) diffeqbmq = Eq(Mq(x).diff(x,x), -q) BMq = dsolve(diffeqbmq, Mq(x), ics = {Mq(0):0, Mq(l):0}) SFq = Eq(Vq(x),BMq.rhs.diff(x))
but the functions in Sympy such as Function, Eq, dsolve is not usable in gh python. it shows a warning: name 'Function' is not defined.
Could I ask how to solve it?
Hi,
Function is a class defined in the top level module sympy. To use it in
your script, you either need to do Function = sp.Function, then use the
name Function, or use sp.Function everywhere.
That replaces import lines such as from sympy import Function that are
normally defined at the top of these scripts.
I'm on mobile and couldn't find exactly where Eq and dsolve are defined in sympy. If you assign those names or use the fully qualified name every time like I wrote for Function, you should be able to run your script.
Thank you for your quick reply!
I did what you suggest, but it shows another warning:
_Runtime error (Exception): type() argument 1 must be string, not unicode
Traceback:
line 102, in value, "C:\Users\20204895\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rpyc\core\async_.py"
line 469, in sync_request, "C:\Users\20204895\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rpyc\core\protocol.py"
line 76, in syncreq, "C:\Users\20204895\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rpyc\core\netref.py"
line 253, in __call__, "C:\Users\20204895\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rpyc\core\netref.py"
line 18, in script_
line 18 is : q = sp.symbols('q', cls=Function)
I'm not sure if it's the problem with python 2.7, since it works well with python 3.0
That looks like a mismatch between what IronPython thinks is a string
(unicode) and what Cpython 2 does (bytes). The 'q' string is local to
IronPython, so is unicode, and when sympy receives in python 2 it cannot
use it as a (bytes) string there.
I'm away until the end of the month and do not have access to a computer to help you with some code to workaround this. You might be able to make it work with some combination of:
- using bytes strings in IronPython (
b'q') - using the
rpy.deliverutility function to create a string that is local to the Cpython interpreter, if you can find a way to make sure it is bytes and not unicode - importing the
strtype from Cpython and use it to create Cpython strings.
Sorry I can't help much more right now, hope you can make it work
Hi @r-yu52, sorry it's been a while since you asked for help on this but I've been doing some cleaning around here and just looked at it again today.
From what I can tell, I can properly run sympy functionalities from Grasshopper, as long as all strings sent to it are bytes strings. (And of course, imports need to be properly defined in each of the GHPython scripts you run.) The code below gives the expected result:
import scriptcontext as sc
sp = sc.sticky['sympy']
x = sp.symbols(b'x')
q = sp.symbols(b'q', cls=sp.Function)
Mq = sp.symbols(b'Mq', cls=sp.Function)
Vq = sp.symbols(b'Vq', cls=sp.Function)
l = sp.symbols(b'l') # Symbol l was not defined
diffeqbmq = sp.Eq(Mq(x).diff(x, x), -q(x)) # -q is not valid, symbolic functions need to be instantiated: -q(x)
BMq = sp.dsolve(diffeqbmq, Mq(x), ics={Mq(0): 0, Mq(l): 0})
SFq = sp.Eq(Vq(x), BMq.rhs.diff(x))
print(BMq, SFq)
Note that your original code had a couple of additional errors that prevented it from working, even outside in regular CPython, see the comments in the code.