I know that my problem is quite specific but still hope to find here an answer and that it can be helpful for more people in the future.
I have different reference intervals, which indicate time periods, and different values associated to each period. For example:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % endingpoints for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
If you notice, the first and third period are the same (same start and end reference value, 17-25) therefore the values 1 and 3 can be associated with the same period.
Therefore I would like to obtain two arrays, one listing the timesteps for each period and one listing the associated values to each period. I am able to do it only repeating the timesteps for each period, doing:
time_cell = cell (length(starts),1);
values_cell = cell (length(starts),1);
values_repeated = cell (1,length(starts));
for i= 1:length(starts)
time_cell{i,1}= (starts(i,1):1:ends(i,1))';
values_cell{i,1}= values(i);
values_repeated{:,i} = repmat(values_cell(i,1),length(time_cell {i,1}),1);
end
all_times_numeric = cell2mat(time_cell(:,1));
all_values = cat(1,values_repeated{:,:})
Which allows me to obtain:
all_values =
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
I am able to eliminate the repetitions from all_times_numeric using the function unique, but I am struggling in finding a method to merge the values that correspond to the same period in something like
all_values =
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
or
all_values =
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
Is there a way of obtaining any of these arrays using the for loop implemented in the example and extending the results for any case (any start/end period, more values associated to the same periods, etc.)? Many thanks in advance!
Here is an option:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % ending points for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
all_values = zeros(max(ends),max(values));
for k = 1:length(starts)
all_values(starts(k):ends(k),values(k)) = values(k);
end
all_values = all_values(sum(all_values,2)>0,:);
all_values = arrayfun(@(r) nonzeros(all_values(r,:)).',...
1:length(all_values),'UniformOutput',false).'
Up to the line before the last one, add_values
is a matrix size max(ends)
-by-max(values)
, looks like this:
all_values =
1 0 3
1 0 3
1 0 3
.
.
.
0 2 0
0 2 0
so for each time step we have a row with the matching values in different column. Now we want to get all the zeros out, and keep only the non-zero numbers in each row. So we define new anonymous function:
@(r) nonzeros(all_values(r,:)).'
that get a row r
, and return all the values different than zero in all_values(r,:)
. The output of nonzeros
is a column, so to keep the result as a row we add the .'
(transpose). Now we want to apply this on all rows, so we use arrayfun
:
arrayfun(function_handle,1:length(all_values)).'
this apply the function in function_handle
, which is the function we just defined, on all elements in 1:length(all_values)
, which are simply all row numbers in all_values
. But, since the output of our functions varies in size, we need to toggle off the 'UniformOutput'
option, so the result for each element is stored in different cell in a cell array. The output of arrayfun
is a row, so to get the result as a column we add the .'
(transpose). So we get:
all_values =
[1x2 double]
[1x2 double]
[1x2 double]
.
.
.
[ 2]
[ 2]
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments