# How to write such a loop?

1 view (last 30 days)
Negar on 18 Jan 2015
Commented: Negar on 18 Jan 2015
Hello everybody, I have two data vectors: d1 and d2, I have passed them through a segmentation algorithm, and the resulted class indexes are IDX1 and IDX2. Number of members in each segment are segMem1 for d1 and segMem2 for d2. Now I want to assign one index to each component in d1 (and d2), according to segMem1 (and segMem2). Moe specifically, I want to index the 3 first components of d1 as 1 1 1, the two next components as 2 2 , the 2 third components as 1 1 and so on, and at last I want to have 1 1 1 2 2 1 1 3 4 4 for d1. I have written the following code, and it seems to work for indexing d1. But I don't know how to make another loop to generalize this to both d1 and d2?
clear all
close all
clc
% data
d1 = [10 3 44 33 4 16 7 10 22 54];
d2 = [3 24 35 12 3 4 7];
IDX1 = [1 2 1 3 4];
IDX2 = [3 1 2 1];
segMem1 = [3 2 2 1 2]; % Determines how many times each index in IDX1 should be repeated.
segMem2 = [2 1 2 2];
n = 1;
a = cell(1,length(d1));
for k = 1:length(segMem1)
for j = n:segMem1(k)+n-1
a{j} = IDX1(k);
end
n = n+segMem1(k);
end
Any help would be greatly appreciated.
dpb on 18 Jan 2015
...I can not make it done for more than one data vector.
Then it doesn't work, does it? If it did, you wouldn't have a problem.
"Houston, we have a problem" in that the algorithm isn't well-enough defined by your initial description from which to write a piece of code. It's quite possible the actual solution is far removed from your first pass and the only practical way to attack it is to know the requirements first, not to try to guess how to hack on a given piece of code without answers to the questions posed by IA...
Negar on 18 Jan 2015
You are right dpb, I made a mistake in my description. But I tried to explain it in next comments. anyways, I try once more: IDX1 contains indexes after classification. so d1 is divided into 5 segments, and classified into 4 classes(to be labeled as 1,2,3,4): d1 = [10 3 44|33 4|16 7|10| 22 54]; where the vertical bar (|) shows the segment boundaries. Now I want IDX1 to be distributed according to segMem1: I mean I want IDX1 to be: [1 1 1 | 2 2 |1 1 |3 |4 4] I hope its now clear why IDX1 has five elements, while d1 has 10. Thank you for taking the time.

dpb on 18 Jan 2015
Edited: dpb on 18 Jan 2015
>> cell2mat(arrayfun(@(x,y) repmat(x,y,1),IDX1,segMem1,'uniform',0).')
ans =
1
1
1
2
2
1
1
3
4
4
>>
Since Matlab doesn't know about jagged arrays other than by cell array, you'll have to build the pieces and rearrange them into a cell array.
Oh, a spurious thought though I've never tried it; I suppose one could wrap a cellfun call around arrayfun, maybe to process the two cells as you've smushed them together above; otherwise a loop or the cell array.
OK, the looping construction works well enough...
>> for i=1:length(IDX)
idx=IDX{i};
seg=s{i};
cell2mat(arrayfun(@(x,y) repmat(x,1,y),idx,seg,'uniform',0))
end
ans =
1 1 1 2 2 1 1 3 4 4
ans =
3 3 1 2 2 1 1
>>
Left as row vectors for more compact display...
Negar on 18 Jan 2015
Thank you so much dpb, just working great ! You made my day! :)

Negar on 18 Jan 2015
Edited: Negar on 18 Jan 2015
I tried to make it for 2 data vectors, as follows:
clear all
close all
clc
% data
d1 = [10 3 44 33 4 16 7 10 22 54];
d2 = [3 24 35 12 3 4 7];
IDX1 = [1 2 1 3 4];
IDX2 = [3 1 2 1];
segMem1 = [3 2 2 1 2]; % Determines how many times each index in IDX1 should be repeated.
segMem2 = [2 1 2 2];
s = {segMem1 segMem2};
IDX = {IDX1 IDX2};
nData = 2 % 2 data vectors
n = 1;
a = cell(2,1);
for i = 1:nData
for k = 1:length(s{i})
for j = n:s{i}(k)+n-1
a{j,i}(k) = IDX{i}(k);
end
n = n+s{i}(k);
end
n = 1;
end
When running this code, I get all elements of the cell 'a' as doubles:
a =
1 3
1 3
1 [0,1]
[0,2] [0,0,2]
[0,2] [0,0,2]
[0,0,1] [0,0,0,1]
[0,0,1] [0,0,0,1]
[0,0,0,3] []
[0,0,0,0,4] []
[0,0,0,0,4] []
Could anyone suggest what I should do in order to have all elements as scalars? like
a =
1 3
1 3
1 1
2 2
2 2
1 1
1 1
3
4
4