Related
I created a very simple MWE to illustrate my problem. When I type y**(2), the program works. But when I type sin(y) or cos(y), it results in the error TypeError: can't convert expression to float. I discuss attempts to fix this error below.
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import Eq, Symbol, solve
import matplotlib.pyplot as plt
y = Symbol('y')
i = input()
i = ''.join(i).split(',')
for x in range(0, len(i)):
i[x] = i[x].strip()
userMediums = i
def refIndexSize(medium):
def refractiveProfile(y):
return eval(medium, {'y': y, 'np': np})
lowerProfile = Eq(eval(medium), 1)
upperProfile = Eq(eval(medium), 1.6)
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
return lowerProfile
refIndexSize(userMediums[0])
Error:
sin(y)+1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_48/825631216.py in <module>
29 return lowerProfile
30
---> 31 refIndexSize(userMediums[0])
/tmp/ipykernel_48/825631216.py in refIndexSize(medium)
20 return eval(medium, {'y': y, 'np': np})
21
---> 22 lowerProfile = eval(medium)
23 upperProfile = Eq(eval(medium), 1.6)
24 bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
<string> in <module>
/srv/conda/envs/notebook/lib/python3.7/site-packages/sympy/core/expr.py in __float__(self)
357 if result.is_number and result.as_real_imag()[1]:
358 raise TypeError("can't convert complex to float")
--> 359 raise TypeError("can't convert expression to float")
360
361 def __complex__(self):
TypeError: can't convert expression to float
I've looked at other questions regarding TypeError: can't convert expression to float, such as this and this. As a result, I have tried changing the order of my imports, although I can do nothing to change the wildcard from vpython import *, as it is the only way to import vpython (to my understanding), but this did not work. I've also tried inputting sp.sin(y) after looking at a different SO answer, but this did not help either. Once again, any tips or assistance is appreciated.
Your problem lies in this line:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
Specifically this part:
abs(round(float(solve(upperProfile)[0]),5))
Here the solve() function returns complex solutions in a list.
See this:
[1.5707963267949 - 1.04696791500319*I, 1.5707963267949 + 1.04696791500319*I]
So, when you pick the 0 index it will be a complex result like this one:
1.5707963267949 - 1.04696791500319*I
So, you are trying to cast float() to this solution which results in error. Instead you can remove the bounds for solutions having complex results by using try-except block like this:
try:
bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
abs(round(float(solve(upperProfile)[0]),5))]
lowerBound = np.amin(bounds)
upperBound = np.amax(bounds)
except:
print("The solutions are complex. Cant find a result")
Also import like this:
from vpython import *
from scipy.optimize import fsolve
import math
import numpy as np
import sympy as sp
from sympy import *
import matplotlib.pyplot as plt
In an ipython session, with the most relevant imports:
In [1]: import numpy as np
...: import sympy as sp
...: from sympy import Eq, Symbol, solve
Modify your function to return the bounds as well.
In [2]: def refIndexSize(medium):
...:
...: def refractiveProfile(y):
...: return eval(medium, {'y': y, 'np': np})
...:
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [abs(round(float(solve(lowerProfile)[0]),5)),
...: abs(round(float(solve(upperProfile)[0]),5))]
...: lowerBound = np.amin(bounds)
...: upperBound = np.amax(bounds)
...:
...: return lowerProfile, bounds
...:
Define the symbol, and call the function with a string. In the interactive session I don't need to go through the input complications.
In [3]: y = sp.Symbol('y')
y**2 gives the bounds that you claim in a comment:
In [4]: refIndexSize("y**(2)")
Out[4]: (Eq(y**2, 1), [1.0, 1.26491])
Errors due to sin definition
Using a sin expression gives a NameError. sin hasn't been imported or defined.
In [5]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-5-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
NameError: name 'sin' is not defined
Import sin from math gives your error:
In [6]: from math import sin
In [7]: refIndexSize("sin(y)+1")
Traceback (most recent call last):
File "<ipython-input-7-30c99485bce7>", line 1, in <module>
refIndexSize("sin(y)+1")
File "<ipython-input-2-6fea36c332b7>", line 6, in refIndexSize
lowerProfile = Eq(eval(medium), 1)
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 359, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
math.sin expects a float value, so does not work with symbol y.
But import sin from sympy, and it works:
In [8]: from sympy import sin
In [9]: refIndexSize("sin(y)+1")
Out[9]: (Eq(sin(y) + 1, 1), [0.0, 0.6435])
Errors due to complex values
Originally your question showed the use of sin(y), which gives the complex error that #Prakash discusses
In [10]: refIndexSize("sin(y)")
Traceback (most recent call last):
File "<ipython-input-10-d470e7448a68>", line 1, in <module>
refIndexSize("sin(y)")
File "<ipython-input-2-6fea36c332b7>", line 9, in refIndexSize
abs(round(float(solve(upperProfile)[0]),5))]
File "/usr/local/lib/python3.8/dist-packages/sympy/core/expr.py", line 358, in __float__
raise TypeError("can't convert complex to float")
TypeError: can't convert complex to float
Let's simplify your function to get rid float call that seems to be giving problems
In [11]: def refIndexSize(medium):
...: lowerProfile = Eq(eval(medium), 1)
...: upperProfile = Eq(eval(medium), 1.6)
...: bounds = [solve(lowerProfile),
...: solve(upperProfile)]
...: return lowerProfile, bounds
...:
Run on sin(y)+1), we get the [0.0, 0.6435] values as before:
In [12]: refIndexSize("sin(y)+1")
Out[12]: (Eq(sin(y) + 1, 1), [[0, pi], [0.643501108793284, 2.49809154479651]])
Run on sin(y), we see that the 'raw' bounds includes complex values:
In [13]: refIndexSize("sin(y)")
Out[13]:
(Eq(sin(y), 1),
[[pi/2],
[1.5707963267949 - 1.04696791500319*I,
1.5707963267949 + 1.04696791500319*I]])
If you really need a rounded float from such an answer, you need to either extract the real part first, or use abs first:
In [15]: bounds = _[1][1]
In [17]: abs(bounds[0])
Out[17]: 1.88773486361789
The function evaluates if I input a pair of arguments. But when I try to evaluate the function at grid points, it fails, saying "ValueError: dimension mismatch". I paste the code below. Could anyone help with the problem?
import numpy as np
from qutip import*
import pylab as plt
from numpy import eye,pi,kron,random,vdot,absolute,power,sqrt,matmul
from numpy import exp,arange
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
j0= tensor(sigmaz(),identity(2),identity(2))
def otoc(k0,n):
u0=(-1j*k0/6 *(tensor(sigmaz(),sigmaz(),identity(2)))).expm()
jn= u0.inv()**n*j0*u0**n
return ((commutator(jn,j0)* commutator(j0,jn)).tr()/8)
k0 = np.arange(0,4,0.1)
n = np.linspace(0,50,50)
X,Y = meshgrid(k0, n)
Z = otoc(X, Y)
The error showing is the following
Traceback (most recent call last):
File "/Users/sreerampg/Dropbox/myself/programs/levy's lemma/untitled8.py", line 27, in <module>
Z = otoc(X, Y)
File "/Users/sreerampg/Dropbox/myself/programs/levy's lemma/untitled8.py", line 20, in otoc
u0=(-1j*k0/6 *(tensor(sigmaz(),sigmaz(),identity(2)))).expm()
File "/Applications/anaconda3/lib/python3.7/site-packages/qutip/qobj.py", line 599, in __rmul__
return other * self.data
File "/Applications/anaconda3/lib/python3.7/site-packages/scipy/sparse/base.py", line 550, in __rmul__
return (self.transpose() * tr).transpose()
File "/Applications/anaconda3/lib/python3.7/site-packages/cvxpy/interface/scipy_wrapper.py", line 31, in new_method
return method(self, other)
File "/Applications/anaconda3/lib/python3.7/site-packages/scipy/sparse/base.py", line 516, in __mul__
raise ValueError('dimension mismatch')
ValueError: dimension mismatch
I used broyden1 in Python resolver. The question was answered here, I need to use a bit larger numbers, but not newton_krylov. If I use numbers over 100, then it starts throwing errors.
The code is here:
import numpy as np
import scipy.optimize
from scipy.optimize import fsolve
from functools import partial
from itertools import repeat
small_data=[100,220,350,480]
def G(small_data, x):
return np.cos(x) +x[::-1] - small_data
G_partial = partial(G, small_data)
approximate=list(repeat(1,period))
y = scipy.optimize.broyden1(G_partial, approximate, f_tol=1e-14)
print(y)
The error is:
Warning (from warnings module):
File "C:\Python\Python38\lib\site-packages\scipy\optimize\nonlin.py", line 1004
d = v / vdot(df, v)
RuntimeWarning: invalid value encountered in true_divide
Traceback (most recent call last):
File "read_data.py", line 176, in <module>
y = scipy.optimize.broyden1(G_partial, approximate, f_tol=1e-14)
File "<string>", line 6, in broyden1
File "C:\Python\Python38\lib\site-
packages\scipy\optimize\nonlin.py", line 350, in nonlin_solve
raise NoConvergence(_array_like(x, x0))
scipy.optimize.nonlin.NoConvergence: [ 99.49247662 219.22593164 350.14354166 480.95722345]
I found that the best method is changing the equation in Boryden1 to :
y = scipy.optimize.broyden1(G_partial, approximate, f_tol=5000e-14)
instead of:
f_tot=1e-14
so larger values will be accepted with a good accuracy
I'm trying to take the gradient of a function in which I assign numpy array elements individually (assigning local forces to a global force vector in an FEA), but this appears to break Autograd -- if I use np.zeros for the global array I get ValueError: setting an array element with a sequence, while if I use np.empty I get NotImplementedError: VJP of empty_like wrt argnums (0,) not defined.
Example:
import autograd.numpy as np
from autograd import jacobian, grad
def test(input):
a = np.empty_like(input)
a[:] = input[:]
grad(test)(np.array([0.]))
Gives the error:
C:\Miniconda3\python.exe C:/Users/JoshuaF/Desktop/gripper/softDrone/bug_test.py
Traceback (most recent call last):
File "C:\Miniconda3\lib\site-packages\autograd\core.py", line 31, in __init__
vjpmaker = primitive_vjps[fun]
KeyError: <function primitive.<locals>.f_wrapped at 0x000001AB1D0AA8C8>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/JoshuaF/Desktop/gripper/softDrone/bug_test.py", line 8, in <module>
grad(test)(np.array([0.]))
File "C:\Miniconda3\lib\site-packages\autograd\wrap_util.py", line 20, in nary_f
return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
File "C:\Miniconda3\lib\site-packages\autograd\differential_operators.py", line 25, in grad
vjp, ans = _make_vjp(fun, x)
File "C:\Miniconda3\lib\site-packages\autograd\core.py", line 10, in make_vjp
end_value, end_node = trace(start_node, fun, x)
File "C:\Miniconda3\lib\site-packages\autograd\tracer.py", line 10, in trace
end_box = fun(start_box)
File "C:\Miniconda3\lib\site-packages\autograd\wrap_util.py", line 15, in unary_f
return fun(*subargs, **kwargs)
File "C:/Users/JoshuaF/Desktop/gripper/softDrone/bug_test.py", line 5, in test
a = np.empty_like(input)
File "C:\Miniconda3\lib\site-packages\autograd\tracer.py", line 45, in f_wrapped
node = node_constructor(ans, f_wrapped, argvals, kwargs, argnums, parents)
File "C:\Miniconda3\lib\site-packages\autograd\core.py", line 35, in __init__
.format(fun_name, parent_argnums))
NotImplementedError: VJP of empty_like wrt argnums (0,) not defined
Is there any way to use Autograd on a numpy array which is assembled element-wise?
Based on the tutorial https://github.com/HIPS/autograd/blob/master/docs/tutorial.md, it looks like array assignment is unfortunately not supported in autograd functions.
I have written the following python plotting script using matplotlib:
import pynbody as pyn
import numpy as np
import matplotlib.pyplot as plt
import glob
s = pyn.load('./ballsV2.00001')
sl = s.g[np.where((s.g['z'] < 0.005) & (s.g['z']>-0.005))]
sx = s.s['x'][0]
sy = s.s['y'][0]
sz = s.s['z'][0]
r2 = ((s.g['x']-sx)**2+(s.g['y']-sy)**2+(s.g['z']-sz)**2)
Flux = np.array(1./(4*np.pi*r2)*np.exp(-1*7.00114988051*np.sqrt(r2)))
print(type(np.log10(sl['radFlux'])))
print(type(np.log10(Flux)))
plt.figure(figsize = (15,12))
#plt.scatter(sl['x'],sl['y'],c=np.log10(sl['radFlux']),s=75,edgecolors='none', marker = '.',vmin=-6,vmax=1)
plt.scatter(sl['x'],sl['y'],c=np.log10(Flux),s=75,edgecolors='none', marker = '.',vmin=-8,vmax=4)
plt.xlim([-0.5,0.5])
plt.ylim([-0.5,0.5])
plt.xlabel("x")
plt.ylabel("y")
plt.colorbar(label="log(Code Flux)")
plt.savefig('./ballsV2_0.1.pdf')
plt.savefig('./ballsV2_0.1.png')
plt.show()
plt.close()
When I run the script I get the following error:
foo#bar ~/Data/RadTransfer/Scaling_Tests/ballsV2 $ py
balls.py
balls.py:15: RuntimeWarning: divide by zero encountered in log10
print(type(np.log10(sl['radFlux'])))
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
Traceback (most recent call last):
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/colors.py", line 141, in to_rgba
rgba = _colors_full_map.cache[c, alpha]
KeyError: (-4.1574455411341349, None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/colors.py", line 192, in _to_rgba_no_colorcycle
c = tuple(map(float, c))
TypeError: 'numpy.float64' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "balls.py", line 17, in <module>
plt.scatter(sl['x'],sl['y'],c=np.log10(Flux),s=75,edgecolors='none', marker = '.',vmin=-8,vmax=4)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 3435, in scatter
edgecolors=edgecolors, data=data, **kwargs)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/__init__.py", line 1892, in inner
return func(ax, *args, **kwargs)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 4028, in scatter
alpha=alpha
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/collections.py", line 890, in __init__
Collection.__init__(self, **kwargs)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/collections.py", line 139, in __init__
self.set_facecolor(facecolors)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/collections.py", line 674, in set_facecolor
self._set_facecolor(c)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/collections.py", line 659, in _set_facecolor
self._facecolors = mcolors.to_rgba_array(c, self._alpha)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/colors.py", line 237, in to_rgba_array
result[i] = to_rgba(cc, alpha)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/colors.py", line 143, in to_rgba
rgba = _to_rgba_no_colorcycle(c, alpha)
File "/home/grondjj/anaconda3/lib/python3.6/site-packages/matplotlib/colors.py", line 194, in _to_rgba_no_colorcycle
raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
ValueError: Invalid RGBA argument: -4.1574455411341349
Ignore the divide by zero stuff,the issue is the scatter plot function isn't taking my array of values to map colour to. What is strange is that the commented out scatter plot command above it runs fine. The only difference is the array of values I am passing it. I made sure to cast them to the same type (they are both <class 'numpy.ndarray'>). Also, the values themselves are more sane ranging between ~4000 and 1E-7 in the Flux array, it is only the np.log10(sl['radFlux'] that has the divide by zero errors and that one works. Any suggestions?
Flux and np.log10(sl['radFlux']) ended up being different lengths. sl (a slice of s) was not used to compute r2, so Flux ended up being to big. It would be nice if matplotlib checked that the color array was the same length as the scatter x and y arrays and had an error message like it does when the x and y arrays are different lengths.