Error in Runge-Kutta 4 solution - netlogo

I'm trying to solve a system of ODE's using the Runge-Kutta 4 Method (RK4). I am code testing the algorithm below, and finding that the solution does not equal the analytical solution (and the error is large). Below I have included my code testing for the I.V.P. dy/dt = f(t,y). I have tried finding errors in this code, but cannot spot them. Any help is much appreciated.
globals
[t
dt
growth-rate]
turtles-own [ state ]
to setup
clear-all
create-turtles 1 [ set state 1]
set dt .01
set growth-rate .05
reset-ticks
end
to go
tick
set t t + dt
ask turtles [ set state rk4 t state dt ] ;integrate the diff eq.
end
;differential equation to be integrated using rk4
to-report df [ t_n state_n ] ; i.v.p. y(dot) = f(t_n, y_n)
report growth-rate * (state_n)
end
;;;;;;;function calls
to-report rk4 [ t_n state_n h ]
let k1 df t_n state_n
let k2 df (t_n + 0.5 * h) (state_n + ((h / 2) * k1))
let k3 df (t_n + 0.5 * h) (state_n + ((h / 2) * k2))
let k4 df (t_n + h) (state_n + k3)
let state_n+1 state_n + ((h / 6) * (k1 + (2 * k2) + (2 * k3) + k4))
report state_n+1
end
Integrating this function to t=100, I have an error of > 7 (numerical solution ~156, and analytical solution ~148)

I think the implementation is basically fine, but your interpretation of how many ticks you need may be out. If you change your go statement to the below code, it works
to go
ask turtles [ set state rk4 t state dt ] ;integrate the diff eq.
set t t + dt
tick
if ticks = steps / dt [ stop ]
end
You should ahve set t t + dt after the state update, because state_n+1 is calculated from state_n at t_n and having the time update first makes it based on t_n+1. In practice, however, that doesn't fix the problem (or make any real difference to the values). But think about getting from t_0 to t_1. You need to go through 1/dt ticks.
So I think when you explain the problem with your example of integrating to t=100, you are actually integrating to t=101. But I am not sure because you didn't provide that bit of your model.

Related

Rank Selection in GA?

