Imaginary Matrices in Sympy using MatrixSymbol - python

Multiplying a matrix with the imaginary unit raises an exception, i.e.,
import sympy as sy
M = sy.MatrixSymbol('M', 2, 2)
print(sy.I * M)
raises the exception
TypeError: Invalid comparison of non-real I
My current workaround is to replace sy.I with an i = sy.Symbol('i').
Is there a better way to use the MatrxixSymbol together with imaginary expressions?
Thanks.
PS: Conda Python 3.7.6 and Sympy version 1.5.1 is used.

This is a bug in SymPy. I've opened github.com/sympy/sympy/issues/18743 for it. The bug only occurs when printing the expression, so you can work around it by avoiding printing the expression.

Related

how to solve an equality containing tanh

I use the following example to try to solve the inequality containing tanh, but it produces the error
TypeError: Equation should be a polynomial with Rational coefficients
Anyone knows how to solve it ?
from sympy import Symbol, S
from sympy.solvers.solveset import solveset
x=Symbol('x')
v=0.05*x-8.5
solveset((1-(2*exp(-v))/(exp(v)+exp(-v)))>0, x, S.Reals)
You need to use exp from SymPy:
from sympy import Symbol, S
from sympy.functions import exp
from sympy.solvers.solveset import solveset
x = Symbol('x')
v = 0.05*x-8.5
solveset((1-(2*exp(-v))/(exp(v)+exp(-v)))>0, x, S.Reals)
which yields
Interval.open(170.000000000000, oo)
Having updated the sympy version to 1.9, the code finally works well for me.
Btw, in my case, in order to update the sympy, I should also update python to a newer version (currently 3.9.7) from my older version (3.7.1) since each python version seems to correspond to (a) certain sympy version(s).

sympy error 'Symbol' object is not callable

