How to find time delay between two time series data? - matlab

I want to know how to find delay between two time series, for example when we have this pseudo time series data:
A: 1 1 1 1 1 2 1 1 1 1
B: 1 1 1 1 2 1 1 1 1 1
C: 1 1 2 1 1 1 1 2 1 1
For example:
A: 1 1 1 1 1 2 1 1 1 1
B: 1 1 1 1 2 1 1 1 1 1
clear all;
filename = 'pseudo.xls';
visi=xlsread(filename); %nuskaitomi visi stulpeliai
[n,m]=size(visi);
A=visi(:,1);
B=visi(:,2);
C=visi(:,3);
A1=transpose(A);
B1=transpose(B);
C1=transpose(C);
t=(1:10);
plot(t,A1,'b'); hold on;
plot(t,B1,'m');
d1 = finddelay(B1,A1);
[c,lags] = xcorr(B1,A1);
d2 = -(lags(c == max(c)));
And the answer is d1=1 and d2=1. It all right.
But what about the time delay between B and C.
B: 1 1 1 1 2 1 1 1 1 1
C: 1 1 2 1 1 1 1 2 1 1
How to find two delay parameters?
And how it works when we have two long time series?
Perhaps you can offer and more methods of determining the time delay?
Thank you for your advice and answers :)

Related

How do I create a list of 1's in KDB?

I'm trying to create a list of 1's in KDB.
I've tried:
{1} each (til 500)
which worked, but is ugly. Is there a more elegant way? (I tried ' as well, but this didn't work).
You can use the 'take' (#) operator for this.
q)500#1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1..

What is the immediate lower number next to One in Double precision

What is the most immediate lower number next to number 1, in double-precision number format ? How to find that in MATLAB?
For instance, the next higher number next to positive number X can be find using X+eps(X). But how to do that for an immediate lower number?
format hex # So that the difference is easy to see
X-eps(X)
appears to work just fine
use the code bellow ,B is most immediate lower number next to number 1 that is half of eps:
A = uint64(0);
bits=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0];
for i = 1: 64
A = bitset(A, i, bits(i));
end
fileID = fopen('bits.bin','w');
fwrite(fileID, A,'uint64');
fclose(fileID);
fileID = fopen('bits.bin');
B = fread(fileID,1,'*float64');
fclose(fileID);
disp(B);
disp(1.0-B);
disp(eps(1.0))

Generating a matrix containing 3 numbers

