What is wrong with my call to checkodesol in sympy? - python

I am learning sympy, and wanted to verify the solution to an ODE. I do not yet quite understand sympy naming conventions.
Instead of doing the standard methods of loading all packages at the top, I wanted to just import sympy and then use explicit long name to reference any other name inside sympy. On latest conda python
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0] :: Anaconda, Inc. on linux
When typing
import sympy
x = sympy.symbols('x')
y = sympy.Function('y')
ode = sympy.Eq(sympy.Derivative(y(x),x),1+2*x)
sol = sympy.dsolve(ode,y(x))
sympy.solvers.ode.checkodesol(ode,sol)
And the above gives error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'sympy.solvers.solvers' has no attribute 'ode'
But from the page https://docs.sympy.org/latest/modules/solvers/ode.html
It says
But if I do the following, it works
from sympy import checkodesol
checkodesol(ode,sol)
(True, 0)
But I do not want to import checkodesol explicitly. I want to just import sympy and then use the long name to call checkodesol or any other sympy sub packages, as this makes it more clear to me in the code where each function is coming from (at the cost of a little extra typing)
The question is, why using sympy.solvers.ode.checkodesol does not work?

At the very top of the documentation you linked to, it says
These are functions that are imported into the global namespace with
from sympy import *. These functions (unlike Hint Functions, below)
are intended for use by ordinary users of SymPy.
Then you can use checkodesol(ode, sol) directly.
If you do import sympy, then you need to call
sympy.checkodesol(ode, sol)

Related

NameError: name 'cos' is not defined, sageMath9.4

I am writing a Python module using SageMath9.4. Basically, I want to import this module into Jupyterlab Notebooks (running a SageMath 9.4 kernel) to do calculations etc.
Here is the start of it:
class Coxeter_System:
'''This class defines the standard root system associated to an abstract Coxeter group.'''
def __init__(self, coxeter_matrix):
'''Sets up a Coxeter system and root system. At this stage, limited to up to rank 7.
'''
def set_up_coefficient_space(coxeter_matrix):
'''Sets up a polynomial ring a Free module over a polynomial ring quotiented by the minimal polynomials of the
non-rational cos(pi/m_ij) values.
This is so roots can be compared using an abstract free module rather than over reals'''
A = coxeter_matrix
k = len(A.rows())
# Get the cos(pi/m_ij) which are irrational
non_rational_angles = [x for x in [cos(pi/x) for x in set(A[i,j] for i in range(0,k) for j in range(0,k))] if x not in QQ]
However, when I open another Jupyterlab session, import the Python module and try to create an instance of the object "Coxeter_System", I get the following error (I have tried to do from math import cos both from the notebook where I want to import the module to, and in the module itself, but I still get the same error.
Any help would be greatly appreciated!):
NameError Traceback (most recent call last)
<ipython-input-6-6b542b6cb042> in <module>
----> 1 W = c.Coxeter_System(Matrix([[Integer(1),Integer(3),Integer(4)],[Integer(3),Integer(1),Integer(3)],[Integer(4),Integer(3),Integer(1)]]))
~/coxeter_groups.py in __init__(self, coxeter_matrix)
60 return matrix(R,k,B)
61
---> 62 R = set_up_coefficient_space(coxeter_matrix)
63 A = coxeter_matrix
64 k = len(A.rows())
~/coxeter_groups.py in set_up_coefficient_space(coxeter_matrix)
17
18 # Get the cos(pi/m_ij) which are irrational
---> 19 non_rational_angles = [x for x in [cos(pi/x) for x in set(A[i,j] for i in range(0,k) for j in range(0,k))] if x not in QQ]
20
21 # sort the irrational values of cos(pi/m_ij) in ascending order
~/coxeter_groups.py in <listcomp>(.0)
17
18 # Get the cos(pi/m_ij) which are irrational
---> 19 non_rational_angles = [x for x in [cos(pi/x) for x in set(A[i,j] for i in range(0,k) for j in range(0,k))] if x not in QQ]
20
21 # sort the irrational values of cos(pi/m_ij) in ascending order
NameError: name 'cos' is not defined
Just use math.cos instead of using cos after from math import cos
e.g. math.cos(pi/x)
import math
math.cos(pi/x)
For most IDEs you will have to import some of the most popular math packages,
# Example:
import numpy as np
import math as m
import sagemath as sm
numpy and math you will have no problem using it with a simple import numpy in Google Colab or most popular IDEs.
What is SageMath?
SageMath, previously known as Sage, is a computational algebraic system (CAS) that stands out for being built on mathematical and contrasted packages such as NumPy, Sympy, PARI/GP o Máxima.
Install the SageMath package in Jupyter Notebook:
In the case of sagemath, inside jupyter you will have to do some extra steps.
To install the sagemath package we must do a pip:
!pip install sagemath
The image shows the confirmation within Jupyter
Using sagemath
# import and add the alias s
import sagemath as s
Yo use it we place the alias "s" in front of the function
s.cos(s.pi/x)
If sagemath does not always work correctly.
We know the following: "The philosophy of SageMath is to use existing open-source libraries wherever they exist. Therefore, it uses many libraries from other projects."
For these mathematical functions you can use numpy:
import numpy as np
np.cos(np.pi/x)
It will not fail and also in Jupyter you do not need additional installation.
I hope I've been useful.