I am trying to solve an equation for r when given values for x and y. to do this I am using the solve ability of sympy. the code that I have is
import numpy as np
import matplotlib.pyplot as plt
from sympy import solve
from sympy import Symbol
from sympy import acos,sin
x=2
y=-2
r=Symbol("r",real=True)
solve(r(acos(1.0-(y/r)))-sin(acos(1.0-(y/r)))-x)
when I run the code it gives me the error
'Symbol' object is not callable
line 10, in <module>
solve(r(acos(1.0-(y/r)))-sin(acos(1.0-(y/r)))-x)
the reason I import numpy and matplotlib is that I will use them later in my code. Thanks for any help.
The error directs you toward what to look for: a Symbol that is being called. In Python syntax this is a Symbol followed by pair of parentheses with one or more arguments between them. You probably intended to multiply by r in the first argument of the expression:
>>> solve(r(acos(1.0-(y/r)))...
^__make that r*acos(1.0-(y/r))...
An editor that highlights matching parentheses (like the online editor of Python code at repl.it) can be helpful in these circumstances. Parentheses are either grouping or, when following a Python name, acting as the delimiters for the arguments being passed to a function.

"SystemError: <class 'int'> returned a result with an error set" in Python

I wanted to apply a very simple function using ndimage.generic_filter() from scipy. This is the code:
import numpy as np
import scipy.ndimage as ndimage
data = np.random.rand(400,128)
dimx = int(np.sqrt(np.size(data,0)))
dimy = dimx
coord = np.random.randint(np.size(data,0), size=(dimx,dimy))
def test_func(values):
idx_center = int(values[4])
weight_center = data[idx_center]
weights_around = data[values]
differences = weights_around - weight_center
distances = np.linalg.norm(differences, axis=1)
return np.max(distances)
results = ndimage.generic_filter(coord,
test_func,
footprint = np.ones((3,3)))
When I execute it though, the following error shows up:
SystemError: <class 'int'> returned a result with an error set
when trying to coerce values[4] to an int. If I run the function test_func() without using ndimage.generic_filter() for a random array values, the function works alright.
Why is this error occurring? Is there a way to make it work?
For your case:
This must be a bug in either Python or SciPy. Please file a bug at https://bugs.python.org and/or https://www.scipy.org/bug-report.html. Include the version numbers of Python and NumPy/SciPy, the full code that you have here, and the entire traceback.
(Also, if you can find a way to trigger this bug that doesn't require the use of randomness, they will likely appreciate it. But if you can't find such a method, then please do file it as-is.)
In general:
"[R]eturned a result with an error set" is something that can only be done at the C level.
In general, the Python/C API expects most C functions to do one of two things:
Set an exception using one of these functions and return NULL (corresponds to throwing an exception).
Don't set an exception and return a "real" value, usually a PyObject* (corresponds to returning a value, including returning None).
These two cases are normally incorrect:
Set an exception (or fail to clear one that already exists), but then return some value other than NULL.
Don't set an exception, but then return NULL.
Python is raising a SystemError because the implementation of int, in the Python standard library, tried to do (3), possibly as a result of SciPy doing it first. This is always wrong, so there must be a bug in either Python or the SciPy code that it called into.
I was having a very similar experience with Python 3.8.1 and SciPy 1.4.1 on Linux. A workaround was to introduce np.floor so that:
centre = int(window.size / 2) becomes centre = int(np.floor(window.size/2))
which seems to have resolved the issue.

Why does built-in sum behave wrongly after "from numpy import *"?

I have some code like:
import math, csv, sys, re, time, datetime, pickle, os, gzip
from numpy import *
x = [1, 2, 3, ... ]
y = sum(x)
The sum of the actual values in x is 2165496761, which is larger than the limit of 32bit integer. The reported y value is -2129470535, implying integer overflow.
Why did this happen? I thought the built-in sum was supposed to use Python's arbitrary-size integers?
See How to restore a builtin that I overwrote by accident? if you've accidentally done something like this at the REPL (interpreter prompt).
Doing from numpy import * causes the built-in sum function to be replaced with numpy.sum:
>>> sum(xrange(10**7))
49999995000000L
>>> from numpy import sum
>>> sum(xrange(10**7)) # assuming a 32-bit platform
-2014260032
To verify that numpy.sum is in use, try to check the type of the result:
>>> sum([721832253, 721832254, 721832254])
-2129470535
>>> type(sum([721832253, 721832254, 721832254]))
<type 'numpy.int32'>
To avoid this problem, don't use star import.
If you must use numpy.sum and want an arbitrary-sized integer result, specify a dtype for the result like so:
>>> sum([721832253, 721832254, 721832254],dtype=object)
2165496761L
or refer to the builtin sum explicitly (possibly giving it a more convenient binding):
>>> __builtins__.sum([721832253, 721832254, 721832254])
2165496761L
The reason why you get this invalid value is that you're using np.sum on a int32. Nothing prevents you from not using a np.int32 but a np.int64 or np.int128 dtype to represent your data. You could for example just use
x.view(np.int64).sum()
On a side note, please make sure that you never use from numpy import *. It's a terrible practice and a habit you must get rid of as soon as possible. When you use the from ... import *, you might be overwriting some Python built-ins which makes it very difficult to debug. Typical example, your overwriting of functions like sum or max...
Python handles large numbers with arbitrary precision:
>>> sum([721832253, 721832254, 721832254])
2165496761
Just sum them up!
To make sure you don't use numpy.sum, try __builtins__.sum() instead.

Changing floating point behavior in Python to Numpy style

Is there a way to make Python floating point numbers follow numpy's rules regarding +/- Inf and NaN? For instance, making 1.0/0.0 = Inf.
>>> from numpy import *
>>> ones(1)/0
array([ Inf])
>>> 1.0/0.0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division
Numpy's divide function divide(1.0,0.0)=Inf however it is not clear if it can be used similar to from __future__ import division.
You should have a look at how Sage does it. IIRC they wrap the Python REPL in their own preprocessor.
I tried to do something similar, and I never figured out how to do it nicely. But, I can tell you a few things I tried, that didn't work:
Setting float = numpy.float -- python still uses the old float
trying to change float.div to a user-defined function -- "TypeError: can't set attributes of built-in/extension type float". Also, python doesn't like you mucking with the dict object in built-in objects.
I decided to go in and change the actual cpython source code to have it do what I wanted, which is obviously not practical, but it worked.
I think the reason why something like this is not possible is that float/int/list are implemented in C in the background, and their behavior cannot be changed cleanly from inside the language.
You could wrap all your floats in numpy.float64, which is the numpy float type.
a = float64(1.)
a/0 # Inf
In fact, you only need to wrap the floats on the left of arithmetic operations, obviously.

Categories