I am trying to create an 8x8 matrix containing 0s, 1s and 2s. Each row and each column should contain two 0s, three 1s and three 2s.
Previously I have used the below to generate an example containing only 1s and 0s.
output = zeros(8, 8);
for i=1:8
tmp = (1:8) + (i);
tmp = rem(tmp, 4);
output(i,:) = tmp;
output(i,:) = tmp > 0;
end
output =
1 1 0 1 1 1 0 1
1 0 1 1 1 0 1 1
0 1 1 1 0 1 1 1
1 1 1 0 1 1 1 0
1 1 0 1 1 1 0 1
1 0 1 1 1 0 1 1
0 1 1 1 0 1 1 1
1 1 1 0 1 1 1 0
However I would now like something similar to the following:
output =
1 1 0 1 2 2 0 2
1 0 1 2 2 0 2 1
0 1 2 2 0 2 1 1
1 2 2 0 2 1 1 0
2 2 0 2 1 1 0 1
2 0 2 1 1 0 1 2
0 2 1 1 0 1 2 2
2 1 1 0 1 2 2 0
Thanks for your help.
What you have in your example is a Hankel matrix so you could use the hankel function
c = [1 1 0 1 2 2 0 2];
k = [2 1 1 0 1 2 2 0];
A = hankel(c,k)
where c is the first column of the output matrix and k is the last row.
Making your output matrix a Hankel matrix is a good idea (based on your requirements) as it will enforce the row and column frequency counts for each value. You would not necessarily get this just by creating rows that are random permutations of a base row (using randperm for example) as duplicate rows would be possible which would break your column requirements.
As an example, if you want random c with fixed numbers of specific elements, you can randomly permute a base vector containing the required values and frequencies - as per your requirement this would be
c = [0 0 1 1 1 2 2 2];
index = randperm(numel(c));
c = c(index);
c =
0 2 0 2 2 1 1 1
To get the square Hankel structure then choose k to be the next cyclic permutation of c
k = circshift(c',1)'
k =
1 0 2 0 2 2 1 1
and just call hankel with these as mentioned above
A = hankel(c,k)
A =
0 2 0 2 2 1 1 1
2 0 2 2 1 1 1 0
0 2 2 1 1 1 0 2
2 2 1 1 1 0 2 0
2 1 1 1 0 2 0 2
1 1 1 0 2 0 2 2
1 1 0 2 0 2 2 1
1 0 2 0 2 2 1 1
The above output is based on what I got on my machine based on the output from randperm.
Any output matrix generated using the above will meet your requirements specified in the question.

How to do multilevel indexing on array of structs in Matlab?

Let's say I create an array of structs in matlab using:
mystruct = repmat(struct('field1',1, 'field2', ones(10,1)), 10, 1 );
For my purposes (simple example aside), I would find it very useful to get a vector output from using:
myvector = mystruct(:).field2(1)
However this gives me the error:
'Scalar index required for this type of multi-level indexing.'
EDIT: What I expect to get is the first element of the ones vector, from each struct in the array, hence a 10x1 vector of '1'.
I could easily manually using a for loop go through each value in my struct and assign to myvector but that seems incredibly cumbersome and also slow. Any thoughts?
I'm assuming you're trying to collect all of the field2 vectors into myvector:
myvector = [mystruct(:).field2];
Returns:
myvector =
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
EDIT: Per your comment, you can use the above and throw out the data you don't want (myvector(2:end,:) = []; in this case). This is a pretty memory intensive way to do it though. There may be a way to pull what you want using structfun or similar but I'd need to think about how to do it.
EDIT2: Try arrayfun(#(x) x.field2(1), mystruct) and see if this returns what you're looking for.
In two step you can:
get your struct filed2 as a matrix:
foo = [mystruct.field2];
get the first row (that contains the first indices of the field2)
myvector = foo(1, :);

Iterate one vector through another in Matlab Part 2

This is a similar request to my post at Iterate one vector through another in Matlab
I am using Luis' suggestion with the following code:
E=[1 2 3 4 5 6 7 8 9 10];
A = [1 2];
s = size(E,2);
t = numel(A);
C = cell(1,s);
[C{:}] = ndgrid(A);
C = cat(s+1, C{:});
C = fliplr(reshape(C, t^s, s));
This produces a good result for C as a 1024x10 matrix with all possible permutations of 1 and 2 to a length of 10 columns. What I want to do is remove any rows that are not in increasing order. For example now I get:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 1 2 2
All are valid except for the third row since it goes from 2 to back to 1.
I have code to get the desired result, but it is very slow and inefficient.
E=[1 2 3 4 5 6 7 8 9 10];
A = [1 2];
s = size(E,2);
t = numel(A);
C = cell(1,s);
[C{:}] = ndgrid(A);
C = cat(s+1, C{:});
C = fliplr(reshape(C, t^s, s));
min=0;
for row=1:size(C,1)
for col=1:size(C,2)
if(C(row,col)>min)
min=C(row,col);
elseif(C(row,col)<min)
C(row,:)=0;
continue;
end
end
min=0;
end
C = C(any(C,2),:); %remove all zero rows
The desired output is now:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 2 2 2
1 1 1 1 1 1 2 2 2 2
1 1 1 1 1 2 2 2 2 2
1 1 1 1 2 2 2 2 2 2
1 1 1 2 2 2 2 2 2 2
1 1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
Any ideas on how to optimize my code so I do not need to use nested loops?
The super-simple but not-quite-so-obvious solution via a couple of row-wise operations:
d = diff(C, [], 2);
m = min(d, [], 2);
C = C(m>=0, :);
Of course, in this particular example it would be far easier to just generate the resulting matrix directly:
C = flipud(triu(ones(s+1,s).*(max(A)-min(A))) + min(A));
but I assume you're also interested in less trivial values of A ;)