How to plot a cumulative sum (running total) of a turtles-own variable in Netlogo? - simulation

I can plot the sum of worms per animal using the code below (visualized in Figure 1).
plot sum [worm-number] of animals
Figure 1.
I want my graph to be cumulative however like Figure 2 but I don't know how to code this. Previous examples use older syntax which does not work in NetLogo 6.2.0 and does not show how to plot the data.
Figure 2.

You only have to use a global variable which will keep track of the new worms, and to which you will refer for plotting.
As we do not have a full example of your code, I am just going to write something that plausibly mimics what you should do:
breed [animals animal]
globals [
cumulative-worms
]
; **************************
; The rest of your code here
; **************************
to get-infected ; The procedure executed by animals when they get new worms.
let new-worms (1 + random 5)
set worm-number (worm-number + new-worms)
set cumulative-worms (cumulative-worms + new-worms)
end
At this point you can just create a plot where you will use plot cumulative-worms.

Related

Iterating a function in MATLAB

Incredibly simple question, but I think I'm unable to come up with the correct terminology to google search it.
If I have a snippet of code that relies on three independent variables:
code(x,y,z)
That produces two values, i.e.:
output1, output2
How do I go about iterating like so (pseudocode):
for x
for y
for z
code(x,y,z)
end
end
end
And have data I can parse to generate 3D graphs such as
surf(x,y,output1)
A naive solution I came up with was just to create a bin of n length and then iterating one variable n times to come up with a 2D graph, i.e:
x_axis = zeros(1,25)
for m = 1:25
xm = x + 1
x_axis(m) = xm
code(x,y,z)
Even a referral to some documentation would be extremely helpful.
Thanks!
Brute force approach:
for x=[1:50]
for y=[1:50]
for z=[1:50]
result(y,x,z)=code(x,y,z);
end
end
end
More paradigmatic approach (in MATLAB) is to meshgrid it, and pump those in.
[XX,YY,ZZ]=meshgrid([1:50],[1:50],[1:50]);
result=code(XX,YY,ZZ);

Merge close centroids

suppose I want to cluster data with 3 features. After running a clustering algorithm as a result I got the following 6 cluster centers:
246.844727524039 250.149069392025 94.0942587475951
121.988259016632 162.247917376091 100.033277638728
246.832071340390 250.114555535282 94.0640197467370
247.069762690783 237.380529249185 176.069941183101
57.6643682370364 59.8647220036974 44.0150398556124
253.248727658092 254.655572229735 71.2948414962619
Anyone can notice that centers 1 and 3 are very close to each other. Is there a way to merge them as one center? I'm looking something like a function that returns the merged cluster centers. Any ideas?
I suggest the following approach:
define a threshold which represents the minimal possible Eucledean distance between two centroids.
iterate over all the possible pairs, and if some their distance is lower then the thresohld - unite them.
You can perform this calculation as follows:
[m,n] = size(centers);
threshold = 1; %defines a threshold
centroidsToMerge = [];
for i=1:m
for j=(i+1):m
if norm(centers(i,:)-centers(j,:))<threshold
centroidsToMerge = [centroidsToMerge;[i,j]];
end
end
end
results for threshold=1:
centroidsToMerge = [1, 3]
results for threshold=30:
centroidsToMerge = [ 1,3 ; 1,6 ; 3,6 ]
If you have the Statistics and Machine Learning Toolbox you can use MATLAB's pdist function in order to calculate all the pair distanced automatically, and thus maybe avoiding the for loops. Unfortunately, I don't have this toolbox at the moment so I wasn't able to use it. However, I still believe that it is a good way to start with.

Use of Logical Masks

I working on a homework assignment and trying to solve the following problem:
Here is the code I have so far:
function [ ] = Activity45( Time )
%Homework 4
%Activity 4.5
t=Time;
A=[0:0.1:t];
B=3*exp(-(A/3)).*sin(pi.*A);
C=(B>0);
plot(A,B(C))
end
So I am trying to use a mask to extract the data from Matrix B in Matrix C. But I do not know how to match the data up between A and C, to then use plot().
Any help?
With plot(A(C), B(C)) you don't get the intended curve because you don't have values equal to zero. Instead the last two points to the left and right are connected with a line above 0. The right way would be to set the value on the Y-Axis to zero.
B(~C)=0;
plot(A,B);
For future formulas, it might be a good idea to use variable names matching the variable names in your formulas.

