I have the following issue with Sympy when trying to solve difference (recursive) equations. When the free terms are integers, everything is OK, e.g.
y = sym.Function('y')
t = sym.symbols('t',integer=True)
f = y(t)- 1/3*y(t-1) - 9
eq_sol = sym.rsolve(f,y(t))
eq_sol
But if a coefficient is a decimal or a fraction, such as here (9 changes to 9.1),
y = sym.Function('y')
t = sym.symbols('t',integer=True)
f = y(t)- 1/3*y(t-1) - 9.1
eq_sol = sym.rsolve(f,y(t))
eq_sol
an error appears:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_27564/4249747763.py in <module>
2 t = sym.symbols('t',integer=True)
3 f = y(t)- 1/3*y(t-1) - 9.1
----> 4 eq_sol = sym.rsolve(f,y(t))
5 eq_sol
~\Anaconda3\lib\site-packages\sympy\solvers\recurr.py in rsolve(f, y, init)
741 h_part[int(result[k])].append(coeff)
742 continue
--> 743 raise ValueError(
744 "'%s(%s + k)' expected, got '%s'" % (y.func, n, h))
745 for k in h_part:
ValueError: 'y(t + k)' expected, got '9.10000000000000'
I would be grateful to those who could provide a hint.
Thank you very much, Oscar Benjamin! That did the trick:
y = sym.Function('y')
t = sym.symbols('t',integer=True)
f = y(t)- 1/3*y(t-1) - Fraction(9,2) # different number here, not 9.1
eq_sol = sym.rsolve(f,y(t))
eq_sol
Related
I need to make an integral of the type g(u)jn(u) where g(u) is a smooth function without zeros and jn(u) in the Bessel function with infinity zeros, but I got the following error:
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
First I need to change of variable x to variable u and make an integration in the new variable u but how the function u(x) is not analytically invertible so I need to use interpolation to make this inversion numerically.
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
x = np.linspace(0.1, 100, 1000)
u = lambda x: x*np.exp(x)
dxdu_x = lambda x: 1/((1+x) * np.exp(x)) ## dxdu as function of x: not invertible
dxdu_u = InterpolatedUnivariateSpline(u(x), dxdu_x(x)) ## dxdu as function of u: change of variable
After this, the integral is:
from mpmath import mp
def f(n):
integrand = lambda U: dxdu_u(U) * mp.besselj(n,U)
bjz = lambda nth: mp.besseljzero(n, nth)
return mp.quadosc(integrand, [0,mp.inf], zeros=bjz)
I use quadosc from mpmath and not quad from scipy because quadosc is more appropriate to make integral of rapidly oscillating functions, like Bessel functions. But, by other hand, this force me to use two different packges, scipy to calculate dxdu_u by interpolation, and mpmath to calculate the Bessel functions mp.besselj(n,U) and the integral of the product dxdu_u(U) * mp.bessel(n,U) so I suspect that this mix of two different packages can make some issue/ conflict. So when I make:
print(f(0))
I got the error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-38-ac2976a6b736> in <module>
12 return mp.quadosc(integrand, [0,mp.inf], zeros=bjz)
13
---> 14 f(0)
<ipython-input-38-ac2976a6b736> in f(n)
10 integrand = lambda U: dxdu_u(U) * mp.besselj(n,U)
11 bjz = lambda nth: mp.besseljzero(n, nth)
---> 12 return mp.quadosc(integrand, [0,mp.inf], zeros=bjz)
13
14 f(0)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
Does anyone know how I can solve this problem?
Thanks
The full traceback (the part you sniped) shows that the error is in the __call__ method of the univariatespline object. So indeed the problem is that the mpmath integration routine feeds in its mpf decimals, and scipy has no way of dealing with them.
A simplest fix is then to manually cast the offending part of the argument of the integrand to a float:
integrand = lambda U: dxdu_u(float(U)) * mp.besselj(n,U)
In general this is prone to numerical errors (mpmath uses its high-precision variables on purpose!) so proceed with caution. In this specific case it might be OK, because the interpolation is actually done in double precision. Still, best check the results.
A possible alternative might be to avoid mpmath and use the weights argument to scipy.integrate.quad, see the docs (scroll down to weights="sin" part)
Another alternative is to stick with mpmath all the way and implement the interpolation yourselves in pure python (this way, mpf objects are probably fine since they should support usual arithmetics). It's likely a simple linear interpolation is enough. If it's not, it's not too big of a deal to code up your own cubic spline interpolator.
The full traceback:
In [443]: f(0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-443-6bfbdbfff9c4> in <module>
----> 1 f(0)
<ipython-input-440-7ebeff3611f6> in f(n)
2 integrand = lambda U: dxdu_u(U) * mp.besselj(n,U)
3 bjz = lambda nth: mp.besseljzero(n, nth)
----> 4 return mp.quadosc(integrand, [0,mp.inf], zeros=bjz)
5
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in quadosc(ctx, f, interval, omega, period, zeros)
998 # raise ValueError("zeros do not appear to be correctly indexed")
999 n = 1
-> 1000 s = ctx.quadgl(f, [a, zeros(n)])
1001 def term(k):
1002 return ctx.quadgl(f, [zeros(k), zeros(k+1)])
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in quadgl(ctx, *args, **kwargs)
807 """
808 kwargs['method'] = 'gauss-legendre'
--> 809 return ctx.quad(*args, **kwargs)
810
811 def quadosc(ctx, f, interval, omega=None, period=None, zeros=None):
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in quad(ctx, f, *points, **kwargs)
740 ctx.prec += 20
741 if dim == 1:
--> 742 v, err = rule.summation(f, points[0], prec, epsilon, m, verbose)
743 elif dim == 2:
744 v, err = rule.summation(lambda x: \
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in summation(self, f, points, prec, epsilon, max_degree, verbose)
230 print("Integrating from %s to %s (degree %s of %s)" % \
231 (ctx.nstr(a), ctx.nstr(b), degree, max_degree))
--> 232 results.append(self.sum_next(f, nodes, degree, prec, results, verbose))
233 if degree > 1:
234 err = self.estimate_error(results, prec, epsilon)
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in sum_next(self, f, nodes, degree, prec, previous, verbose)
252 case the quadrature rule is able to reuse them.
253 """
--> 254 return self.ctx.fdot((w, f(x)) for (x,w) in nodes)
255
256
/usr/local/lib/python3.6/dist-packages/mpmath/ctx_mp_python.py in fdot(ctx, A, B, conjugate)
942 hasattr_ = hasattr
943 types = (ctx.mpf, ctx.mpc)
--> 944 for a, b in A:
945 if type(a) not in types: a = ctx.convert(a)
946 if type(b) not in types: b = ctx.convert(b)
/usr/local/lib/python3.6/dist-packages/mpmath/calculus/quadrature.py in <genexpr>(.0)
252 case the quadrature rule is able to reuse them.
253 """
--> 254 return self.ctx.fdot((w, f(x)) for (x,w) in nodes)
255
256
<ipython-input-440-7ebeff3611f6> in <lambda>(U)
1 def f(n):
----> 2 integrand = lambda U: dxdu_u(U) * mp.besselj(n,U)
3 bjz = lambda nth: mp.besseljzero(n, nth)
4 return mp.quadosc(integrand, [0,mp.inf], zeros=bjz)
5
at this point it starts using the scipy interpolation code
/usr/local/lib/python3.6/dist-packages/scipy/interpolate/fitpack2.py in __call__(self, x, nu, ext)
310 except KeyError:
311 raise ValueError("Unknown extrapolation mode %s." % ext)
--> 312 return fitpack.splev(x, self._eval_args, der=nu, ext=ext)
313
314 def get_knots(self):
/usr/local/lib/python3.6/dist-packages/scipy/interpolate/fitpack.py in splev(x, tck, der, ext)
366 return tck(x, der, extrapolate=extrapolate)
367 else:
--> 368 return _impl.splev(x, tck, der, ext)
369
370
/usr/local/lib/python3.6/dist-packages/scipy/interpolate/_fitpack_impl.py in splev(x, tck, der, ext)
596 shape = x.shape
597 x = atleast_1d(x).ravel()
--> 598 y, ier = _fitpack._spl_(x, der, t, c, k, ext)
599
600 if ier == 10:
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
_fitpack._spl_ probably is compiled code (for speed). It can't take the mpmath objects directly; it has to pass their values as C compatible doubles.
To illustrate the problem, make a numpy array of mpmath objects:
In [444]: one,two = mp.mpmathify(1), mp.mpmathify(2)
In [445]: arr = np.array([one,two])
In [446]: arr
Out[446]: array([mpf('1.0'), mpf('2.0')], dtype=object)
In [447]: arr.astype(float) # default 'unsafe' casting
Out[447]: array([1., 2.])
In [448]: arr.astype(float, casting='safe')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-448-4860036bcca8> in <module>
----> 1 arr.astype(float, casting='safe')
TypeError: Cannot cast array from dtype('O') to dtype('float64') according to the rule 'safe'
With integrand = lambda U: dxdu_u(float(U)) * mp.besselj(n,U),
In [453]: f(0) # a minute or so later
Out[453]: mpf('0.61060303588231069')
I am trying to calculate the solution to the following equation: 0 = WB-S for B, while setting upper and lower bounds for the results. The matrices have the following shape:
W is mxn
B is zxn
S is mxz
I have tried using the scipy.optimize.lsq_linear function of scipy. However, I run into the following error:
b must have at most 1 dimension.
In this case, b is S on my equation.
df_ret.shape
(2414, 97)
df_matrix.shape
(2414, 336)
df_bd.shape
(97,)
lb = 2,5*df_bd
up = -2.5*df_bd
res = lsq_linear(df_matrix, df_ret, bounds = (lb,up))
--------------------------------------------------------------------------- ValueError Traceback (most recent call
last) in
----> 1 res = lsq_linear(df_matrix, df_ret, bounds = (lb,up))
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize_lsq\lsq_linear.py
in lsq_linear(A, b, bounds, method, tol, lsq_solver, lsmr_tol,
max_iter, verbose)
261 b = np.atleast_1d(b)
262 if b.ndim != 1:
--> 263 raise ValueError("b must have at most 1 dimension.")
264
265 if b.size != m:
ValueError: b must have at most 1 dimension.
I am a newbie to numpy. Today when I use it to work with linear regression, it shows as below:
KeyError Traceback (most recent call
last)
~/anaconda3/lib/python3.6/site-packages/autograd/numpy/numpy_extra.py
in new_array_node(value, tapes)
84 try:
---> 85 return array_dtype_mappings[value.dtype](value, tapes)
86 except KeyError:
KeyError: dtype('int64')
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call
last)
<ipython-input-4-aebe8f7987b0> in <module>()
24 return cost/float(np.size(y))
25
---> 26 weight_h, cost_h = gradient_descent(least_squares, alpha,
max_its, w)
27
28 # a)
<ipython-input-2-1b74c4f818f4> in gradient_descent(g, alpha, max_its,
w)
12 for k in range(max_its):
13 # evaluate the gradient
---> 14 grad_eval = gradient(w)
15
16 # take gradient descent step
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
gradfun(*args, **kwargs)
19 #attach_name_and_doc(fun, argnum, 'Gradient')
20 def gradfun(*args,**kwargs):
---> 21 return
backward_pass(*forward_pass(fun,args,kwargs,argnum))
22 return gradfun
23
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
forward_pass(fun, args, kwargs, argnum)
57 tape = CalculationTape()
58 arg_wrt = args[argnum]
---> 59 start_node = new_node(safe_type(getval(arg_wrt)),
[tape])
60 args = list(args)
61 args[argnum] = merge_tapes(start_node, arg_wrt)
~/anaconda3/lib/python3.6/site-packages/autograd/core.py in
new_node(value, tapes)
185 def new_node(value, tapes=[]):
186 try:
--> 187 return Node.type_mappings[type(value)](value, tapes)
188 except KeyError:
189 return NoDerivativeNode(value, tapes)
~/anaconda3/lib/python3.6/site-packages/autograd/numpy/numpy_extra.py
in new_array_node(value, tapes)
85 return array_dtype_mappings[value.dtype](value, tapes)
86 except KeyError:
---> 87 raise TypeError("Can't differentiate wrt numpy arrays
of dtype {0}".format(value.dtype))
88 Node.type_mappings[anp.ndarray] = new_array_node
89
TypeError: Can't differentiate wrt numpy arrays of dtype int64
I really have no idea about what is happened. I guess it might be related to the structure of array in numpy. Or did I forget to download any packages? Below is my original codes.
# import statements
datapath = 'datasets/'
from autograd import numpy as np
# import automatic differentiator to compute gradient module
from autograd import grad
# gradient descent function
def gradient_descent(g,alpha,max_its,w):
# compute gradient module using autograd
gradient = grad(g)
# run the gradient descent loop
weight_history = [w] # weight history container
cost_history = [g(w)] # cost function history container
for k in range(max_its):
# evaluate the gradient
grad_eval = gradient(w)
# take gradient descent step
w = w - alpha*grad_eval
# record weight and cost
weight_history.append(w)
cost_history.append(g(w))
return weight_history,cost_history
# load in dataset
csvname = datapath + 'kleibers_law_data.csv'
data = np.loadtxt(csvname,delimiter=',')
# get input and output of dataset
x = data[:-1,:]
y = data[-1:,:]
x = np.log(x)
y = np.log(y)
#Data Initiation
alpha = 0.01
max_its = 1000
w = np.array([0,0])
#linear model
def model(x, w):
a = w[0] + np.dot(x.T, w[1:])
return a.T
def least_squares(w):
cost = np.sum((model(x,w)-y)**2)
return cost/float(np.size(y))
weight_h, cost_h = gradient_descent(least_squares, alpha, max_its, w)
# a)
k = np.linspace(-5.5, 7.5, 250)
y = weight_h[max_its][0] + k*weight_h[max_its][1]
plt.figure()
plt.plot(x, y, label='Linear Line', color='g')
plt.xlabel('log of mass')
plt.ylabel('log of metabolic rate')
plt.title("Answer Of a")
plt.legend()
plt.show()
# b)
w0 = weight_h[max_its][0]
w1 = weight_h[max_its][1]
print("Nonlinear relationship between the body mass x and the metabolic
rate y is " /
+ str(w0) + " + " + "log(xp)" + str(w1) + " = " + "log(yp)")
# c)
x2 = np.log(10)
Kj = np.exp(w0 + w1*x2)*1000/4.18
print("It needs " + str(Kj) + " calories")
Could someone help me to figure it out? Thanks a lot.
Here's the important parts of your error:
---> 14 grad_eval = gradient(w)
...
Type Error: Can't differentiate wrt numpy arrays of dtype int64
Your gradient function is saying it doesn't like to differentiate arrays of ints, which makes some sense, since it probably wants more precision than an int can give. You probably need them to be doubles or floats. For a simple solution to this, I believe you can just change your initializer from:
w = np.array([0,0])
which is going to automatically cast those 0s as ints, to:
w = np.array([0.0,0.0])
Those decimals after the 0 will let it know you want floats. There's other ways to go about telling it what kind of array you want (https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.array.html), but this is a simple way.
ValueError
Traceback (most recent call last)
<ipython-input-129-810db8fa03c3> in <module>()
20 # TODO:<your code here>
21
---> 22 w=np.subtract(w,(compute_grad(X_expanded[ind, :], y, w)))
23
24
shape = (6, 1)
weight_gradients = np.empty(shape,)
for k in range(len(w)):
sum_gradient = 0
#print(sum_gradient)
for i in range (len(X)):
linear_model_output=X[i,0]*w[0]+X[i,1]*w[1]+X[i,2]*w[2]+X[i,3]*w[3]+X[i,4]*w[4]+X[i,5]*w[5]
exp_lmo = np.exp(linear_model_output)
y_i=y[i]
add_to_grad = -X[i][k]*1*(y_i*exp_lmo-exp_lmo+y_i)/(exp_lmo+1)
sum_gradient = sum_gradient + add_to_grad
sum_gradient = sum_gradient/len(y)
weight_gradients[k] = sum_gradient ############ERROR LINE
at weight_gradients[k] = sum_gradient I receive the error.
My guess is that its due to a frustratingly stupid lack of knowledge of the language. Unfortunately, I have previously used code exactly like this in my program and it hasn't thrown up an error, really just making me rather confused.
I'm using this code as part of a project to simulate orbits of 3 bodies. I am using the Euler method in this part but i am getting some errors that i am not sure how to get rid of.
import vpython as v
from numpy import arange, linspace, array
import numpy as np
np.seterr(divide='ignore')
Earth = array([-1.47E+11, 0, 0, -30290])
Mars = array([-2.07E+11, 0, 0, -26500])
def derivatives(Body1, Body2, t):
Mass_earth = 5.97E+24
Mass_mars = 6.42E+23
Mass_sun = 1.99E+30
Abs_Radius_earth = 1.47E+11
Abs_Radius_mars = 2.07E+11
Radius_earth = array([Body1[0], Body1[1]])
Radius_mars = array([Body2[0], Body2[1]])
ve = 1
vm = 1
G = 6.67408E-11
dvedt = (G*Mass_sun*Radius_earth)/(np.abs(Abs_Radius_earth))**3 + np.divide((G*Mass_mars*(Radius_mars-Radius_earth)), (np.abs(Radius_mars-Radius_earth))**3)
dvmdt = (G*Mass_sun*Radius_mars)/(np.abs(Abs_Radius_mars))**3 + np.divide((G*ME*(Radius_earth-Radius_mars)), (np.abs(Radius_earth-Radius_mars))**3)
dvedt = v.vector(float(dvedt[0]), float(dvedt[1]), 0)
return(ve, vm, dvedt, dvmdt)
Evol = array([Earth[2], Earth[3]])
Epol = array([Earth[0], Earth[1]])
Mvol = array([Mars[2], Mars[3]])
Mpol = array([Mars[0], Mars[1]])
E = array([Epol, Evol])
M = array([Mpol, Mvol])
for t in arange(1, 11, 1):
Evol += (t * derivatives(E, M, 1)[2])
E = array([Epol, Evol])
print(E, M)
Here is the error message:
C:\Program Files\Anaconda3\lib\site-packages\ipykernel\__main__.py:20: RuntimeWarning: invalid value encountered in true_divide
C:\Program Files\Anaconda3\lib\site-packages\ipykernel\__main__.py:21: RuntimeWarning: invalid value encountered in true_divide
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-25-ef24509c2299> in <module>()
31
32 for t in arange(1, 11, 1):
---> 33 Evol += (t * derivatives(E, M, 1)[2])
34 E = array([Epol, Evol])
35 print(E, M)
<ipython-input-25-ef24509c2299> in derivatives(Body1, Body2, t)
20 dvedt = (G*Mass_sun*Radius_earth)/(np.abs(Abs_Radius_earth))**3 + np.divide((G*Mass_mars*(Radius_mars-Radius_earth)), (np.abs(Radius_mars-Radius_earth))**3)
21 dvmdt = (G*Mass_sun*Radius_mars)/(np.abs(Abs_Radius_mars))**3 + np.divide((G*ME*(Radius_earth-Radius_mars)), (np.abs(Radius_earth-Radius_mars))**3)
---> 22 dvedt = v.vector(float(dvedt[0]), float(dvedt[1]), 0)
23 return(ve, vm, dvedt, dvmdt)
24
TypeError: only length-1 arrays can be converted to Python scalars
This is probably a simple fix but I just cant seem to get it to work. I'm mainly focusing on all the earth parts, if i can get that working i will apply it to the other planets (mars).
Any help will be super helpful.