How to access QString for QGIS-2.14 in PyQt4

This is a bit QGIS specific, but figure it's kind of low level so I've posted here. I can definitely move this over to gis.stackexchange.com if that's better.
Trying to use QgsRasterCalculator, which seems to want a QString type object for a couple of arguments. I try to create a QString (like described here) but get:
import PyQt4
PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QString'
So I try to use a regular string for my first argument (calc = QgsRasterCalculator( 'demffac > 120', newStreams, 'GTiff', rFac.extent(), rFac.crs().authid(), rFac.height(), rFac.width(), entries)), I got:
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: arguments did not match any overloaded call:
QgsRasterCalculator(QString, QString, QString, QgsRectangle, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QString, QString, QString, QgsRectangle, QgsCoordinateReferenceSystem, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QgsRasterCalculator): argument 1 has unexpected type 'str'
I'm using QGIS 2.14, which has been documented as using QString (as I understand it). I've tried to use the sip package to reset (per these instructions) but QGIS's python console doesn't seem to want to change (ValueError: API 'QString' has already been set to version 2).
Any way to make my QgsRasterCalculator() call work? Thanks for any info!
/==================EDIT: screen grab of my QGIS's responses to suggestions=========
/==================
Version info:
from PyQt4.QtCore import QT_VERSION_STR
from PyQt4.pyqtconfig import Configuration
print("Qt version:", QT_VERSION_STR)
('Qt version:', '4.8.5')
cfg = Configuration()
print("SIP version:", cfg.sip_version_str)
('SIP version:', '4.14.7')
print("PyQt version:", cfg.pyqt_version_str)
('PyQt version:', '4.10.2')
Looking more closely at the traceback, it seems that QgsRasterCalculator does not require the use of QString. This is proved by the fact that you passed python strings for the first three arguments, and the error message does not complain about them at all. Rather, it complains about the fifth argument, which must be either an int or QgsCoordinateReferenceSystem object, whereas you seem to be passing in unicode or str objects. Why are you passing in the return value of rFac.crs().authid()? Surely you should be passing in rFac.crs(), rather than authid() (which is documented as returning a string).
With regard to potential issues with QString:
When used with Python2, PyQt4 most definitely does have the QString class - unless you take explicit steps to change that by using the sip module. The code at the beginning of your question is not what you actually ran, because it does not raise that specific error:
Python 2.7.15 (default, Jun 27 2018, 13:05:28)
[GCC 8.1.1 20180531] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt4
>>> PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QtCore'
If you import the QtCore module properly, the code works fine:
>>> from PyQt4 import QtCore
>>> QtCore.QString('foo')
PyQt4.QtCore.QString(u'foo')
Note that it never makes sense to import the PyQt4 package on its own. It is just an empty namespace which (for performance reasons) imports the other modules lazily. You must therefore always import the Qt modules explicitly as I have done above.
PS:
In the second half of your question, it seems that the PyQt APIs have somehow already been changed to version 2, which will switch off support for QString. To switch it back on, you would need to do:
import sip
sip.setapi('QString', 1)
However, this step must be done before any other PyQt modules are imported.

RecursionError: maximum recursion depth exceeded on integrate, sympy 1.1.1

