How to identify recurring patterns in time-series data in Matlab - matlab

I am calculating ENSO indices using Matlab and one condition is that I have to find anomalous sea surface temperatures. The condition is that an El Niño event is characterised by sea surface temperatures that are 0.5 degrees above the normalised "0-value" for 5 months. I have gotten as far as to make my monthly time series data logical (i.e. "1" is a monthly data value above 0.5 and "0" is a monthly data value below 0.5), but I wanted to know if there was a command in Matlab that allows me to identify when this value repeats 5 times or more.
As an example code:
Monthly_data=[0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0]
I would ideally need a command that finds when a minimum of five "1"s occur after each other. Does this exist?
If more info is needed please let me know, I am new to matlab so I am not yet sure of the structure and syntax that is valued for asking questions on here.
Thank you!

not sure this is what you need but perhaps gives you some direction.
> x = diff(Monthly_data);
> find(x==-1)-find(x==1)
ans =
5 2 1 7
these are the lengths of the 1 sequences. You may need to pad front and end of the array with 0 to eliminate sequences missing one boundary.
To find the start index of the sequence longer than 5:
> s=find(x==1);
> s(find(x==-1)-s>5)
ans = 18
or
> s(find(x==-1)-s>=5)
ans =
2 18
note that because of the diff lag, these are one more than the array index, or consider it as position for zero based indexing.

Related

Event Multiple Calculator/Generator? - MatLab

This might be an obvious question to some, however I am a beginner coder and would appreciate any links or advice I can get.
I am trying to create a code to generate a matrix with values based on the number of possible occurring events.
I am considering each end-member I have an independent event (this is being applied to a end-member mixing scenario in chemistry). Each of these events can occur 2 different ways (the value can be negative or positive). I am also trying to make this code capable of any number of independent events. I am thinking this matrix will be, ncol = the number of independent events, and nrows = the number of event multiples.
For example: If I have 3 independent events (3 columns in matrix), with 2 possible occurrences each (positive or negative), that means there are 8 event multiples or combinations (8 rows in the matrix).
For each combination (row), I would like to automatically generate the outcomes if I only use "1" to indicate the value is positive and "-1" to indicate the value is negative. The order of the row combinations should not matter.
Unfortunately I am using MatLab R2015a, but I was thinking a similar function to what I'm asking is called "combnk" or "combntns" in MatLab R2016a.
% Beginning of code:
NoIndEvents = 3; % Number of independent events
NoOccur = 2; % Number of occurrences for each ind. event
newmatrix = ones(NoOccur^NoIndEvents,NoIndEvents); % Initialize matrix
% Have no idea how to generate this part...
% My desired output (no hard coding & easily modified for any
% number of columns/ ind. events)
newmatrix =
1 1 1
-1 -1 -1
1 1 -1
1 -1 1
-1 1 1
-1 -1 1
-1 1 -1
1 -1 1
Does anyone know of a function I can use for this? I have a feeling this might be super easy and I just can't wrap my brain around the coding aspect of it...
Thank you in advance!
~Sydney
The issue is that nchoosek, combnk, etc. do not consider ordering of the result so they won't produce enough combinations (i.e [-1 -1 1] is the same as [1 -1 -1]). You could generate all permutations of your input (with each possible value duplicated NoIndEvents times). And then use unique on the first NoIndEvents columns of the result to get all of your permutations.
P = perms(repmat([-1 1], NoIndEvents, 1));
out = unique(P(:,1:NoIndEvents), 'rows')
-1 -1 -1
-1 -1 1
-1 1 -1
-1 1 1
1 -1 -1
1 -1 1
1 1 -1
1 1 1

Find the first index such that all successive elements are zero

I have a vector in matlab
a = [1 8 0 7 0 5 9 0 0 0 0 0 0 0 0]
Here I am interested to FIND the first index (beyond which the value are completely zero) where the zeros occur continuously. In this example I expect the answer to be 8.
find pretty much does this for you:
find(a, 1, 'last') + 1
since find just returns a list of the positions of non-zero characters, all you have to do is ask find to only give you the last such element and then the next element (hence the +1)
One approach that works even if your last entry is non-zero or your first entry is zero or all your entries are zero, covers just about everything.
find(diff([1 a]==0)==1,1,'last')
Note that this finds the location of the last group of zeros.
last_idx = max(find(a~=0)) + 1
however, if your last entry is not a zero you've to be careful...

comparing multiple columns of matrix together

