Printing n choose k combinations in matlab - matlab

I need to create an algorithm in matlab which returns any combination of n subset from the k set. For example I have a set {1,2,3,4,5} and I need any combination of 3 numbers included in this set. So this function should returns:
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
I have tried to write it by myself, but unsuccessfully and I give up. It partially works, but it creates endless loop.
for i=1:n
if(firstTime)
lastComb=min //123
firstTime=false
else
for d=k:-1:1
while(lastComb(:,end) < n-k+d && lastComb(:,end)<=n)
newComb=lastComb
newComb(d)=lastComb(d)+1
combos= [combos; newComb]
lastComb=newComb
end
while(lastComb(:,end) > n-k+d && lastComb(:,end)<=n)
newComb=lastComb
for p=d:-1:1
if(newComb(p)+1 <=n)
newComb(p)=newComb(p)+1
combos= [combos; newComb]
end
end
end
end
end
end

Overall, your syntax is a little confusing (as previously stated by someone else). If you're posting a question here, it's a good idea to include all of your code, including the defined variables just for ease of those that are helping you.
A few major issues that I'm seeing with what you have are as follows:
(1) You seem to only be getting "n" combinations with what you're writing, which I think is 3 combinations. Instead, you should be getting 10 combinations. The beginning of this function should probably have a combination calculation [nCk = n!/((n-k)!*k!)].
(2) You're defining the first combination as 1,2,3, but then you don't but it into the "combos" set that you are making. Instead you replace it with something else before it can reach "combos."
There are a couple more, but try fixing these parts and the others may come naturally.
Overall, this function already exists. Just type "open nchoosek" into MATLAB to see a refined version of what you are attempting if you get stuck!

Related

Seeking vectorized solution to sum up elements using accumarray in Matlab/Numpy

(To anyone who reads this, just to not waste your time, I wrote up this question and then came up with a solution to it right after I wrote it. I am posting this here just to help out anyone who happened to also be thinking about something like this.)
I have a vector with elements that I would like to sum up. The elements that I would like to add up are elements that share the same "triggerNumber". For example:
vector = [0, 1, 1, 1, 1]
triggerNumber = [1, 1, 1, 2, 2]
I will sum up the numbers that share a triggerNumber of 1 (so 0+1+1 =2) and share a triggerNumber of 2 (so 1+1+1 = 3). Therefore my desiredOutput is the array [2, 2].
accumarray accomplishes this task, and if I give it those two inputs:
output = accumarray(triggerNumber.',vector.').'
which returns [2, 2]. But, while my "triggerNumbers" are always increasing, they are not necessarily always increasing by one. So for example I might have the following situation:
vector = [0, 1, 1, 1, 1]
triggerNumber = [4, 4, 4, 6, 6]
output = accumarray(triggerNumber.',vector.').'
But now this returns the output:
output = [0, 0, 0, 2, 0, 2]
Which is not what I want. I want to just sum up elements with the same trigger number (in order), so the desired output is still [2, 2]. Naively I thought that just deleting the zeros would be sufficient, but then that messes up the situation with the inputs:
vector = [0, 0, 0, 1, 1]
triggerNumber = [4, 4, 4, 6, 6]
which if I deleted the zeroes would return just [2] instead of the desired [0, 2].
Any ideas for how I can accomplish this task (in a vectorized way of course)?
I just needed to turn things like [4, 4, 4, 6, 6] into [1, 1, 1, 2, 2], which can be done with a combination of cumsum and diff.
vector = [0, 0, 0, 1, 1];
triggerNumber = [4, 4, 4, 6, 6];
vec1 = cumsum(diff(triggerNumber)>0);
append1 = [0, vec1];
magic = append1+1;
output = accumarray(magic.',vector.').'
which returns [2, 2]....and hopefully my method works for all cases.

What is the difference between ending lines with ellipses or without in literally written matrices? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
The basics
The regular way of writing matrices in MATLAB is the one-liner, like:
A = [3,2,1;2,1,3;1,3,2];
Breaking a command into several lines is done with 3 dots, like:
x = tan(...
y); % ie: x = tan(y);
The problem
Now, combining these two rules to write a matrix literally (to clearly see its structure) results in:
B = [3, 2, 1;...
2, 1, 3;...
1, 3, 2];
MATLAB (in scripts and functions) however also accepts this form:
C = [3, 2, 1;
2, 1, 3;
1, 3, 2];
The question
Are both ways of writing a matrix (B and C above) completely identical in terms of how MATLAB reads them? If there is a difference, should one be preferred over the other, and why?
EDIT: There are many ways writing a matrix in MATLAB, in one or on multiple lines, which all produce the same output. But is there one method that MATLAB understands best (i.e. minimum effort to understand the input properly)? Or is the effort on the program side always the same?
The reason why I ask: I just found myself using both methods in a single script, once to simply break a long line of numbers, once to to have a better view on the data.
Writing:
A = [3, 2, 1; 2, 1, 3; 1, 3, 2];
Or:
B = [3, 2, 1;...
2, 1, 3;...
1, 3, 2];
Or:
C = [3, 2, 1;
2, 1, 3;
1, 3, 2];
Or an even shorter way:
D = [3, 2, 1
2, 1, 3
1, 3, 2];
Are all completely identical. ; or line breaks are both used for separating matrix rows.
Simple test:
>> isequal(A,B)
ans =
logical
1
>> isequal(A,C)
ans =
logical
1
>> isequal(A,D)
ans =
logical
1
So, which is best?
Using ... and line breaks (and ;) is completely unnecessary, it is using line breaks and than overriding them with ... for no reason. It is actually like writing:
B = [3, 2, 1; 2, 1, 3; 1, 3, 2];
Using ; and line breaks is also unnecessary although it may be helpful adding ; if you will want in the future to make them one line. It may also look more clear (opinion based?)
Using no line breaks is quite common, it is more compact although may not look as nice.
To summarise: Using ... and line breaks (and ;) is unnecessary and maybe confusing. Other option are mainly opinion based.

