1
votes

I have two vectors, both formatted as double. Vector "A" is mx2. The first column contains continuous timesteps and the second column data from a measurement series.

Vector "B" is a nx2 (1<n<m) and contains several timestamps which match to some of the timesteps in vector "A".

Now I want to split vector "A" into a matrix "M". The Matrix should start a new column, each time, the timesteps of "A" corrspond with the timestamps in the first column in vector "B" and end when they correspond with the one in the second column.

So in each row of "B", the two timestamps define a column of the matrix "M". As the sequences between two timestamps doesn't have the same length, every row should be filled up with 0 up to a fix row. For example row 5. The matrix should only contain the measurement data and none of the timestamps. The matrix should be formatted as double.

In an example it would look like:

vector A [18 x 2]: 
1. column [11:13:30  11:13:31  11:13:32  11:13:33  11:13:34  11:13:35  11:13:36  11:13:37  11:13:38  11:13:39  11:13:40  11:13:41  11:13:42  11:13:43  11:13:44  11:13:45  11:13:46  11:13:47]
2. column [6000, 6500, 5000, 8000, 15000, 15500, 16000, 6000, 4000, 16500, 14000, 400, 5000, 6000, 9000, 12000, 13000, 5000]

vector B [3 x 2]: 
1. column [11:13:33  11:13:39  11:13:44]
2. column [11:13:36  11:13:40  11:13:46]

matrix M [3 x 6]: 
1. column [8000 15000 15500 16000 0]
2. column [16500 14000 0 0 0]
3. column [9000 12000 13000 0 0]

This seems like a quite complex thing to me and I hope anybody can help me with this.

2
@PranavTotala is suggesting an edit, he noticed that in the example B is smaller than A, but in the text it is written that they're the same size. Please fix your post. - Cris Luengo
Oh, sorry for that mistake. I just wanted to say, that A and B both have 2 columns but can differ in the amount of their rows. But of course they don't have the same size. - Chris
Are A and B cell arrays? Are the time stamps encoded as numeric values or strings? - gnovice
A and B are formatted as double. Therefore, the timestamps in B, as well as the timeseries in A, are encoded as numeric value. - Chris

2 Answers

2
votes

The following code should do the job:

A = {
  '11:13:30'  6000;
  '11:13:31'  6500;
  '11:13:32'  5000;
  '11:13:33'  8000;
  '11:13:34' 15000;
  '11:13:35' 15500;
  '11:13:36' 16000;
  '11:13:37'  6000;
  '11:13:38'  4000;
  '11:13:39' 16500;
  '11:13:40' 14000;
  '11:13:41'   400;
  '11:13:42'  5000;
  '11:13:43'  6000;
  '11:13:44'  9000;
  '11:13:45' 12000;
  '11:13:46' 13000;
  '11:13:47'  5000
};

B = {
  '11:13:33' '11:13:36';
  '11:13:39' '11:13:40';
  '11:13:44' '11:13:46';
};

fill = 5;

% Obtain the computation parameters from A...
A_len = size(A,1);
A_seq = (1:A_len).';

% Find the breakpoints of A using the values in B...
idx_beg = ismember(A(:,1),B(:,1)) .* A_seq;
idx_beg = idx_beg(idx_beg > 0);
idx_end = ismember(A(:,1),B(:,2)) .* A_seq;
idx_end = idx_end(idx_end > 0);

%Compute the maximum number of elements per row...
rows = max(idx_end - idx_beg + 1);

% Adjust the fill in order to cover enough elements...
fill = max([fill rows]);

% Create the row indexers of A based on the breakpoints...
ran = arrayfun(@(x)idx_beg(x):idx_end(x),1:numel(idx_beg),'UniformOutput',false);

% Create the final matrix with zero-padding on the right...
mat = cellfun(@(x)[[A{x,2}] zeros(1,fill-numel(x))],ran,'UniformOutput',false);
mat = cell2mat(mat(:,:).');

Final output:

mat =
       8000       15000       15500       16000           0
      16500       14000           0           0           0
       9000       12000       13000           0           0

The code is pretty self-explanatory, but if you need clarifications feel free to ask in the comments below.

EDIT

A = [
  30  6000;
  31  6500;
  32  5000;
  33  8000;
  34 15000;
  35 15500;
  36 16000;
  37  6000;
  38  4000;
  39 16500;
  40 14000;
  41   400;
  42  5000;
  43  6000;
  44  9000;
  45 12000;
  46 13000;
  47  5000
];

B = [
  33 36;
  39 40;
  44 46;
];

fill = 5;

% Obtain the computation parameters from A...
A_len = size(A,1);
A_seq = (1:A_len).';

% Find the breakpoints of A using the values in B...
idx_beg = ismember(A(:,1),B(:,1)) .* A_seq;
idx_beg = idx_beg(idx_beg > 0);
idx_end = ismember(A(:,1),B(:,2)) .* A_seq;
idx_end = idx_end(idx_end > 0);

%Compute the maximum number of elements per row...
rows = max(idx_end - idx_beg + 1);

% Adjust the fill in order to cover enough elements...
fill = max([fill rows]);

% Create the row indexers of A based on the breakpoints...
ran = arrayfun(@(x)idx_beg(x):idx_end(x),1:numel(idx_beg),'UniformOutput',false);

% Create the final matrix with zero-padding on the right...
mat = cellfun(@(x)[A(x,2).' zeros(1,fill-numel(x))],ran,'UniformOutput',false);
mat = cell2mat(mat(:,:).');
0
votes

Here is the code for the question. I calculated the difference between the two timestamps of vect B. Then i checked the same timestamp in A and replaced val number of variables in M from A(2) and iterated it for all A. Adding The val variable saved from an extra nested for loop where i had to find B(i,2).

a=length(A(:,1));
b=length(B(:,1));
M= zeros(5,b);
i=1;

for j=1:a
    if B{i,1} == A{j,1}
        durn_vect=B{i,2}-B{i,1};
        val=durn_vect(4)*600+durn_vect(5)*60+durn_vect(7)*10+durn_vect(8)+1;
        for k=1:val
            M(k,i)=A{j+k-1,2};
        end
        i=i+1;
    end
    if(i>3)
        break
    end
end