I have a 50x50 matrix named nghlist(i,j) containing 0 and 1 values. 1 means there is a relation between (i,j).
There is another 5x50 matrix named chlist.
I need to check the nghlist matrix and if there is any connection between i and j (nghlist(i,j)==1) then I need to go to the chlist matrix and compare the values on column i and column j. For example compare columns (1,3,8,21,52) and get how many similar values they share together. i.e. I find all those columns have 3 similar values.
I tried using following code. But the problem is I need to compare the unknown number of columns (depend on the node connection (nghlist) for example 4 or 5 columns) together.
for i=1:1:n
for j=1:1:n
if (i~=j & nghlist(i,j)==1)
sum(ismember(chlist(:,i),chlist(:,j)));
end
end
end
Any help is highly appreciated.
++++ simplified example ++++++
take a look at the example http://i.imgur.com/mQjDqzz.jpg
nghlist matrix:
1 1 1 0 0
1 1 1 0 0
1 1 1 1 1
0 0 1 1 1
0 0 1 1 1
chlist matrix:
3 1 4 5 4
4 3 5 6 5
5 4 6 7 6
In this example since node 1 is connected to nodes 2 and 3, I need to compare column 1,2 and 3 from chlist. The output would be 1 (because they only share value '4').
And this value for node 5 would be 2 (because columns 3,4 and 5 only share value '5' and '6'). I hope now it is clear.
If the result of your simplified example is [1,2,0,3,2] then the following code worked for me.
(Matrix a stands for nghlist and matrix b for chlist, result is stored in s )
for i = 1:size(a,1)
s(i)=0;
row = a(i,:);
idx = find(row==1);
idx = idx(idx~=i);
tempb = b(:,idx);
for j=1:size(tempb,1)
if sum(sum(tempb==tempb(j,1)))==size(tempb,2)
s(i)=s(i)+1;
end
end
end
For every node you find all the ones in its row, then discard the one referring to the node itself. Pick the appropriate columns of chlist (line 6) and create a new matrix. For every element of the 1st column of this matrix check if it exists in all other columns.If it does, update the s value
Let's say, the indices of the columns that are to be compared is called idxList:
idxList = [1,3,8,21,50];
You may compare all with the first one and use "AND" to find the minimum number of shared values:
shared = ones(size(chlist(:,i)))
for ii = 2:length(idxList)
shared = (shared == (chlist(:,idxList(1)) == chlist(:,idxList(ii))))
end
Finally, sum as before
sum(shared)
I haven't checked the exact code, but the concept should become clear.
I manage to solve it this way. I compare the first and second column of tempb and put the result in tem. then compare tem with third column of tempb and so on. Anyway thank you finmor and also pyStarter, your codes has inspired me. However I knew its not the best way, but at least it works.
for i=1:size(nghlist,1)
s(i)=0;
j=2;
row=nghlist(i,:);
idx=find(row==1);
tempb=chlist(:,idx);
if (size(tempb,2)>1)
tem=intersect(tempb(:,1),tempb(:,2));
if (size(tempb,2)<=2)
s(i)=size(tem,1);
end
while (size(tempb,2)>j & size(tem)~=0)
j=j+1;
tem= intersect(tem(:,1),tempb(:,j));
s(i)=size(tem,1);
end
end
end

Matlab: Making code for coinflip

I'm having trouble with this problem since I'm new to matlab
"Use help to learn about the built in function ‘rand’. Write a script to use the rand function to generate a sequence of ‘head’ or ‘tail’ where one is head and zero is tail. The other function that you need to use is ‘round’ to convert the output of the ‘rand’ function to an integer. When we run your function it should display something like this: “T H T T H H H…..”.
I've used the help function and searched online but I still don't understand the random function.
I've used
flip = random('norm',1:10,1)
flip =
1.0774 0.7859 1.8865 3.9932 6.5326 5.2303 7.3714 7.7744 10.1174 8.9109
As you can see, it keeps giving me random numbers. I want my numbers to be either 0 or 1.
I know the 10 in 1:10 will display 10 values, but what does the two 1's mean?
I'd appreciate any help, thanks!
For completeness, there's also the randi function (at least from 2011b onwards):
faceId = randi(2,1,10) % generates random integers between 1 and 2 (inclusively)
faceId =
2 2 2 1 1 2 2 1 1 2
That avoids the need for the < 0.5 comparison and the +1
You can do as follow:
faceId=rand(1,10)<0.5
faceId =
1 1 0 0 1 1 1 0 0 0
faceName='TH';
faceName(faceId+1)
ans =
THHHHTTHTH

I Need help Numeric Comparison in matlab

I have one matrix called targets (1X4000); column 1 to 2000 contains double value 0 and column 2001 to 4000 contains double value 1
a)
i want to create a matrix called targets_1 where i want to check if the value is 0 then make the entry 1 so at the end of the day i must have a matrix with :column 1 to 2000 with value 1 and column 2001:4000 with value zero
b)
Same situation as above but this time i want to check if the value is 1 then make the entry 1 and if it is zero then make the entry zero; at the end; my new matrix targets_2 contains values: column 1 to 2000 with value zero and column 2001:4000 with value 1
i know how to use the strcmp function to make such checking with strings, but problem is that my original matrix is double and i dont know if there is such function like
setosaCmp = strcmp('setosa',species);
which could work with double (numbers); any help would be appreciated
Your question isn't very clear. It sounds like the following would satisfy your description:
targets_1 = 1 - targets;
targets_2 = targets;
targets1 = double(targets == 0);
targets2 = targets;
I'm basing this answer purely on the fact that you've mentioned setosaCmp = strcmp('setosa', species);. From this I'm guessing that
You have Statistics Toolbox, as setosa is a species of iris from the Fisher Iris dataset widely used in Statistics Toolbox demos, and
You have a variable containing class labels, and you'd like to construct some class indicator variables (i.e. a new variable for each class label, each of which is 1 when the item is in that class, and 0 when it's not).
Is that right? If not, please ignore me.
If I'm right, then I think the command you're looking for is dummyvar from Statistics Toolbox. Try this:
>> classLabels = [1, 2, 1, 2, 3, 1, 3];
>> dummyvar(classLabels)
ans =
1 0 0
0 1 0
1 0 0
0 1 0
0 0 1
1 0 0
0 0 1