Here my loop:
for i = 1: m-1
for j = i+1:m
if isequal(A(:,i), A(:,j)) %are any two columns equal?
Then the first column index is to be removed from the list of
questions.
remove(i) = 1;
else
T = A(:,i)+A(:,j); % are any two columns mirror
images?
if all(T == 1)
remove(i) = 1;
end
end
end
end
questions = questions(~remove);
Try this:
% remove duplicate columns
o1 = transpose(unique(a','rows'));
% remove mirror images
o2 = ~o1;
[b,c,d] = unique([o1,~o1]','rows');
k = sort(d);
k2 = k(~diff(k));
s = k2(k2<=ceil(size(b,1)/2));
o1(:,s) = [];
I haven't tested it but should work.
Thank you, this is a nice solution. Now I am exited to see if my
program will become faster!
I was a little bit to eager there, it turns out it doesn't work, as
the wrong questions get deleted. If there is only 1 set of mirror
questions, it is enough to change the last line:
1(:,s(m)) = [];
but if there are more than one pair of mirror questions, the false
ones might get deleted (that is both [1,0,0] and [0,1,1] might get
deleted, but the other pair [0,1,0] and [1,0,1] would not be deleted,
instead of one of each pair...)
all the information needed is in the output of unique, I am just
having a hard time figuring out how to do this.
Ok, so I have one solution:
b = b';
[b,m,d] = unique([b,~b]', 'rows', 'first');%remove mirror
columns
d = m(d);
order = [1:length(d)]';
d2 = order-d;
index = find(d2>0);
to_delete = min(index-length(d)/2, d(index));
to_delete = unique(to_delete);
questions(to_delete) = [];
I am guessing the stuff in the middle could be done more efficiently,
but it works!
You might try this. It uses only one call to 'unique'. The result is placed in B.
T = A.';
p = T(:,1)==1;
T(p,:) = 1-T(p,:); % Complement T rows that have 1 in first col.
[t,m,t] = unique(T,'rows'); % Reduce to unique T rows ('last')
B = A(:,sort(m)); % Reduce to corresponding cols. in A
Roger Stafford
Thank you, that is if course a lot simpler and faster!