Getting single dimensional array, not multi dimensional

When I run
[w*2 for w in [1, 2, 3]]
I get
[[2, 4, 6]]
but actually I want
[2, 4, 6]
Live example
Obviously following is in option, but I do not want to rely on that:
[w*2 for w in [1, 2, 3]][0]
I found a solution myself:
(w*2 for w in [1, 2, 3])
// -> [2, 4, 6]

Create array of points from single dimensional array of points

Waht i need to do is take a single dimensional array, ie:
[1, 1, 2, 2, 3, 3]
and turn it into an array of points:
[[1, 1], [2, 2], [3, 3]]
I am hoping for a simple native matlab way of doing it rather then a function. This will be going into sets of points ie:
[ [[1, 1], [2, 2], [3, 3]],
[[4, 4], [5, 5], [6, 6]],
[[7, 7], [7, 7], [8, 8]] ]
The reason this is going to happen is the points will be stored in a text file as a single stream and i need to turn them into something meaningful.
First note that a horizontal concatenation of row vectors will result in one larger row vector rather than in a row of pairs, that is [[1, 1], [2, 2], [3, 3]] is the same as [1 1 2 2 3 3]. Hence, you need to concatenate them vertically.
You can try
a = [1, 1, 2, 2, 3, 3];
b = reshape(a, 2, floor(length(a)/2))';
This will result in a matrix where each row represents the coordinates of one point.
b =
1 1
2 2
3 3
I'm just adding this answer for the sake of diversity:
Just as H.Muster said, concatenation of vectors will result in a larger vector or a matrix (depending on your operation). You can go with that.
But you can also use a cell array, which is a set of data containers called "cells". A cell can contain any type of data, regradless of what other cells contain in the same cell array.
In your case, creating a cell array can be done using a slightly different syntax (than H.Muster's answer):
a = [1, 1, 2, 2, 3, 3];
p = mat2cell(a, 1, 2 * ones(1, numel(a) / 2))
p is a cell array, each cell containing a 1-by-2 point vector. To access an element in a cell array, you'll have to use curly braces. For instance, the second point would be p{2} = [2, 2].

Dimension Mismatch MatLab; cant figure out why it is mismatching

I think it may be a syntax issue, here is the code.
load ([ 'C:\Users\Abid\Desktop\Inquiry Runs\dtS' ])
dtS((dtS==0))=nan;
for j=2:9;
maxS=max(dtS(j,:));
minS=min(dtS(j,:));
maxval(j,:)=dtS((dtS>(maxS-.1*maxS)));
minval(j,:)=dtS((dtS<(minS+.1*minS)));
avmax(j)=mean(maxval(j,:));
avmin(j)=mean(minval(j,:));
avs(j,:)=[avmax(j) avmin(j)]
end
So I know the the row matrices are different sizes every loop. For example maxval(j,:) will change depending one row it is looking through for certain values.
I did this manually and I see that on the first loop the matrices are size (1,1), however, if I set the loop to run for only j=2, the row length is 13.
Usually if a matrix is changing size on the loop, I only get a warning, but this time I think it is due to a reason I don't understand.
You are right that the problem is with maxval(j, :) being a different size. length(maxval(j, :)) is not length(dtS((dtS>(maxS-.1*maxS)))); this causes a problem since maxval has to be 'rectangular', but if it were extended by this line of code, some of its values would not be defined. Consider:
x = [1, 2; 3, 4];
x(3, :) = [5, 6, 7];
If this code were legal, the result would be:
x: [1, 2, ?;
3, 4, ?;
5, 6, 7]
and because of those undefined values, matlab will not let you do this. You could use a cell array instead:
maxval = cell(9, 1);
avmax = zeros(9, 1);
avs = zeros(9, 2);
for j=2:9;
maxS=max(dtS(j,:));
minS=min(dtS(j,:));
maxval{j} = dtS((dtS>(maxS-.1*maxS)));
minval{j} = dtS((dtS<(minS+.1*minS)));
avmax(j)=mean(maxval{j});
avmin(j)=mean(minval{j});
avs(j,:)=[avmax(j) avmin(j)]
end