Strange behaviour of MATLAB combnk function - matlab

I am trying to generate all combination of 2 elements in a given range of numbers. I am using 'combnk' function as follows.
combnk(1:4,2)
ans =
3 4
2 4
2 3
1 4
1 3
1 2
combnk(1:6,2)
ans =
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
The order of combinations returned appears to change. I need to know the order in advance for my program to work properly.
Is there any solution to make sure I get the combinations in a consistent order?
Also, why is MATLAB showing this strange behavior?
The only solution I can think of so far is to first check the 1st entry of the result matrix and flip it up side down using 'flipud' function.
Update: By a little bit of experimenting I noticed the reverse order occurs only when the length of the set of numbers is less than 6. This is why combnk(1:6,2) produce the 'correct' order. Where as combnk(1:5,2) produce the results backwards. This is still big problem.

You could try nchoosek instead of combnk. I don't have the matlab statistics toolbox (only octave), so I don't know if nchoosek has any significant disadvanvatages.

This will solve the ordering issue:
a=combnk(1:4,2);
[~,idx]=sortrows(a);
aNew=a(idx,:);
I don't know why MATLAB is showing this behavior.

Related

extract the unique blocks from matrix using Mean Square Error matlab

The Mean Square Error(MSE), is a method used to define the difference in between two blocks, and can be calculated as follow: a and b two blocks equal size
MSE = sqrt(sum(sum((a-b).^2)))/size(a or b)
If the MSE is less than a given threshold, than the two blocks are not different.
Given a matrix A, already reshaped to be contain blocks all in the same raw,
the purpose is to extract all blocks where the MSE is less than a given threshold (based on the first block), then return the mean of those blocks. again, extract the second group of blocks which the MSE is less than the given threshold where the blocks that already assigned to be a part of other group of blocks must not be extracted again. Better than that, it must be deleted to reduce the search time. and so on till all blocks of the matrix A are assigned to be part of a group. the blocks of the resulted matrix should be organized based on the number of block within the group, from the biggest number of blocks to the lowest. And here is an example :
Given matrix A where the size of A is 2 by 14:
A= [1 1 2 2 9 9 4 4 6 6 5 5 3 3
1 1 2 2 9 9 4 4 6 6 5 5 3 3];
PS: its not necessary the blocks contain the same numbers, it is just to make the example clear.
blocks size is : 2 by 2
the threshold is 2
now we extract all blocks where the MSE is less than the threshold starting from the first block in the matrix A. so the blocks are:
1 1 2 2 3 3
1 1 2 2 3 3
the mean of those blocks is
Result= [ 2 2
2 2];
again. we extract all blocks where the MSE is less than the threshold, but we need to avoid the blocks that already extracted, so the second group of blocks is :
9 9
9 9
the mean of this block is it self, so:
Result= [2 2 9 9
2 2 9 9];
again. we extract all blocks where the MSE is less than the threshold, but we need to avoid the blocks that already extracted, so the third group of blocks is :
4 4 6 6 5 5
4 4 6 6 5 5
the block
3 3
3 3
is not a part of this group even if the MSE is less then the threshold because is already extracted to be part of the first group.
the mean of those blocks is:
5 5
5 5
therefore the result should be:
Result= [2 2 5 5 9 9
2 2 5 5 9 9 ];
there are any fast way to apply that ?
PS: that Datasize is huge, therefore , there are a need for a fast way to do that.

Accessing indexes as first columns of matrix in Matlab

I have data that is output from a computational chemistry program (Gaussian09) which contains sets of Force Constant data. The data is arranged with indexes as the first 2-4 columns (quadratic, cubic and quartic FC's are calculated). As an example the cubic FC's look something like this, and MatLab has read them in successfully so I have the correct matrix:
cube=[
1 1 1 5 5 5
1 1 2 6 6 6
.
.
4 1 1 8 8 8
4 2 1 9 9 9
4 3 1 7 7 7 ]
I need a way to access the last 3 columns when feeding in the indices of the first 3 columns. Something along the lines of
>>index=find([cube(:,1)==4 && cube(:,2)==3 && cube(:,3)==1]);
Which would give me the row number of the data that is index [ 4 3 1 ] and allow me to read out the values [7 7 7] which I need within loops to calculate anharmonic frequencies.
Is there a way to do this without a bunch of loops?
Thanks in advance,
Ben
You have already found one way to solve this, by using & in your expression (allowing you to make non-scalar comparisons).
Another way is to use ismember:
index = find(ismember(cube(:,1:3),[4 3 1]));
Note that in many cases, you may not even need the call to find: the binary vector returned by the comparisons or ismember can directly be used to index into another array.

How to find the unique rows in a matrix in matlab, where the order of numbers in row is NOT important?

I have a matrix of following form in matlab:
3 4
4 3
5 6
6 5
I would like to have the rows 1 and 2 to be considered a duplicate, where the elements of the two rows are the same but not in the same order. Similarly rows 3 and 4 should be considered the same. So, given the matrix above, I would like to have the following as the result:
3 4
5 6
I have tried the unique function but it cannot help me for this purpose.
My actual matrix is quite large, and I don't want to solve the problem with an exhaustive pairwise search, since it is extremely time consuming.
Is there an elegant way of achieving my goal?
This is one way of ding this:
X = [3 4
4 3
5 6
6 5];
X = sort(X, 2);
UniqueRows = unique(X, 'rows');
UniqueRows =
3 4
5 6

MATLAB: Conditionally matrix elements into two separate cell arrays

A matrix has 2 rows and several columns, and the first contains alternating strings of 1's and 0's. I want to use this binary as a decision to copy the information below it into one of two cell arrays. I understand that this can be done through iteration with the use of the IF conditional, or with while loops, but I'm having trouble cleaning it up.
For example, for
mat = [ 1 1 1 0 0 1 1 0 0 0 0 1 1 1 ;...
1 2 3 4 5 6 7 1 2 3 4 5 6 7 ]
I would like to output two cell arrays, one for the '1s', and one for the '0s':
1 2 3
6 7
5 6 7
and:
4 5
1 2 3 4
There are a couple of ways of doing this, I am sure. One might be using a loop; however, you can also make good use with the built-in find function. Below is a sample solution based on your example.
For '1s',
Here, we would like to get the indices with '1' from the first row.
on_array= mat(2, find(mat(1,:)));
or as suggested by #H.Muster
on_array= mat(2, mat(1,:)==1);
For '0s',
Here, we would like to get the indices with '0' from the first row.
off_array = mat(2, find(mat(1,:)==0));
or as suggested by #H.Muster
off_array= mat(2, mat(1,:)==0);
For the output format(the one that you want), i am sure you know what to do. Good luck.

data rearrangement in matlab

I have the following code
[X1,Y1]=meshgrid(1:5,1:5);
z=X1.^2+Y1.^2
[X2,Y2]=meshgrid([1 2 3 3.5 4 5],[1 2 3 3.5 4 5]);
z2=interp2(X1,Y1,z,X2,Y2)
mesh(X2,Y2,z2)
Is there any way to stucture data such as command mesh(z2) would produce the same result ?
I am not exactly sure what you are asking, but you could certainly cut out a few lines in your code to do the same thing:
[X2,Y2]=meshgrid([1 2 3 3.5 4 5],[1 2 3 3.5 4 5]);
z2=X2.^2+Y2.^2;
mesh(X2,Y2,z2);
Or, you could just do:
[X1,Y1]=meshgrid(1:5,1:5);
z=X1.^2+Y1.^2;
mesh(z);
For this particular example, I don't think you will see much of a difference between the two methods.