Positional argument missing error in scipy optimize - scipy

I wanted to get a maximum estimate for the following function in mu and sigma using scipy where s is defined as the sample
s = np.random.normal(mu, sigma, 100)
def f(mu, sigma):
x = norm.pdf(s,mu,sigma)
x = np.prod(x)
x = np.log(x)
return x
I've tried
x0 = [0,1]
bounds = [(-5,5),(-5,5)]
print(optimize.minimize(f, x0, method='SLSQP', bounds=bounds))
but keep getting the error:
f() missing 1 required positional argument: 'sigma'
I'm not sure what's going on here

You need to pass the arguments to f as a vector:
def f(z):
mu, sigma = z
x = norm.pdf(s,mu,sigma)
x = np.prod(x)
x = np.log(x)
return x

Related

SIR model using fsolve and Euler 3BDF

Hi i've been asked to solve SIR model using fsolve command in MATLAB, and Euler 3 point backward. I'm really confused on how to proceed, please help. This is what i have so far. I created a function for 3BDF scheme but i'm not sure how to proceed with fsolve and solve the system of nonlinear ODEs. The SIR model is shown as and 3BDF scheme is formulated as
clc
clear all
gamma=1/7;
beta=1/3;
ode1= #(R,S,I) -(beta*I*S)/(S+I+R);
ode2= #(R,S,I) (beta*I*S)/(S+I+R)-I*gamma;
ode3= #(I) gamma*I;
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
R0=0;
I0=10;
S0=8e6;
odes={ode1;ode2;ode3}
fun = #root2d;
x0 = [0,0];
x = fsolve(fun,x0)
function [xs,yb] = ThreePointBDF(f,x0, xmax, h, y0)
% This function should return the numerical solution of y at x = xmax.
% (It should not return the entire time history of y.)
% TO BE COMPLETED
xs=x0:h:xmax;
y=zeros(1,length(xs));
y(1)=y0;
yb(1)=y0+f(x0,y0)*h;
for i=1:length(xs)-1
R =R0;
y1(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - R, y1(i-1,:)+2*h*F(i,:))
S = S0;
y2(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - S, y2(i-1,:)+2*h*F(i,:))
I= I0;
y3(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - I, y3(i-1,:)+2*h*F(i,:))
end
end
You have an implicit equation
y(i+1) - 2*h/3*f(t(i+1),y(i+1)) = G = (4*y(i) - y(i-1))/3
where the right-side term G is constant in the call to fsolve, that is, during the solution of the implicit step equation.
Note that this is for the vector valued system y'(t)=f(t,y(t)) where
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
To solve this write
G = (4*y(i,:) - y(i-1,:))/3
y(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - G, y(i-1,:)+2*h*F(i,:))
where a midpoint step is used to get an order 2 approximation as initial guess, F(i,:)=f(t(i),y(i,:)). Add solver options for error tolerances as necessary, you want the error in the implicit equation smaller than the truncation error O(h^3) of the step. One can also keep only a short array of function values, then one has to be careful for the correspondence of the position in the short array to the time index.
Using all that and a reference solution by a higher order standard solver produces the following error graphs for the components
where one can see that the first order error of the constant first step results in a first order global error, while with a second order error in the first step using the Euler method results in a clear second order global error.
Implement the method in general terms
from scipy.optimize import fsolve
def BDF2(f,t,y0,y1):
N, h = len(t)-1, t[1]-t[0];
y = (N+1)*[np.asarray(y0)];
y[1] = y1;
for i in range(1,N):
t1, G = t[i+1], (4*y[i]-y[i-1])/3
y[i+1] = fsolve(lambda u: u-2*h/3*f(t1,u)-G, y[i-1]+2*h*f(t[i],y[i]), xtol=1e-3*h**3)
return np.vstack(y)
Set up the model to be solved
gamma=1/7;
beta=1/3;
print beta, gamma
y0 = np.array([8e6, 10, 0])
P = sum(y0); y0 = y0/P
def f(t,y): S,I,R = y; trns = beta*S*I/(S+I+R); recv=gamma*I; return np.array([-trns, trns-recv, recv])
Compute a reference solution and method solutions for the two initialization variants
from scipy.integrate import odeint
tg = np.linspace(0,120,25*128)
yg = odeint(f,y0,tg,atol=1e-12, rtol=1e-14, tfirst=True)
M = 16; # 8,4
t = tg[::M];
h = t[1]-t[0];
y1 = BDF2(f,t,y0,y0)
e1 = y1-yg[::M]
y2 = BDF2(f,t,y0,y0+h*f(0,y0))
e2 = y2-yg[::M]
Plot the errors, computation as above, but embedded in the plot commands, could be separated in principle by first computing a list of solutions
fig,ax = plt.subplots(3,2,figsize=(12,6))
for M in [16, 8, 4]:
t = tg[::M];
h = t[1]-t[0];
y = BDF2(f,t,y0,y0)
e = (y-yg[::M])
for k in range(3): ax[k,0].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
y = BDF2(f,t,y0,y0+h*f(0,y0))
e = (y-yg[::M])
for k in range(3): ax[k,1].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
for k in range(3):
for j in range(2): ax[k,j].set_ylabel(["$e_S$","$e_I$","$e_R$"][k]); ax[k,j].legend(); ax[k,j].grid()
ax[0,0].set_title("Errors: first step constant");
ax[0,1].set_title("Errors: first step Euler")

Using a function that has another function as parameter:

