I have a Predator-Prey Model:
dR/dt = λR - aRF
dF/dt = -μF + bRF
Where λ and μ are growth rates of rabbits (R) and foxes (F) respectively, treated in isolation. a is the predation rate of foxes on rabbits, and b is the growth rate of popluation of foxes through predation on rabbits.
So far I have the following code, but I've really confused myself, where is my model going wrong?
function PredPrey
lambda = 0.1; % Lambda = Reproduction rate of rabbits
mu = 0.15; % Mu = Death rate of foxes
a = 0.005; % a = Rate of rabbits caught per fox
b = 0.002; % b = foxes born per rabbit caught
N = 3;
R = zeros(1,N);
F = zeros(1,N);
R(1) = 100;
F(1) = 10;
for n = 2:N
R(n) = R(n-1) + lambda*R(n-1) - a*R(n-1)*F(n-1);
F(n) = F(n-1) - mu*F(n-1) + b*a*R(n-1)*F(n-1);
end
Xvals = 1:N;
plot(Xvals,R,'b',Xvals,F,'r')
end
Basically you have a system of odes which needs tools like ode45 to handle. I suggest you to take a look at
https://www.mathworks.com/help/matlab/ref/ode45.html
Moreover, you may use
function f = predPrey(t,x)
f = zeros(2,1);
% x(1) represents the number of rabbits
% x(2) represents the number of foxes
% Model's parameters
a = 0.01
b = 0.02
c = 0.03
d = 0.04
f(1) = a*x(1) - b*x(1)*x(2);
f(2) = -c*x(2) + d*x(1)*x(2);
end
with the following command:
[time,valx] = ode45(#(t,x) predPrey(t,x),[0,5],[200,100]);
to solve the system for time t = 0 to t = 5 with the initial population of 200 rabbits and 100 foxes.
Note that
rabbit = valx(:,1)
fox = valx(:,2)
Related
I'm having serious problems in a simple example of fem assembly.
I just want to assemble the Mass matrix without any coefficient. The geometry is simple:
conn=[1, 2, 3];
p = [0 0; 1 0; 0 1];
I made it like this so that the physical element will be equal to the reference one.
my basis functions:
phi_1 = #(eta) 1 - eta(1) - eta(2);
phi_2 = #(eta) eta(1);
phi_3 = #(eta) eta(2);
phi = {phi_1, phi_2, phi_3};
Jacobian matrix:
J = #(x,y) [x(2) - x(1), x(3) - x(1);
y(2) - y(1), y(3) - y(1)];
The rest of the code:
M = zeros(np,np);
for K = 1:size(conn,1)
l2g = conn(K,:); %local to global mapping
x = p(l2g,1); %node x-coordinate
y = p(l2g,2); %node y-coordinate
jac = J(x,y);
loc_M = localM(jac, phi);
M(l2g, l2g) = M(l2g, l2g) + loc_M; %add element masses to M
end
localM:
function loc_M = localM(J,phi)
d_J = det(J);
loc_M = zeros(3,3);
for i = 1:3
for j = 1:3
loc_M(i,j) = d_J * quadrature(phi{i}, phi{j});
end
end
end
quadrature:
function value = quadrature(phi_i, phi_j)
p = [1/3, 1/3;
0.6, 0.2;
0.2, 0.6;
0.2, 0.2];
w = [-27/96, 25/96, 25/96, 25/96];
res = 0;
for i = 1:size(p,1)
res = res + phi_i(p(i,:)) * phi_j(p(i,:)) * w(i);
end
value = res;
end
For the simple entry (1,1) I obtain 0.833, while computing the integral by hand or on wolfram alpha I get 0.166 (2 times the result of the quadrature).
I tried with different points and weights for quadrature, but really I do not know what I am doing wrong.
I am having a system of 6 ode.
What i am trying to manage, is to solve it, for several different values of one of its parameters, parameter 'p', using a for loop at the integration.
I have managed to do it using ode45, however,
using a non-built-in integrator, it seems i am making a mistake and I don't get back the same values, or graphs.
I would appreciate any feedback on my code on what went wrong
Using ODE45
p = -100:+1:350;
time = 0:.05:3;
initial = [0 0 0 0 0 0];
x = NaN(length(time),length(initial),length(p));
for i=1:length(p)
[t,x(:,:,i)] = ode45(#ode,time,initial,[],p(i));
end
figure(1)
plot3(squeeze(x(:,1,:)),squeeze(x(:,2,:)),squeeze(x(:,3,:)))
function dx = ode(~,x,p)
bla bla
end
Using the non-built-in integrator
figure
hold all
for p = -100:+1:350
inicond = [0 0 0 0 0 0];
dt = 0.01;
time = 0:dt:10;
[y] = integrator(#ode,inicond,time,dt,p);
x1 = y(:,1);
x2 = y(:,2);
x3 = y(:,3);
figure(1)
plot3(x1,x2,x3)
axis equal
legend('-DynamicLegend')
end
function [y] = integrator(ode,inicond,time,dt,p)
y = NaN(length(time),length(inicond));
y(1,:) = inicond;
for j=2:length(time)
k1 = dt*ode(y(j-1,:),p);
k2 = dt*ode(y(j-1,:)+k1/2,p);
k3 = dt*ode(y(j-1,:)+k2/2,p);
k4 = dt*ode(y(j-1,:)+k3,p);
y(j,:) = y(j-1,:) + k1/6+k2/3+k3/3+k4/6;
end
end
function [dydt] = ode(y,p)
bla bla
end
Using the non-built-in function to solve Van der Pol for multiple 'epsilon'values: This works., while for the previous it doesnt..
figure
hold all
for epsilon = 0:.2:5
inicond = [0.2 0.8];
dt = 0.1;%timestep for integration
time = 0:dt:100;
[x] = integrator(#VanDerPol,inicond,time,dt,epsilon);
xdot = x(:,2);
x = x(:,1);
figure(1)
plot(x,xdot,'DisplayName',sprintf('epsilon = %1.0f',epsilon))
figure(2)
plot3(time, x,xdot)
axis equal
legend('-DynamicLegend')
end
function [x] = integrator(VanDerPol,inicond,time,dt,epsilon)
x = NaN(length(time),length(inicond));
x(1,:) = inicond;
%%% ACTUAL CALL OF INTEGRATOR %%%%%%%%%%%%%%
for j=2:length(time)
k1 = dt*feval(VanDerPol,x(j-1,:),epsilon);
k2 = dt*feval(VanDerPol,x(j-1,:)+k1/2,epsilon);
k3 = dt*feval(VanDerPol,x(j-1,:)+k2/2,epsilon);
k4 = dt*feval(VanDerPol,x(j-1,:)+k3,epsilon);
x(j,:) = x(j-1,:) + k1/6+k2/3+k3/3+k4/6;
end
end
function [dxdt] = VanDerPol(x,epsilon)
dxdt=NaN(1,2);
dxdt(1,1) = x(:,2);
dxdt(1,2) = epsilon*(1 - x(:,1)^2)*x(:,2) - x(:,1);
end
I am afraid that with the second way, the values of all the repetitions might not be stored correctly and for this reason the values of the occurring matrices after integration, hardly vary one from another
I am interested in modifying the code below to find the parameters I_1, I_2, I_3 and I_4, to be used in another code. Every time I run the code, it throws up
In an assignment A(:) = B, the number of elements in A and B must be the same
on this line " mult(mult == 0) = B;".
I have spent eternity figuring out what the problem could be. Here is the code:
%%% Some Parameters %%
delta = 0.6; % Blanked subframe ratio
B = [0 0.2 0.4 0.6 0.8 1]; %Power splitting factor
k = 2.3; %Macro BS density
f = k*5; %Small cell density
j = 300; %users density
P_m = 46; %Macro BS transmission power
P_s = 23; %SC transmit power
Zm = -15;
Zs = -15;
iter = 30; %Iteration run
h = 500; %Simulation area
hu = 0.8*h; %users simulation area
Vm = round(k*h); %Macro BS average no in h
Vs = round(f*h); %SC average no in h
Vu = round(j*hu); %%users average no in hu
Pm = 10^(P_m/10)/1000*10^(Zm/10);
Ps = 10^(P_s/10)/1000*10^(Zs/10);
for i = iter;
%% XY coodinates for Macrocell, small cells and users.
Xm = sqrt(h)*(rand(Vm,1)-0.5);
Ym = sqrt(h)*(rand(Vm,1)-0.5);
Xs = sqrt(h)*(rand(Vs,1)-0.5);
Ys = sqrt(h)*(rand(Vs,1)-0.5);
Xu = sqrt(hu)*(rand(Vu,1)-0.5);
Yu = sqrt(hu)*(rand(Vu,1)-0.5);
%Total coordinates for MBS and small cells
Total_Coord = [Xs Ys ones(size(Xs)) Xm Ym 2*ones(size(Xm))];
%Distance between BSs and users
[Xsm_mat, Xu_mat] = meshgrid(Total_Coord(:,1),Xu);
[Ysm_mat, Yu_mat] = meshgrid(Total_Coord(:,2),Yu);
Distance = sqrt((Xsm_mat-Xu_mat).^2 + (Ysm_mat-Yu_mat).^2);
%% To determine serving BS for each user
[D_m,idx_m] = min(Distance(:,(length(Xs)+1):end),[],2);
idx_m = idx_m + length(Xs);
[D_s,idx_s] = min(Distance(:,1:length(Xs)),[],2);
%% Power received by users from each BS
Psm_mat = [Ps*ones(length(Xu),length(Xs))
Pm*ones(length(Xu),length(Xm))]; % Transmit power of MBS and small cells
Pr_n = Psm_mat.*exprnd(1,size(Psm_mat))./(Distance*1e3).^4;
mult = binornd(1,delta,1,length(Xm)); % Full transmission power of each
interfering MBS for delta
mult(mult == 0) = B; % Reduced transmission power for (1-delta)
Pr = Pr_n.*[ones(length(Xu),length(Xs)) repmat(mult,length(Xu),1)];%
Interference from each BS
%% Power received by each user from serving BSs
Prm = Pr(sub2ind(size(Pr),(1:length(idx_m))',idx_m));
Prs = Pr(sub2ind(size(Pr),(1:length(idx_s))',idx_s));
P_m_n = Pr_n(sub2ind(size(Pr_n),(1:length(idx_m))',idx_m));
%% Total interference for each UE
I_T = sum(Pr,2) - Prm - Prs;
I_1 = P_m_n./(Prs + I_T);
I_2 = Prs./(P_m_n + I_T);
I_3 = B*I_1;
I_4 = Prs./(B*P_m_n + I_T);
end
The error appeared on this line "mult(mult == 0) = B;".
I know it to be assignment problem which requires equality in both the left and right dimensions. Suggestions for correction will be appreciated.
Your vector mult has length Vm (number of macro BS?). Assigning to mult(mult==0) will assign to a subset of this vector (those that have a value equal to zero). What you are assigning is your variable B which you define as B = [0 0.2 0.4 0.6 0.8 1], i.e., it is a length-6 vector. The assignment fails unless mult has exactly 6 zeros.
I highly doubt that this is what you want. It looks like you are trying to assign the same value ("Reduced transmission power"). Then your B should be scalar though.
Since we have no idea what you are trying to do (and your code is not exactly an MCVE), we can only guess.
I'm trying to solve a system of ordinary differential equations from y_1 to y_2, say
G' = D
D' = f(y,G,D)
with the initial conditions
G(y_1) = 0
D(y_1) = 0
My problem is that I do not know y_1 and y_2, to counter for this I of course need two additional equations which is
F_1(y_1,y_2,G(y_2)) = 0
F_2(y_1,y_2,G(y_2)) = 0
So far I have tried to implement it using fsolve (i guess the new name is fzero) to find the zeros, then from the functions F_1 and F_2 i call the ode45 to solve from y_1 to y_2 in order to calculate the functions. However it does not work and I can not seem to find any mistakes. Therefore i looked for new methods/ideas and I found the method bvp4c, but I'm not sure whether i can use it in my case. Does anyone have experience with bvp4c and know whether and how I should use it, or do you have other ideas?
Any help is appreciated.
Code for reference:
function [Fval,sol,t,G] = EntrepreneurialFinanceNondiversifiableRisk
global sigma rf tau b epsilon gamma theta1 theta2 alpha ya K I taug mu eta...
omega
sigma=0.2236; rf=0.03; tau=0.1129; b=0.85; epsilon=0.2; gamma=2;
theta1 = -0.704; alpha = 0.6; theta2=1.704; ya=0.1438; K=27; I = 10;
taug = 0.1; mu = 0.04; eta = 0.4; omega = 0.1;
tau = 0;
option = optimset('Display','iter');
sol = fsolve(#f,[0.1483,2.8],option);
Fval = f(sol);
[t,G] = solvediff(sol(1),sol(2));
function F = f(x)
yd = x(1);
yu = x(2);
global rf tau b theta1 alpha theta2 K I taug
Vstar =# (y) (1-tau+tau*(1-theta1-(1-alpha)*(1-tau)* theta1/tau)^...
(1/theta1))*y/rf;
VstarPrime = (1-tau+tau*(1-theta1-(1-alpha)*(1-tau)...
*theta1/tau)^(1/theta1))*1/rf;
qbar =#(yd,yu) (yd^theta1-yd^theta2)/(yu^theta2*yd^theta1-yu^theta1*...
yd^theta2);
qunderbar =# (yd,yu) (yu^theta2-yu^theta1)/(yu^theta2*yd^theta1-...
yu^theta1*yd^theta2);
A =# (y) (1-tau)*(y/rf);
V = #(y,yd) A(y) + (tau * b)/rf * (1 - (y/yd)^(theta2)) - (1-alpha)*A(yd)*...
(y/yd)^(theta2);
F0 =# (yd,yu) b/rf-(b/rf-alpha*A(yd))*qunderbar(yd,yu)/(1-qbar(yd,yu));
[t,G] = solvediff(yd,yu);
F = zeros(2,1);
F(1) = Vstar(yu)-F0(yd,yu)-K-taug*(Vstar(yu)-K-I)-G(end,2);
F(2) = (1-taug)*VstarPrime-G(end,2);
function [t,G] = solvediff(yd,yu)
[t,G] = ode45(#diff,[yd,yu],[0,0]);
Assuming the domain of definition is big enough and you have good initial values, a Newton implementation with divided differences for the construction of the Jacobian looks like this:
h=1e-5
for k=1:10 do
Fval = F(yd, yu)
dFdyd = (F(yd+h, yu)-F(yd-h, yu))/(2*h)
dFdyu = (F(yd, yu+h)-F(yd, yu-h))/(2*h)
dF = [ dFdyd dFdyu ]
ynext = [ yd; yu ] - dF^(-1)*Fval;
yd = ynext(1); yu = ynext(2);
end
I asked a question a few days before but I guess it was a little too complicated and I don't expect to get any answer.
My problem is that I need to use ANN for classification. I've read that much better cost function (or loss function as some books specify) is the cross-entropy, that is J(w) = -1/m * sum_i( yi*ln(hw(xi)) + (1-yi)*ln(1 - hw(xi)) ); i indicates the no. data from training matrix X. I tried to apply it in MATLAB but I find it really difficult. There are couple things I don't know:
should I sum each outputs given all training data (i = 1, ... N, where N is number of inputs for training)
is the gradient calculated correctly
is the numerical gradient (gradAapprox) calculated correctly.
I have following MATLAB codes. I realise I may ask for trivial thing but anyway I hope someone can give me some clues how to find the problem. I suspect the problem is to calculate gradients.
Many thanks.
Main script:
close all
clear all
L = #(x) (1 + exp(-x)).^(-1);
NN = #(x,theta) theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')];
% theta = [10 -30 -30];
x = [0 0; 0 1; 1 0; 1 1];
y = [0.9 0.1 0.1 0.1]';
theta0 = 2*rand(9,1)-1;
options = optimset('gradObj','on','Display','iter');
thetaVec = fminunc(#costFunction,theta0,options,x,y);
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
NN(x,theta)'
Cost function:
function [jVal,gradVal,gradApprox] = costFunction(thetaVec,x,y)
persistent index;
% 1 x x
% 1 x x
% 1 x x
% x = 1 x x
% 1 x x
% 1 x x
% 1 x x
m = size(x,1);
if isempty(index) || index > size(x,1)
index = 1;
end
L = #(x) (1 + exp(-x)).^(-1);
NN = #(x,theta) theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')];
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
Dew = cell(2,1);
DewApprox = cell(2,1);
% Forward propagation
a0 = x(index,:)';
z1 = theta{1}*[1;a0];
a1 = L(z1);
z2 = theta{2}*[1;a1];
a2 = L(z2);
% Back propagation
d2 = 1/m*(a2 - y(index))*L(z2)*(1-L(z2));
Dew{2} = [1;a1]*d2;
d1 = [1;a1].*(1 - [1;a1]).*theta{2}'*d2;
Dew{1} = [1;a0]*d1(2:end)';
% NNRes = NN(x,theta)';
% jVal = -1/m*sum(NNRes-y)*NNRes*(1-NNRes);
jVal = -1/m*(a2 - y(index))*a2*(1-a2);
gradVal = [Dew{1}(:);Dew{2}(:)];
gradApprox = CalcGradApprox(0.0001);
index = index + 1;
function output = CalcGradApprox(epsilon)
output = zeros(size(gradVal));
for n=1:length(thetaVec)
thetaVecMin = thetaVec;
thetaVecMax = thetaVec;
thetaVecMin(n) = thetaVec(n) - epsilon;
thetaVecMax(n) = thetaVec(n) + epsilon;
thetaMin = cell(2,1);
thetaMax = cell(2,1);
thetaMin{1} = reshape(thetaVecMin(1:6),[2 3]);
thetaMin{2} = reshape(thetaVecMin(7:9),[1 3]);
thetaMax{1} = reshape(thetaVecMax(1:6),[2 3]);
thetaMax{2} = reshape(thetaVecMax(7:9),[1 3]);
a2min = NN(x(index,:),thetaMin)';
a2max = NN(x(index,:),thetaMax)';
jValMin = -1/m*(a2min-y(index))*a2min*(1-a2min);
jValMax = -1/m*(a2max-y(index))*a2max*(1-a2max);
output(n) = (jValMax - jValMin)/2/epsilon;
end
end
end
EDIT:
Below I present the correct version of my costFunction for those who may be interested.
function [jVal,gradVal,gradApprox] = costFunction(thetaVec,x,y)
m = size(x,1);
L = #(x) (1 + exp(-x)).^(-1);
NN = #(x,theta) L(theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')]);
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
Delta = cell(2,1);
Delta{1} = zeros(size(theta{1}));
Delta{2} = zeros(size(theta{2}));
D = cell(2,1);
D{1} = zeros(size(theta{1}));
D{2} = zeros(size(theta{2}));
jVal = 0;
for in = 1:size(x,1)
% Forward propagation
a1 = [1;x(in,:)']; % added bias to a0
z2 = theta{1}*a1;
a2 = [1;L(z2)]; % added bias to a1
z3 = theta{2}*a2;
a3 = L(z3);
% Back propagation
d3 = a3 - y(in);
d2 = theta{2}'*d3.*a2.*(1 - a2);
Delta{2} = Delta{2} + d3*a2';
Delta{1} = Delta{1} + d2(2:end)*a1';
jVal = jVal + sum( y(in)*log(a3) + (1-y(in))*log(1-a3) );
end
D{1} = 1/m*Delta{1};
D{2} = 1/m*Delta{2};
jVal = -1/m*jVal;
gradVal = [D{1}(:);D{2}(:)];
gradApprox = CalcGradApprox(x(in,:),0.0001);
% Nested function to calculate gradApprox
function output = CalcGradApprox(x,epsilon)
output = zeros(size(thetaVec));
for n=1:length(thetaVec)
thetaVecMin = thetaVec;
thetaVecMax = thetaVec;
thetaVecMin(n) = thetaVec(n) - epsilon;
thetaVecMax(n) = thetaVec(n) + epsilon;
thetaMin = cell(2,1);
thetaMax = cell(2,1);
thetaMin{1} = reshape(thetaVecMin(1:6),[2 3]);
thetaMin{2} = reshape(thetaVecMin(7:9),[1 3]);
thetaMax{1} = reshape(thetaVecMax(1:6),[2 3]);
thetaMax{2} = reshape(thetaVecMax(7:9),[1 3]);
a3min = NN(x,thetaMin)';
a3max = NN(x,thetaMax)';
jValMin = 0;
jValMax = 0;
for inn=1:size(x,1)
jValMin = jValMin + sum( y(inn)*log(a3min) + (1-y(inn))*log(1-a3min) );
jValMax = jValMax + sum( y(inn)*log(a3max) + (1-y(inn))*log(1-a3max) );
end
jValMin = 1/m*jValMin;
jValMax = 1/m*jValMax;
output(n) = (jValMax - jValMin)/2/epsilon;
end
end
end
I've only had a quick eyeball over your code. Here are some pointers.
Q1
should I sum each outputs given all training data (i = 1, ... N, where
N is number of inputs for training)
If you are talking in relation to the cost function, it is normal to sum and normalise by the number of training examples in order to provide comparison between.
I can't tell from the code whether you have a vectorised implementation which will change the answer. Note that the sum function will only sum up a single dimension at a time - meaning if you have a (M by N) array, sum will result in a 1 by N array.
The cost function should have a scalar output.
Q2
is the gradient calculated correctly
The gradient is not calculated correctly - specifically the deltas look wrong. Try following Andrew Ng's notes [PDF] they are very good.
Q3
is the numerical gradient (gradAapprox) calculated correctly.
This line looks a bit suspect. Does this make more sense?
output(n) = (jValMax - jValMin)/(2*epsilon);
EDIT: I actually can't make heads or tails of your gradient approximation. You should only use forward propagation and small tweaks in the parameters to compute the gradient. Good luck!