ValueError while using scipy.integrate to calculate value of a function - python

I am trying to evaluate a function for different values of a variable n, I created a np.linspace for this vairiable and plugged it into a function Q:
def Q(z_i, z_min,f_gamma, mDM, sigma_v,n, with_ucmh):
dQdz_z = lambda z : dQdz(f_gamma, mDM, sigma_v, z,n, with_ucmh)
integrand = lambda z: ((1/((1+z)*H_z(z)))* (dQdz_z(z)) * np.exp(-tau(z)))
second_part = const.C*const.B*integrate.romberg(integrand,z_min,z_i)
return second_part
z_i = 2.0e6
z_min = 5.0e4
sigma_v = 3.0e-27
f_gamma = 1.
mDM = 10.
with_ucmh = True
n = np.linspace(1.,1.3,100)
mu = Q(z_i, z_min,f_gamma, mDM, sigma_v,n, with_ucmh)
I get ValueError: setting an array element with a sequence that point me to the line where I use the integrate.romberg method of scipy, but I don't understand how come I get here this sort of error..

Related

How do I define p in a poly function to return R^2

I am trying to calcualte R^2 from a polynom function I have made.
def polynom(x, p):
r = np.array(x)
s = np.array(x)
for i in range(1, p):
r = r*s
jepps = np.column_stack((x, r))
return jepps
def lollispoly(x,y):
x = polynom(x, p),
b_hatt = np.array(inv(x.T#x)#x.T#y)
hattematrise = x#inv(x.T#x)#x.T
y_hatt = hattematrise#y
TSS = np.sum((y - np.mean(y))**2)
ESS = np.sum((y_hatt - np.mean(y))**2)
RSS = (TSS - ESS)
R2 = ESS/TSS
R2_tilpasset = 1-((RSS/x-p-1))/(TSS/(x-1))
print(R2_tilpasset)
This is the code I have used so far, my first question is how am I gonna define p in here so my polynom function knows what input to get and then my lollispoly function takes that and returns a R^2 value? Is there also a cleaner way to write this or is it okey?
Regards
I have tried to change the p with different numbers, or set p = 2 for example in either function and then I get the error ValueError: Length of values (50) does not match length of index (1). So I am trying to understand how to fix this.

Python type error: 'numpy.ndarray' object is not callable--how to fix?

This is my code. When I run it, I get an issue with the python error: 'numpy.ndarray' object is not callable. I think that the issue is because I call V_function_prime in the functions for find_k, find_w, but I don't know how else to do this
import numpy as np
import copy as cp
import scipy as sp
from scipy import optimize as optimize
from scipy.interpolate import PchipInterpolator as pchip
#primatives
#beta R <1 means that the
beta = .8
R = 1.02
phi = .8
#define a grid
size = 100
w_grid = np.linspace(0.001,5,num = size)
#set up functions
def utility(c):
return np.log(c)
def u_prime(c):
return 1/c
def production(k):
return k**(1/3)
def production_prime(k):
return 1/3*k**(-2/3)
def production_2prime(k):
return (-2/9)*k**(-5/3)
def inv_prod_prime(x):
return (3*x)**(-2/3)
#define functions to get threshold value wbar and optimal policy b, k
def find_w(V_function_prime, k_star, capital_evolution):
w_bar = (1-phi)*k_star + 1/(beta*R*V_function_prime(capital_evolution))
return w_bar
#find_w(phi, R)
#takes in value w and current guess of v_prime and returns optimal bond choice (b)
def find_b(b, w, v_function_prime, k_star):
foc = u_prime(w - b - k_star) - beta*R*v_function_prime(production(k_star) + R*b)
return foc
#takes in value w and current guess of v_prime and returns optimal capital choice (k)
def find_k(k, w, v_function_prime):
foc = (1-phi)*u_prime(w - (1-phi)*k) - beta*v_function_prime(production(k) - R*phi*k)(production_prime(k)-R*phi)
return foc
#value function iteration function
def vfi(R, phi, beta, size, tol):
#use known info ab optimum--add explanation here
k_star = inv_prod_prime(R)
capital_evolution = production(k_star)-R*phi*k_star
#inital guess of value function is utility
VV = utility(w_grid)
#V_prime = u_prime(w_grid)
#params of loop
err = tol + 1
epsilon = 1e-5
while err > tol:
V_previous = cp.copy(VV)
V_function = pchip(w_grid, VV)
#V_w is value function evaluated at w_grid
V_w = V_function(w_grid)
V_function_prime = V_function.derivative(1)
V_prime_w = V_function_prime(w_grid)
w_bar = find_w(V_function_prime, k_star, capital_evolution)
k_prime = np.zeros(size)
b_prime = np.zeros(size)
for i in range(size):
#solve unconstrained region of state-space
if w_grid[i] >= w_bar:
k_choice = k_star
#limits set based on natural bounds for borrowing given in the SP
b_choice = optimize.brentq(find_b, (-phi*k_star), (w_grid[i] - k_star - epsilon), args = (w_grid[i], V_function_prime, k_star))
#solve constrained region of state-space
else:
bound = w_grid[i]/(1-phi) - epsilon
k_choice = optimize.brentq(find_k, (epsilon), (bound), args = (w_grid[i], V_function_prime))
b_choice = -phi*k_choice
#add in new guesses for optimal b, k, and update value function vector
k_prime[i] = k_choice
b_prime[i] = b_choice
VV[i] = utility(w_grid[i] - b_prime[i] - k_prime[i]) + beta*V_function(production(k_prime[i]) + R*b_prime[i])
V_function_update = pchip(w_grid, VV)
err = np.max(np.abs(V_function_update(w_grid) - V_w))
print(err)
V_function = V_function_update
return V_function, b_prime, k_prime
vfi(R, phi, beta, size = 100, tol = 1e-3)
I know this happens bc I have a function V_function_prime that I am passing into another function, but I'm not quite sure how to solve this
#takes in value w and current guess of v_prime and returns optimal capital choice (k)
def find_k(k, w, v_function_prime):
foc = (1-phi)*u_prime(w - (1-phi)*k) - beta*v_function_prime(production(k) - R*phi*k)(production_prime(k)-R*phi) ## Two times repeated function call
return foc
Check above block. v_function_prime(**args) will return an array. You are calling it again with some other arguments.
You might need to remove one of them.

How can I solve this matrix ODE using python?

I would like to numerically compute this ODE from time 0 -> T :
ODE equation where all of the sub-matrix are numerically given in a paper. Here are all of the variables :
import numpy as np
T = 1
eta = np.diag([2e-7, 2e-7])
R = [[0.33, 3.95],
[-2.52, 10.23]]
R = np.array(R)
gamma = 2e-5
GAMMA = 100
S_bar = [54.23, 27.45]
cov = [[0.47, 0.2],
[0.2, 0.14]]
cov = np.array(cov)
shape = cov.shape
Q = 0.5*np.block([[gamma*cov, R],
[np.transpose(R), np.zeros(shape)]])
Y = np.block([[np.zeros(shape), np.zeros(shape)],
[gamma*cov, R]])
U = np.block([[-linalg.inv(eta), np.zeros(shape)],
[np.zeros(shape), 2*gamma*cov]])
P_T = np.block([[-GAMMA*np.ones(shape), np.zeros(shape)],
[np.zeros(shape), np.zeros(shape)]])
Now I define de function f so that P' = f(t, P) :
n = len(P_T)
def f(t, X):
X = X.reshape([n, n])
return (Q + np.transpose(Y)#X + X#Y + X#U#X).reshape(-1)
Now my goal is to numerically solve this ODE, im trying to figure out the right function solve so that if I integrate the ODE from T to 0, then using the final value I get, I integrate back from 0 to T, the two matrices I get are actually (nearly) the same. Here is my solve function :
from scipy import integrate
def solve(interval, initial_value):
return integrate.solve_ivp(f, interval, initial_value, method="LSODA", max_step=1e-4)
Now I can test wether the computation is right :
solv = solve([T, 0], P_T.reshape(-1))
y = np.array(solv.y)
solv2 = solve([0, T], y[:, -1])
y2 = np.array(solv2.y)
# print(solv.status)
# print(solv2.status)
# this lines shows the diffenrence between the initial matrix at T and the final matrix computed at T
# the smallest is the value, the better is the computation
print(sum(sum(abs((P_T - y2[:, -1].reshape([n, n]))))))
My issue is : No matter what "solve" function im using (using different methods, different step sizes, testing all the parameters...) I always get either errors or a very bad convergence (the difference between the two matrices is too high).
Knowing that according to the paper where this ODE comes from ( (23) in https://arxiv.org/pdf/2103.13773v4.pdf) there exists a solution, how can I numerically compute it?

Writing lambda in MATLAB

I am trying to convert this code into MATLAB but I am not sure how to do the subscripts (Y[i] = Y[i-1]) as well as the func and f_exact variables
heres the code:
def Forward_Euler(y0,t0,T,dt,f):
t = np.arange(t0,T+dt,dt)
Y = np.zeros(len(t))
Y[0] = y0
for i in range(1,len(t)):
Y[i] = Y[i-1]+dt*f(Y[i-1], t[i-1])
return Y, t
func = lambda y,t: y-t
f_exact = lambda t: t+1-1/2*np.exp(t)
You can use anonymous functions in matlab:
func = #(y,t)(y - t)
f_exact = #(t)(t + 1 - exp(t)/2) % it works with any matrix t as well
And you can use for matrices as well (they should keep matrix operation rules). For example, in func function, as there is a minus in the form of function, the dimension of y and t must be the same.

Numpy Array Index Issue

I am trying to implement Newtons_method for multivariable scenario. I am trying to output multiple iterations, but am getting an indexing error
import symengine
from symengine import var
import numpy as np
vars =var("x y")
sol=[]
def jacob():
f = ['2*x+y**2-8','x**2-y**2+x*y-3'] # Define function
J = symengine.zeros(len(f),len(vars)) # Initialise Jacobian matrix
# Fill Jacobian matrix with entries
for i, fi in enumerate(f):
for j, s in enumerate(vars):
J[i,j] = symengine.diff(fi, s)
sol.append(J[i,j])
a = np.array([sol[0],sol[1],sol[2],sol[3]])
return a
def eval1(func,val1,val2):
z=[]
for b in func:
b=str(b)
x=val1
y=val2
z.append(eval(b))
return np.array([[z[0],z[1]],[z[2],z[3]]])
def newtons_method(f, df, x0, e):
q=10
while q > e:
q=q-1
x0 = np.absolute(x0 - (np.array([[f(x0[0][0])],[df(x0[1][0])]]))/(eval1(jacob(),x0[0][0],x0[1][0])))
print('Root is at: ', x0)
print('f(x) at root is: ', f(x0))
def f(x):
return 2*x+y**2-8
def df(x):
return x**2-y**2+x*y-3
x0s = np.array([[1],[1]])
for x0 in x0s:
newtons_method(f, df, x0, 1)
I am getting error: invalid index to scalar variable.
Where I set the value to x0 under the newtons_method function, any ideas as to what is going wrong?
When calling newtons_method function, an element of [[1],[1]] i.e. [1] is being passed as parameter x0. Inside the function, x0[0][0] has been used which gives invalid index to scalar variable error.
You should pass x0s as parameter if you want to use both the elements.
x0s = np.array([[1],[1]])
newtons_method(f, df, x0s, 1)

Categories

Resources