extract the unique blocks from matrix using Mean Square Error matlab - 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.

Related

Finding the rows of a matrix with specified elements

I want to find the rows of a matrix which contain specified element of another matrix.
For example, a=[1 2 3 4 5 6 7] and b=[1 2 0 4;0 9 10 11;3 1 2 12]. Now, I want to find the rows of b which contain at least three element of a. For this purpose, I used bsxfun command as following:
c=find(sum(any(bsxfun(#eq, b, reshape(a,1,1,[])), 2), 3)>=3);
It works good for low dimension matrices but when I want to use this for high dimension matrices, for example, when the number of rows of b is 192799, MATLAB gives following error:
Requested 192799x4x48854 (35.1GB) array exceeds maximum array size preference.
Creation of arrays greater than this limit may take a long time and cause MATLAB
to become unresponsive. See array size limit or preference panel for more information.
Is there any other command which does this task without producing the behaviour like above for high dimension matrices?
a possible solution:
a=[1 2 3 4 5 6 7]
b=[1 2 0 4;0 9 10 11;3 1 2 12]
i=ismember(b,a)
idx = sum(i,2)
idx = find(idx>=3)

Genetic Algorithm for Flow shop Scheduling

I need help in Matlab: I need to find out how to Crossover any two sequences for genetic alghorithm in FlowShop, e.g.
1st sequence = 1 5 4 7 3 2 9 8 10 6
2nd sequence = 7 8 9 10 5 4 2 1 3 6
after crossover, the off-springs should be
offspring 1 = 1 5 4 7 3 2 8 9 10 6
offspring 2 = 7 8 9 10 1 5 4 3 2 6
Crossover should be such that each number doesn't repeat itself in the offspring sequence. Can anyone tell me how to do this?
There are a number of existing crossovers defined for permutation encodings. Among them the following would be useful for you:
Cyclic Crossover
Partially Matched Crossover
Uniform-like Crossover
Position-based Crossover
These crossovers aim to preserve the position of the job in the permutation. You can find implementations in C# in the PermutationEncoding plugin of HeuristicLab. Browse the source files and you can also find references to scientific articles that describe these crossovers.

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.

MATLAB: Step through iterations of a vector

all.
I have a 15 element array = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15];.
I was wondering if there was a command such that it would step through iterations of the array without repeating itself. In other words, since there is a chance that randperm() will create the same matrix twice, I want to step through each permutation only once and perform a calculation.
I concede that there are factorial(15) permutations, but for my purposes, these two vectors (and similar) are identical and don't need to be counted twice:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
Thus, is there any way to step through this?
Thanks.
I think what you are looking for is perms. randperm returns a single random permutation, you want all the permutations.
So use
my_permuations = perms([1:15]);
If forward-backward is the same as backward-foward then you can use the top half of the list only...
my_permutation_to_use = my_permutations(1:length(my_permutations)/2, :);
You may compare all permutations, but this would require to store all past permutations. Instead a local decision is better. I recommend this simple rule:
A permutation is valid, if the first element is smaller than the last element.
A permutation is redundant, if the first element is larger than the last element.
For small sizes, this could simply be done with this code:
%generate all permutations
x=perms(1:10)
%select only the valid lines, remove all redundant lines
x(x(:,1)<x(:,end),:)
Remains the problem, that generating x for 1:15 breaks all memory limits and would require about 100h.

How can I flatten every n rows in matrix using Matlab?

I can easily flatten an entire matrix into one row using reshape(M,1,[]). However, this time I want to flatten every n rows into one row. Thus, if we start with 100 rows and n=10, we will end up with 10 rows.
e.g.
1 2 3
4 5 6
7 8 9
10 11 12
with n=2 changes into
1 2 3 4 5 6
7 8 9 10 11 12
Is there a simple way to do this?
Suppose your original matrix is m, then:
reshape(m',[6 2])'
produces the required output. I'll leave it to you to generalise to other cases; comment or post again if that causes you problems.
This should work.
reshape(M',l/n,n)'
Where n is what you've defined and l is the total elements in M.
EDIT: Made it one-liner