I want to integrate x^2 from 2 to 4 with the trapezoidal integration method. For this, I defined a function trap that takes 4 arguments:
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(feval(fn, a) + feval(fn, b) + 2*sum(feval(fn,x)));
and a function f
function y= f(x)
y=x^2
end
Now, by executing trap(f,2,4,0.1), I get the following error:
Not enough input arguments.
Error in f (line 2)
y=x^2
What is the origin of that error?
You have to call trap using the function handle #f, not f.
trap(#f,2,4,0.1)
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(fn(a) + fn(b) + 2*sum(fn(x)));
end
function y= f(x)
y = x.^2;
end
which gives, as expected,
ans =
18.67
Also you needed element-wise multiplication in f(x) to compute y = x.^2.
And feval is not necessary. You can directly call fn(a) to evaluate the function.

Numerical Integral in MatLab using integral command

I am trying to compute the value of this integral using Matlab
Here the other parameters have been defined or computed in the earlier part of the program as follows
N = 2;
sigma = [0.01 0.1];
l = [15];
meu = 4*pi*10^(-7);
f = logspace ( 1, 6, 500);
w=2*pi.*f;
for j = 1 : length(f)
q2(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(2));
q1(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(1));
C2(j)= 1/(q2(j));
C1(j)= (q1(j)*C2(j) + tanh(q1(j)*l))/(q1(j)*(1+q1(j)*C2(j)*tanh(q1(j)*l)));
Z(j) = sqrt(-1)*2*pi*f(j)*C1(j);
Apprho(j) = meu*(1/(2*pi*f(j))*(abs(Z(j))^2));
Phi(j) = atan(imag(Z(j))/real(Z(j)));
end
%integration part
c1=w./(2*pi);
rho0=1;
fun = #(x) log(Apprho(x)/rho0)/(x.^2-w^2);
c2= integral(fun,0,Inf);
phin=pi/4-c1.*c2;
I am getting an error like this
could anyone help and tell me where i am going wrong.thanks in advance
Define Apprho in a separate *.m function file, instead of storing it in an array:
function [ result ] = Apprho(x)
%
% Calculate f and Z based on input argument x
%
% ...
%
meu = 4*pi*10^(-7);
result = meu*(1/(2*pi*f)*(abs(Z)^2));
end
How you calculate f and Z is up to you.
MATLAB's integral works by calling the function (in this case, Apprho) repeatedly at many different x values. The x values called by integral don't necessarily correspond to the 1: length(f) values used in your original code, which is why you received errors.

System of linear equations in matlab with 2 ways but can't get same results

I'm trying to solve a system of 4 linear equations in Matlab with two ways
First:
A = [5,2,3,4;2,6,1,9;6,3,1,5;2,4,7,9];
B = [7;11;5;3];
X = [A\B]';
With the result:
X = 0.5556 17.4667 4.4889 -11.0444
Second:
[x,y,z,w] = solve('5*x+2*y+3*z+4*w-7','2*x+6*y+z+9*w-11','6*x+3*y+z+5*w-5','2*x+4*y+7*z+9*w-3')
With result:
X = -497/45, Y=5/9, Z=262/15, W=202/45
As you can see the results on the second way aren't in the correct order. I googled the equations and found that the first order is the correct one.
Has anyone an idea of what's going on and how to solve it?
Thanx in advance!
Specify the order of the unknowns when you call solve:
>> syms x y z w %// define symbolic variables (unknowns)
>> [x0,y0,z0,w0] = solve('5*x+2*y+3*z+4*w-7',...
'2*x+6*y+z+9*w-11',...
'6*x+3*y+z+5*w-5',...
'2*x+4*y+7*z+9*w-3',...
x, y, z, w)
x0 =
5/9
y0 =
262/15
z0 =
202/45
w0 =
-497/45
By the way, once you have defined x, y, z, w as symbolic variables you can avoid the quotation marks:
>> [x0,y0,z0,w0] = solve(5*x+2*y+3*z+4*w-7,...
2*x+6*y+z+9*w-11,...
6*x+3*y+z+5*w-5,...
2*x+4*y+7*z+9*w-3,...
x, y, z, w)
x0 =
5/9
y0 =
262/15
z0 =
202/45
w0 =
-497/45

Evaluating a symbolic summation in MATLAB

Following code throws out an error.
syms z positive;
syms n;
syms m;
N = 10;
Ms = 10;
Es = 1;
pd = 0.9;
pd_dash = 1-pd;
pf = 0.1;
pf_dash = 1-pf;
pr = 0.1;
qr = 1-pr;
p = 0.005
pi = pf_dash*p;
pb = pd_dash*p;
qi = 1-pi;
qb = 1-pb;
sm = symsum( z^((n+1)*Es), n, 0, N-1 );
temp_sum = symsum(z^((n+m+1)*Es)*qr^(n+m)*pr, m, 0, N-1);
z=1; %assume a value of z
x = eval(sm); %works fine
y = eval(temp_sum);
% Error:The expression to the left of the equals sign is not a valid target for an assignment.
Please suggest a way to resolve this.
The problem that I suspect is: the temp_sum comes out to be in piecewise(...) which eval is not capable of evaluating.
What you actually did:
Create a symbolic expression
Create a variable z which is unused
Call a undocumented function sym/eval
I assume you wanted to:
Create a symbolic expression
Substitute z with 1: temp_sum=subs(temp_sum,z,1)
get the result. Here I don't know what you really have because I don't know which variables are symbolic unknowns and which constants. Try simplify(temp_sum). If you substituted all unknowns it should return a number.