Bug entered at https://github.com/sympy/sympy/issues/14877
Is this a known issue? Is this a new bug? Will report if new.
What could cause it?
>which python
/opt/anaconda/bin/python
>pip list | grep sympy
sympy 1.1.1
>python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
from sympy import *
x=symbols('x');
integrate(exp(1-exp(x**2)*x+2*x**2)*(2*x**3+x)/(1-exp(x**2)*x)**2,x)
gives
.....
File "/opt/anaconda/lib/python3.6/site-packages/sympy/core/mul.py", line 1067, in <genexpr>
a.is_commutative for a in self.args)
RecursionError: maximum recursion depth exceeded
>>>
btw, the anti derivative should be
-exp(1-exp(x^2)*x)/(-1+exp(x^2)*x)
It is a known issue that SymPy fails to integrate many functions. This particular function probably wasn't reported yet, so by all means, add it to the ever-growing list.
SymPy tries several integration approaches. One of them, called "manual integration", is highly recursive: a substitution or integration by parts is attempted, and then the process is repeated for the resulting integral.
In this specific case, the expression has a lot of functions that look like candidates for substitution: x**2, the denominator, the content of another exponential function. And SymPy goes into an infinite chain of substitution that leads not to a solution but to a stack overflow... There is no pattern implemented in integrate that would tell SymPy to make the crucial substitution u = 1 - x*exp(x**2).
There is a separate, experimental, integrator called RUBI which could be used with
from sympy.integrals.rubi.rubi import rubi_integrate
rubi_integrate(exp(1-exp(x**2)*x+2*x**2)*(2*x**3+x)/(1-exp(x**2)*x)**2, x)
but it relies on MatchPy which I don't have installed, so I can't tell if it would help here.

Access to mpmath module in sympy (python)

I am new to sympy and still naive about python.... I wanted to solve a trigonometric equation, to find its zeroes. (Once I have syntax, then I will use a more complex function.)
I cannot find the right syntax yet. Here is what I tried at the iPython console in Spyder (Python 2.7):
from sympy.solvers import solve
from sympy import Symbol
x = Symbol('x')
solve(sin(x), x)
I got this error:
Traceback (most recent call last):
File "", line 1, in
solve(sin(x), x)
NameError: name 'sin' is not defined
OK, so I need to have the correct reference to the sine function.
According to the sympy documentation, I thought this was in mpath, but this did not work:
from mpmath import *
Traceback (most recent call last):
File "<ipython-input-7-8dcdd12d9679>", line 1, in <module>
from mpmath import *
ImportError: No module named mpmath
How do I load/access mpmath or some other way to get the sine function?
This fixed it:
from sympy import sin
To access mpmath do this
from sympy.mpmath import *

Python SymPy solving linear system

I have Python 3.3.3 and SymPy 0.7.4.1, both in x64 version and installed locally on my computer. I am using PSPad as a configured editor for Python scripting.
When using imports from library sympy in a module which should solve a set of three linear equations:
from sympy import Matrix, solve_linear_system
from sympy.abc import x, y, z
def main():
system = Matrix (((3,2,-1,1) ,(2,-2,4,-2),(-1,0.5,-1,0)))
print(solve_linear_system(system, x, y,z))
if __name__ == "__main__":
main()
The editor PSPad console output returns the following:
traceback (most recent call last): File "C:\Users\GOODLU~1\AppData\Local\Temp\PSpad\securesafety_DISK_5GB\Programmation\linear system solve SYMPY.py", line 1, in <module>
from sympy import Matrix,solve_linear_system File "C:\Users\GOODLU~1\AppData\Local\Temp\PSpad\securesafety_DISK_5GB\Programmation\sympy.py", line 2, in <module>
from sympy import var,Eq,solve ImportError: cannot import name var
Process completed, Exit Code 1.
Execution time: 00:00.134
Actually, I am wondering myself heavily about those issues:
Why, when typing the same thing, without an object def main(), and entered line by line in IDLE, everything is solved correctly, as: {x: 1.00000000000000, y: -2.00000000000000, z: -2.00000000000000}
Why, my PSPad file with object, having the same computation lines, doesn't work and returns errors?
In fact, I would like to use SymPy in normal python code and get computed results in a list or printed in console( .. as in IDLE). Just in order to avoid some annoying line-to-line IDLE manipulations, what should my code file look like?
The problem seems to be that you have created a file named sympy.py, which has the same name as the sympy module.
Hence, in the from sympy import ... statement, your sympy.py is acting as the sympy module.
Try renaming the file to something else, like sympy_programming_test.py and let know if it works.

Categories