i am trying to use the "subs" function for differential equation
but i get the error: "can't convert expression to float"
i tryed to check the type of the arrays, but they all float
import sympy as sym
from sympy.integrals import inverse_laplace_transform
from sympy.abc import s,t,y
import numpy as np
U = 1
G =(s+1)/(s*(s+2))
Y = G*U
y = inverse_laplace_transform(Y, s, t)
tm = np.linspace(0,2,3)
y_val = np.zeros(len(tm))
for i in range(len(tm)):
y_val[i] = y.subs(t, tm[i])
print(y)
print(y_val)
line 17
y_val[i] = y.subs(t, tm[i])
TypeError: can't convert expression to float
Ths issue here is that, because tm[0] == 0, the evaluated y in the first iteration of your loop is Heaviside(0), which has no defined real value by default (see https://docs.sympy.org/latest/modules/functions/special.html#heaviside). This is because you have
from sympy.functions import exp, Heaviside
assert y == Heaviside(t) / 2 + exp(-2 * t) * Heaviside(t) / 2
The simplest workaround here is defining a linear space excluding 0, for instance
epsilon = 1e-15
tm = np.linspace(epsilon, 2, 3)
Using y_val = np.zeros(len(tm)), the default datatype of array is float. After modifying the code, you find that one of y_val elements is an object, not float. You can use a list object as a placeholder or you can specify the datatype of numpy array as object:
import sympy as sym
from sympy.integrals import inverse_laplace_transform
from sympy.abc import s,t,y
import numpy as np
U = 1
G =(s+1)/(s*(s+2))
Y = G*U
y = inverse_laplace_transform(Y, s, t)
tm = np.linspace(0,2,3)
# y_val = [0 for _ in range(len(tm))]
y_val = np.zeros(len(tm), dtype=object)
for i in range(len(tm)):
y_val[i] = y.subs(t, tm[i])
print(y_val)
result: [Heaviside(0.0) 0.567667641618306 0.509157819444367]
I have similar problem and your answers work for me, but I still need to put the data into graph.. I modified my problem for this question:
import sympy as sym
from sympy.integrals import inverse_laplace_transform
from sympy.abc import s,t,y
import numpy as np
import matplotlib.pyplot as plt
Y = (5*(1 - 5*s))/(s*(4*(s**2) + s + 1))*(1/s)
y = inverse_laplace_transform(Y, s, t)
tm = np.linspace(1e-15, 20, 100)
y_val = np.zeros(len(tm), dtype=object)
for i in range(len(tm)):
y_val[i] = y.subs(t, tm[i])
plt.plot(y_val, tm)
plt.show()
Running this code I got same error:
TypeError: can't convert expression to float
Related
I am trying to copy a numpy array and change the value of the copied array.
When I create the x array using np.array, the addition doesn't work and it prints 2.00.
import numpy as np
import copy
x = np.array([2,3,4])
inc= np.array([0.2,0.3,0.4])
x_copy = copy.copy(x)
x_copy[0] = x_copy[0] + inc[0]
print("x_copy %.2f" % x_copy[0])
But when I create x without np.array, it works and it prints 2.20.
import numpy as np
import copy
x = [2,3,4]
inc= np.array([0.2,0.3,0.4])
x_copy = copy.copy(x)
x_copy[0] = x_copy[0] + inc[0]
print("x_copy %.2f" % x_copy[0])
I also tried to copy x using x.copy(), but it didn't make any difference.
You can do it in two ways:
either
x =np.array([2.0,3.0,4.0])
or
x = np.array([2,3,4])
x = x.astype(float)
I am trying to minimize the "function()" with respect to two parameters. I have done so by creating mesh arrays and used them in the above "function()" to return similar meshed array values. However, upon using "fmin()" to find the minimum, the output says that the operators could not be broadcasted.
The code is pasted below:
import numpy as np
from scipy.optimize import fmin
import matplotlib.pyplot as plt
i=0
x_values = np.arange(-10,10,2)
y_values = np.arange(-10,10,2)
x_mesh = np.empty((0,len(x_values)))
y_mesh = np.empty((0,len(y_values)))
for i in range(len(x_values)):
y_mesh = np.vstack((y_mesh, y_values))
i=0
for i in range(len(y_values)):
x_mesh = np.vstack((x_mesh, x_values))
y_mesh = np.transpose(y_mesh)
def function(x_mesh, y_mesh):
return (2*x_mesh**2 + y_mesh**2)
''' Want to minimize function '''
x_start = np.zeros((len(x_values), len(y_values)))
y_start = x_start
y = fmin(lamda x_mesh: function(x_mesh, y_mesh), (x_start, y_start), full_output = True, disp = 0)
The output shown was:
File "C:/Users/User/Documents/Year2/Programming/elrter.py", line 42, in function
return (2*x_mesh**2 + y_mesh**2)
ValueError: operands could not be broadcast together with shapes (200,) (10,10)
But why does this happen? What is the solution?
I've got strange (from my point of view) result from numpy polyfit. My code:
import numpy as np
data=np.array([2482.9, 2483.0, 2485.9, 2486.0, 2486.4, 2485.1, 2485.4, 2484.9, 2484.8, 2484.8, 2484.8, 2484.0, 2484.1, 2484.1, 2484.1])
wr = range(len(data))
poly = np.polyfit(wr , data, deg = 2)
wp = np.poly1d(poly)
el = 2484.1
res = wp(el)
print(res)
#result -225256.888955
Is this a bug?
As #DSM has already said - it doesn't look like a quadratic polynom.
We can try to fit it with a higher degree though:
import numpy.polynomial.polynomial as poly
x = wr; y = data
coefs = poly.polyfit(x, y, 4)
ffit = poly.Polynomial(coefs)
plt.plot(x, y)
plt.plot(x, ffit(x))
plt.legend(['y(x)','ffit(x)'])
Result:
I have a folder with 38 files. The names are like this:
AWA_s1_features.mat, AWA_s2_features.mat......AWA_s38_features.mat
Each file is an array with 28 columns but with different # of rows. For example: AWA_s1_features.mat = (139,28), AWA_s2_features.mat = (199, 28) and so on.
As I am doing machine learning I need to join all these files in 1 huge array and label each row. So for the 139 rows of AWA_s1_features.mat there must be 139 1s; for AWA_s2_features.mat there must be 199 2s, and so on until AWA_s38_features.mat which must have a # of 38s.
This is what I mean:
I wrote some code. But I have found that the files are not called in order and therefore the labeling is wrong. For example, AWA_s1_features.mat is not the first file to be called and it has been labeled as 11. AWA_s2_features.mat has been labeled as 21.
So how can I improve my code so that it calls each file in the correct sequence?
Here is the code:
import numpy as np
import scipy.io as sio
import glob
read_files = glob.glob('I:/2D/Features 2D/AWA_s*.mat')
x = np.array([])
y = np.array([])
q = 1
for f in read_files:
l=sio.loadmat(f)['features']
x = np.concatenate((x, l), axis=0) if x.size else l
y_temp = q*np.ones((l.shape[0],1))
y = np.concatenate((y, y_temp), axis=0) if y.size else y_temp
q = q + 1
sio.savemat('AWA_FeaturesAll.mat', {'x':x, 'y':y})
The problem is that the default sorting is alphabetical, meaning that "11" comes before "2". You want numerical sorting and one way would be to use the sorted function with a key parameter, like so:
import numpy as np
import scipy.io as sio
import glob
read_files = glob.glob('I:/2D/Features 2D/AWA_s*.mat')
x = np.array([])
y = np.array([])
q = 1
for f in sorted(read_files, key=lambda f: int(f.split('_')[1][1:])):
l=sio.loadmat(f)['features']
x = np.concatenate((x, l), axis=0) if x.size else l
y_temp = q*np.ones((l.shape[0],1))
y = np.concatenate((y, y_temp), axis=0) if y.size else y_temp
q = q + 1
sio.savemat('AWA_FeaturesAll.mat', {'x':x, 'y':y})
I am trying to implement this function in theano.
This is not about solving the integral (which is immediate) but rather how to implement it.
So far I have gotten this
import theano
from theano import tensor as T
import numpy as np
import scipy.integrate as integrate
x = T.vector('x')
h = T.vector('h')
t = T.scalar('t')
A = np.asarray([[0,1],[1,0]])
A = theano.shared(name='A', value=A)
B = np.asarray([[-1,0],[0,-1]])
B = theano.shared(name='B', value=B)
xn = A.dot(x)
hn = B.dot(h)
res = (t + xn.dot(hn))**(-2)
g = theano.function([t,x,h],res) # this computes the integrand
f = theano.function([x,h], integrate.quad(lambda t: g(t,x,h), 10, np.inf))
Unfortunately, this doesn't work. I am getting the error missing 2 required positional arguments: 'x' and 'h'. Maybe the integrate.quad function cannot "see" the inputs x,h.
Thanks a lot for the help!