MATLAB Answers

0

How can I change the rows of a nchoosek matrix to zero, according to a specific pattern, and avoid nested while loops?

Asked by Oana Cucu on 26 Jun 2018
Latest activity Edited by Jan
on 27 Jun 2018
Hi, I have the following matrix:
combs45 = nchoosek(1:45,2);
I want to change some of its rows to zero as follows:
%i=row number
combs45(1,:)=0 %i=1
combs45(2,:)=0 %i=1+1
combs45(45,:)=0 %i=1+44
%combs45(88,:) keep as it is ,i=1 +44 + 43
combs45(130,:) =0 %i=1+ 44 + 43 + 42
combs45(131,:)=0 %i=1 + 44 + 43 + 42 + 1
combs45(171,:)= 0 %i = 1 + 44 + 43 + 42 + 41
%combs45(211,:) keep, i=1 + 44 + 43 + 42 + 41 +40
combs45(250,:) = 0 %i= 1+ 44 + 43 + 42+ 41 + 40 + 39
combs45(251,:) = 0 %i=1 + 44 + 43 + 42 + 41 + 40 + 39 +1
and so on, until the end of the matrix.
I think the pattern is obvious in terms of what i is incremented by, also I want to keep the row unchanged when the number of steps can be exactly divided by 4.
Basically I don't want to pair together any of the elements inside the triplets (1,2,3), (4,5,6), ..., (43,44,45). Specifically, I don't want to pair 1 with 2 or 3, and 2 with 3, then I don't want to pair 4 with 5, etc, but I'm okay pairing 1 with 4, and 4 with 7, etc.
So I thought that in the 45 choose 2 matrix I want to first change the rows of those pairs (e.g., row1 is [1 2]) to 0 (so make row 1 [0 0]), and then remove the 0 elements from the matrix.
I wrote the following code but it's taking too long to run so I don't know if it's actually any good:
combs45=nchoosek(1:45,2);
i=1;
j=44;
count = 0;
while i<=45
while j>0
if mod(count,4)~=0
combs45(i,:)= 0;
count = count+1;
if mod(count,2)== 0
i=i+1;
combs45(i,:)= 0;
count = count+1;
else
i=i+j;
combs45(i,:)= 0;
count = count+1;
j = j-1;
end
else
count = count+1;
j = j-1;
i = i+j;
end
end
end
I'm wondering if there's a faster code I can run (or if there is a better pattern I can find and then adapt the code accordingly). Any help would be appreciated, thank you!

  6 Comments

Sorry man but if you're going to be so emotional about this I'm afraid I can't comment any further, I'll fix it on my own. Thanks and have a nice day!
Emotional? Sigh. I pointed out that your question was highly ambiguous? And I even fixed it to be readable.
@Oana Cucu: This is a forum for solving questions concerning Matlab. Your question matches the topic and is welcome here.
It is not easy to understand, what you want to achieve, but it is the nature of questions, that some details are not clear. In consequence questions for clarifications are typical for the process of finding a solution.
The members of the forum tell newcomers several times each day to apply a proper formatting. This can become frustrating for the long-term users of the forum, especially because many users still do not care about the instructions - but you did. Thanks!
John D'Errico is not a bunny. There is no reason to threaten to report this to MathWorks, because John is well known in this forum. He offers very useful support for solving Matlab problems and I appreciate his contributions, because they are excellent from the technical point of view. My personal opinion is, that he is not the best teacher for courteousness - but nobody cares about my personal opinions here, except if they concern questions of Matlab problems. Nevertheless, I do not see that his comments here are emotional or aggressive. I think, you will understand the nature of his attitude, if you read some thousands of his contributions or if some of his marvelous tools from the FileExchange saved you days or weeks of work.
I think, this is the most successful way to go: "Thanks and have a nice day!"

Sign in to comment.

1 Answer

Answer by Ameer Hamza
on 26 Jun 2018
Edited by Ameer Hamza
on 26 Jun 2018
 Accepted Answer

Here is my attempt to generate the pattern as described in your question, there might be more efficient ways.
combs45 = nchoosek(1:45,2);
i_pattern = 1; % first pattern value
startNumber = 44;
count = 2;
while i_pattern(end) < size(combs45, 1)
nextValue = 1;
if mod(count, 4) == 2
nextValue = i_pattern(count-1) + 1;
elseif mod(count, 4) == 3
nextValue = i_pattern(count-2) + startNumber;
startNumber = startNumber - 1;
else
nextValue = i_pattern(count-1) + startNumber;
startNumber = startNumber - 1;
end
i_pattern = [i_pattern nextValue];
count = count+1;
end
disp(i_pattern)
Columns 1 through 13
1 2 45 88 130 131 171 211 250 251 288 325 361
Columns 14 through 26
362 396 430 463 464 495 526 556 557 585 613 640 641
Columns 27 through 39
666 691 715 716 738 760 781 782 801 820 838 839 855
Columns 40 through 52
871 886 887 900 913 925 926 936 946 955 956 963 970
Columns 53 through 59
976 977 981 985 988 989 990
Then to set the required rows to zero
i_pattern(4:4:end) = []; % delete every 4th entry.
combs45(i_pattern, :) = 0;
I tried running your code and It appears to be wrong since the value of count exceeds beyond the length of combs45.

  3 Comments

haha okay thanks! i just put it there so that people could tell what I was trying to do, i still can't run it on my machine.
You are welcome. I was also not able to completely run your code, it appears to be an infinite loop. I just paused the code to see the variable values, pausing the code is a good point to remember while debugging your code.
I think I know what you mean, is that when the 'continue debugging' button normally appears? This time it didn't, but I wrote disp(i) in the code at the end of every 'if' statement and then left it running, and it still is running even though I cliked 'Pause', now it's over 500,000. I guess I don't understand since the code has the condition 'i<=45'?

Sign in to comment.