Vector operations on object-array with 'colon' indexing [MATLAB]

In my Matlab code I have an object-array of 'masses' which are an object of a class which describes the mass, speed, accerleration etc.
To speed up the simulation I want to reduce the usage of for-loops with using more vector operations. One of the operations is to get the distance of the current mass to all others.
I would like to solve it like that:
%position is a vector with x and y values e.g. [1 2]
%repeat the current mass as many times as there are other masses to compare with
currentMassPosition = repmat(obj(currentMass).position, length(obj), 2);
distanceCurrentMassToOthersArray = obj(:).position - currentMassPosition;
I cannot use the colon-indexing operation on the object array. Currently i use a for-loop where I iterate through every single object. Do you have any tips to optimise that without using a for loop?
I hope my question was clear enough, otherwise I will optimise it ;).
I used this code to reproduce your problem. For future questions please try to include such examples into your question:
classdef A
properties
position
end
methods
function obj=A()
obj.position=1;
end
end
end
.
%example code to reproduce
x(1)=A
x(2)=A
x(3)=A
%line which causes the problem
x(:).position-3
To understand why this is not working, take a look at the output of x(:).position, just type it into the console. You get multiple ans values, indicating a comma separated list of multiple values. If you use [x(:).position] instead, you get an array of doubles. The correct code is:
[x(:).position]-3

Extract parts of a big matrix and allocate them in new variables with loop function

I am a total beginner in MATLAB and I hope to find some help here. I have some model prediction results for 80 individuals alltogether in one large matrix. I need to extract the data for each individual from the big matrix, assign them in a new variable/matrix, do some extra calculations and then plot certain information as needed.
To do so, I am trying to write a script with a loop function but in a complicated, or maybe more accurately: in a primitive way!
Simplified Example:
My matrix is called: All_Indi_Data .... its dimension is: 600 rows x 21 columns
%Column 1: grouping variable (e.g., code or ID with values 1,2,3,4,5, etc.);
%Column 2: independent var.;
%Column 3: t;
%Column 4: OBS;
%Column 5: PRED;
i= length (All_Indi_Data);
%% First Indi.
q=1; % indicating the ID of the indi for which I want to extract the data
j=1; % variable added to insure writing start from the first row
for r=1:i
if All_Indi_Data (r,1)==q
Indi_1 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
%% Second Indi.
q=q+1
j=1
for r=1:i
if All_Indi_Data (r,1)==q
Indi_2 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
.
.
.
1) My first question is: can I allocate these data in new variables (Indi_1, Indi_2, ect.) in a more simple way with or without the loop function?!!! I would appreciate your help a lot.
2) Is there any code or any way to plot these selected parts (according to the grouping variable, e.g. data for Indi_1) from the previously mentioned big matrix without wasting a lot of time and space (wto recopying the core part of the code again and again) for the script, and using the loop function?! in other words, I would like to detect - with loop function & the grouping variable- which values are of interest and then to plot them (e.g. data in colum 3 with data from column 4 for each individual, starting from the first to the last)?!
I hope that I described my problem clearly and hope to hear something from the expert guys :) ...
Thanks a lot in advance ..
Try the following code:
for idx=1:80
pos=find(All_Indi_Data(:,1)==idx);
eval(['Indi_' num2str(idx) '=All_Indi_Data(pos,:);']);
end
What I do is: in each iteration, I search for a value of the ID, indicated in the variable idx. Note that I do not use ´i´ as the name of a variable, because Matlab uses it and ´j´ and the imaginary unit for complex numbers and that could cause problems.
Then, using find I search for the position (or positions) of All_Indi_Data in which I can find the information of that individual. Now I have in the variable ´pos´ the indexes of the rows in which there is information for the individual of interest.
Finally, using eval I extract the data for each individual into a variable. Note that eval combined with a loop makes it easy to create lots of variables. I indicate the rows I want to extract with ´pos´ and, as I want all the columns, I use just ´:´ (you could use ´1:21´ too).
With another similar loop you can plot the information you want. For example:
for idx=1:80
eval(['x=Indi_' num2str(idx) ';']);
% Now I have in X the information for this individual
%Plot the columns of x I want
plot(x(:, 3), x(:,4));
pause; %stay here until a press a key
end