I have implemented Roulette wheel selection in GA.
TotalFitness=sum(Fitness);
ProbSelection=zeros(PopLength,1);
CumProb=zeros(PopLength,1);
for i=1:PopLength
ProbSelection(i)=Fitness(i)/TotalFitness;
if i==1
CumProb(i)=ProbSelection(i);
else
CumProb(i)=CumProb(i-1)+ProbSelection(i);
end
end
SelectInd=rand(PopLength,1);
for i=1:PopLength
flag=0;
for j=1:PopLength
if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
flag=1;
break;
end
end
if(flag==0)
SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
end
end
Now i was trying to implement rank selection in GA. I learned that:
Rank selection first ranks the population and then every chromosome receives fitness from this ranking.
The worst will have fitness 1, second worst 2 etc. and the best will have fitness N (number of chromosomes in population).
I saw these link1 and link2 and what i understood is that:
First i will sort the Fitness value of the Population.
Then if the Population number is 10 then i will give the probability of selection to the Population like 0.1,0.2,0.3,...,1.0 .
Then i will calculate cumulative Fitness like roulette wheel.
And the next steps is same as roulette wheel.
My Implementation:
NewFitness=sort(Fitness);
NewPop=round(rand(PopLength,IndLength));
for i=1:PopLength
for j=1:PopLength
if(NewFitness(i)==Fitness(j))
NewPop(i,1:IndLength)=CurrentPop(j,1:IndLength);
break;
end
end
end
CurrentPop=NewPop;
ProbSelection=zeros(PopLength,1);
CumProb=zeros(PopLength,1);
for i=1:PopLength
ProbSelection(i)=i/PopLength;
if i==1
CumProb(i)=ProbSelection(i);
else
CumProb(i)=CumProb(i-1)+ProbSelection(i);
end
end
SelectInd=rand(PopLength,1);
for i=1:PopLength
flag=0;
for j=1:PopLength
if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
flag=1;
break;
end
end
if(flag==0)
SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
end
end
Am i understanding the algo wrong?? If it is then can anyone give me any idea how to modify my roulette wheel to rank selection??
If the population has N individuals, the best individual gets rank N and the worst 1 then
TotalFitness = sum(Fitness);
should be changed with:
TotalFitness = (N + 1) * N / 2;
(probably TotalFitness isn't anymore the right name for the variable, but let it go)
(N + 1) * N / 2 is just the sum of the ranks:
1 + 2 + ... + N = (N + 1) * N / 2
The probability of selection should be changed from:
ProbSelection(i) = Fitness(i) / TotalFitness;
to
ProbSelection(i) = i / TotalFitness;
Here using the rank instead of the fitness and assuming that the first individual of the population is the worst and the last is the best (sorted population).
Hence the complexity of the rank selection algorithm is dominated by the complexity of the sorting (O(N * log(N)).
You can see that the probability of selection for the worst individual is:
1 / ((N + 1) * N / 2) = 2 / ((N + 1) * N)
and the probability for the best individual is:
N / (((N + 1) * N / 2)) = 2 * (N + 1)
This is a linear rank selection: the ranks are in a linear progression. There are other schemes of rank selection (e.g. exponential).

MATLAB: How can I create autocorrelated data?

I'm looking to create a vector of autocorrelated data points in MATLAB, with the lag 1 higher than lag 2, and so on.
If I look at the lag 1 data pairs (1, 2), (3, 4), (5, 6), ..., then the correlation is relatively higher, but then at lag 2 it's reduced.
I found a way to do this in R
x <- filter(rnorm(1000), filter=rep(1,3), circular=TRUE)
However, I'm not sure how to do the same thing in MATLAB. Ideally I'd like to be able to fine tune exactly how autocorrelated the data is.
Math:
A group of standard models for autocorrelation in stationary time series are so called "auto regressive model" eg. an autoregressive model with 1 term is known as an AR(1) and is:
y_t = a + b*y_{t-1} + e_t
AR(1) sounds simplistic, but it turns it's a quite powerful tooll. Eg. an AR(p) with p autoregressive terms is actually an AR(1) on a p dimensional vector. (Check Wikipedia page.) Note also b=1, gives a non-stationary random walk.
A more intuitive way to write what's going on (in stationary case with |b| < 1) is define u = a / (1 - b) (turns out u is unconditional mean of AR(1)), then with some algebra:
y_t - u = b * ( y_{t-1} - u) + e_t
That is, the difference from the unconditional mean u gets hit with some decay term b and then a shock term e_t gets added. (you want -1<b<1 for stationarity)
Code:
Since e_t denotes the shock term, this is super easy to simulate. Eg. to simulate an AR(1):
a = 0; b = .4; sigma = 1; T = 1000;
y0 = a / (1 - b); %eg initialize to unconditional mean of stationary time series
y = zeros(T,1);
y(1) = a + b * y0 + randn() * sigma;
for t = 2:T
y(t) = a + b * y(t-1) + randn() * sigma;
end
This code isn't mean to be fast, but illustrative. An AR(1) model implies a certain type of correlation structure, but adding AR or MA terms, you can fit some pretty funky stuff. (MA is moving average model)
Can test sample autocorrelation with autocorr(y). For reference, the bible on time series mathematics is Hamilton's book Time Series Analysis.

Summing breeds netlogo

I am fairly new to netlogo and modelling as a whole., but I am really enjoying it. Right now I am stuck…In my model I have breeds, each breed has “x” turtles, every turtle has a “x” variables, until this point I managed to get the value of each turtle and the value of all of them together but I cannot figure it out how to get the value of all the breeds together. I hope you can help me I really appreciate it.
This is the way i got the sum of the variables of the turtles.
show sum [(electricidad) + (transporte) + (prevención) + (atención)] of CM / Comercio.
In order to obtain the sum of breeds i tried
show sum [(SPA) + (SAT) + (SS) + (TT) + (CM) / 5]
The letters inside the "()" are the names of the breeds.
Do all of the breeds have the same variables? In that case you can use:
sum [electricidad + transporte + prevención + atención] of turtles
If there are different variables for different breeds, you can use something like:
(sum [x + y + z] of SPA) + (sum [a + b + c] of SAT) + ...
The parentheses in the preceding line aren't needed, but they might make the code easier to read. The parentheses in your example aren't needed and should probably be left out, unless you have a special reason to include them.

how to solve special equations in octave

I've got a porblem. I'm new in Octave need to solve these equations in this format:
-397.95 = min(k1*rate + k2);
776.37 = max(k1*rate + k2);
where rate is my row vector at size 10000. All I need is octave function which can deal with roots which are in other function (in my max and min). I know, that this question is a little bit mathematical, but I can't get the right easy function for solving this...
Thank you for answer
It looks like you need to use an optimization to minimise a cost function which would look like:
function y = f(x)
% k1 is x(1), k2 is x(2)
rate = ...
y = [min(x(1)*rate + x(2))+397.95; max(x(1)*rate+x(2))-776.37]
end
You can then use optimization functions such as fminsearch or other (from the optim package). The idea is to try and minimize your cost function, i.e. get y towards 0. It might be a good idea to use abs in your function to avoid issue with negative numbers.
It's easy to see that the constraints for this problem are:
k1 * rate + k2 >= -397.95
and
k1 * rate + k2 <= 776.37
Since larger values of k1 give a larger variance in the result of this equation, your objective is to maximize k1 subject to these constraints (equivalently minimize -k1).
You can now run this as a simple linear program:
height = size(rate,1);
c = [-1;0];
A = [rate',ones(height,1); rate',ones(height,1)];
b = [-397.95*ones(height,1); 766.37*ones(height,1)];
lb = [0;-Inf];
ub = [Inf; Inf];
ctype = [repmat("L",height,1); repmat("U",height,1)];
k = glpk (c,A,b,lb,ub,ctype)
k1 = k(1);
k2 = k(2);
EDIT : I missed that rate was a row vector. I've transposed it appropriately
Actually since there are only two variables, this can be solved directly. Assuming k1 is positive (No reason not to make k1 positive since flipping the sign doesn't really change the problem since k2 can be shifted appropriately), then we have k1*max(rate) + k2 = 776.37 and k1*min(rate) + k2 = -397.95
So
k1*(max(rate) - min(rate)) = 776.37 - (-397.95)
Then we can solve for k1 as
k1 = (776.37 - (-397.95))/(max(rate) - min(rate))
And then k2 can be found as
k2 = 776.37 - k1 * max(rate)

Coding of Ito Stochastic Process

I am trying to implement a routine in mathematica/matlab for a stochastic process. Any code written here is for mathematica, but if someone can help me with encoding this in matlab (if they're more familiar with that) then that would be fine as well. However, mathematica is the priority if possible.
I will state what I want to get after going over the equations first.
The following is the Ito stochastic Process that I am interested in (where z(t)=[x(t),y(t)]:
with the following quantities:
We also have the following (from now I will type x(t),y(t) as x,y):
where, is the first exit time and
GT(x) is a smooth function of x (please see at the end)
Goal: I want to get Q0 in terms of x and only.
===============================================================================
To find the first exit time maybe the following can be used (courtesy of b.gatessucks). Please note that the following is a mathematica code.
CONSTRAINT FOR EXIT TIME:
const[x_, y_] := And[10^-8 <= y <= 10^-3, 0.9*(Uc) <= a1*x^2/2 - a3*x^4/4 <= 1.1*(Uc)]
x0 = 0.1; (* starting point for x[t] *) y0 = 0.1; (* starting point for y[t] *)
proc = ItoProcess[ {\[DifferentialD]x[t] == y[t] \[DifferentialD]t, \[DifferentialD]y[t] == (-G*y[t] - (a1*x[t] - a3*x[t]^3) - eps*b3b*y[t]^3) \[DifferentialD]t + Sqrt[2*eps*G] \[DifferentialD]w[t]}, {t, x[t], y[t], Boole[const[x[t], y[t]]]}, {{x, y}, {x0, y0}}, {t, 0}, w \[Distributed] WienerProcess[]]
Exit time is found:
SeedRandom[3]
sim = RandomFunction[proc, {0, 1, 0.001}];
First#Select[sim[[2, 1, 1]], #[[4]] == 0 &]
that outputs {t, x[t], y[t], Boole[const[x[t], y[t]]]}
I need to be able to use the above code to find the exit time and then use it in Q0. The above snippet to find exit time produces non zero times for properly chosen .
================================================================================
Numerical Task that needs to be set up to find Q0(x):
--> We start from the integral term in this expression. First find 's for many initial conditions (say 100 for now -- i.e., 100 exit times) starting from inside the domain (maybe by using the snippet already mentioned in this post). Now the integral can be evaluated for each of the 100 exit times as functions of x and .
--> Now, the expectation of the integral in Q0 is a sample average (by Law of Large Numbers) of all the 100 integrals evaluated before. Thus, Q0 can be found and it should only be a function of x and .
================================================================================
My issues:
The code above for the exit time only seems to produce non-zero exit times for appropriately chosen initial conditions. If someone can elucidate as to how to pick the appropriate such that there will be sufficient exit time being produced then that would be appreciative. I really want to keep my constraints as specified above in const[x_, y_], but if there seems to be no hope in finding tractable results then I wouldn't mind relaxing it.
The code below for GT(x) results in singularities -- I received error message from DSolve regarding indeterminate expressions....both b0[xc] and DrhoDy[xc] become indeterminate and so the DSolve gives problems when using the initial condition GT[xc] as it becomes indeterminate as well...any way around this matter would be gladly appreciated.
Finally, I really need someone's help in evaluating the 100 integrals in mathematica efficiently (since the terms are huge) for each of the exit times found previously and taking the expectation. I am not sure as to how to find the exit times properly.
================================================================================
To find GT(x):
b1b = 0.9; b3b = .8; a1b = 0.1; a3b = 0.2; G = (1/0.1^2)*
b1b; a1 = (1/.1^2)*a1b; a3 = (1/.1^2)*a3b; xc = Sqrt[a1/a3]; Uc =
a1*xc^2/2 - a3*xc^4/4; L = (G + Sqrt[G^2 + 4*(-(a1 - 3*a3*xc^2))])/2;
y[x_] := (x *a1 - x^3*a3)/(G + L)
b0[x_] := (y[
x]*(a1*x \[Minus]
a3*x ^3)*(1 \[Minus] (a1 \[Minus] 3*a3*x ^2)) \[Minus]
G*y[x]*(a1 \[Minus] 3*a3*x ^2)) /(y[
x] ^2 + (\[Minus]G*y[x] + a1*x \[Minus] a3*x ^3) ^2)
DrhoDy [x_] :=
Sqrt[y[x]^ 2 /(y[x] ^2 + (\[Minus]G*y[x] + a1*x \[Minus] a3*x ^3) ^2)]
linearequation =
y[x]*GT '[x] + b0[x]*GT[x] == G*DrhoDy [x]^2 *GT[x]^ 3;
GT[x] =
DSolve[{linearequation, GT[xc] == Sqrt[b0[xc]/( G*DrhoDy [xc]^2 )]},
GT, x]
ODE:
that satisfies the Initial Condition:
where,
and