Getting the eigenvalues in a list from a list of matrices - matlab

I want my code to prompt the user for a list of eigenvalues, run through every possible 0,1 matrix with that number of vertices, create a list of all possible eigenvalues, and if any match what the user puts in, it returns the corresponding matrix. Got stuck here where it won't iterate correctly:
prompt='How many eigenvalues: ';
x=input(prompt);
prompt2='Enter Eignevalues: ';
y=input(prompt2,'s');
combs=dec2base(0:power(2,x*x)-1,2)-'0';
combs_matshaped=reshape(permute(combs,[3 2 1]),x,x,[]);
for l=combs_matshaped
disp(eig(l))
end
Any ideas on how to structure the for loop?

1-you need to prompt the user for a tolerance as well.
2-round off the eig(l) by the tolerance
3-test if the given values belong to the rounded set through ismember
something like ismember(str2num(prompt2),round(eig(l),tol))
EDIT
To generate a M by N binary matrix , use Mat = randi([0 1], M, N)

Related

Retrieve a specific permutation without storing all possible permutations in Matlab

I am working on 2D rectangular packing. In order to minimize the length of the infinite sheet (Width is constant) by changing the order in which parts are placed. For example, we could place 11 parts in 11! ways.
I could label those parts and save all possible permutations using perms function and run it one by one, but I need a large amount of memory even for 11 parts. I'd like to be able to do it for around 1000 parts.
Luckily, I don't need every possible sequence. I would like to index each permutation to a number. Test a random sequence and then use GA to converge the results to find the optimal sequence.
Therefore, I need a function which gives a specific permutation value when run for any number of times unlike randperm function.
For example, function(5,6) should always return say [1 4 3 2 5 6] for 6 parts. I don't need the sequences in a specific order, but the function should give the same sequence for same index. and also for some other index, the sequence should not be same as this one.
So far, I have used randperm function to generate random sequence for around 2000 iterations and finding a best sequence out of it by comparing length, but this works only for few number of parts. Also using randperm may result in repeated sequence instead of unique sequence.
Here's a picture of what I have done.
I can't save the outputs of randperm because I won't have a searchable function space. I don't want to find the length of the sheet for all sequences. I only need do it for certain sequence identified by certain index determined by genetic algorithm. If I use randperm, I won't have the sequence for all indexes (even though I only need some of them).
For example, take some function, 'y = f(x)', in the range [0,10] say. For each value of x, I get a y. Here y is my sheet length. x is the index of permutation. For any x, I find its sequence (the specific permutation) and then its corresponding sheet length. Based on the results of some random values of x, GA will generate me a new list of x to find a more optimal y.
I need a function that duplicates perms, (I guess perms are following the same order of permutations each time it is run because perms(1:4) will yield same results when run any number of times) without actually storing the values.
Is there a way to write the function? If not, then how do i solve my problem?
Edit (how i approached the problem):
In Genetic Algorithm, you need to crossover parents(permutations), But if you crossover permutations, you will get the numbers repeated. for eg:- crossing over 1 2 3 4 with 3 2 1 4 may result something like 3 2 3 4. Therefore, to avoid repetition, i thought of indexing each parent to a number and then convert the number to binary form and then crossover the binary indices to get a new binary number then convert it back to decimal and find its specific permutation. But then later on, i discovered i could just use ordered crossover of the permutations itself instead of crossing over their indices.
More details on Ordered Crossover could be found here
Below are two functions that together will generate permutations in lexographical order and return the nth permutation
For example, I can call
nth_permutation(5, [1 2 3 4])
And the output will be [1 4 2 3]
Intuitively, how long this method takes is linear in n. The size of the set doesn't matter. I benchmarked nth_permutations(n, 1:1000) averaged over 100 iterations and got the following graph
So timewise it seems okay.
function [permutation] = nth_permutation(n, set)
%%NTH_PERMUTATION Generates n permutations of set in lexographical order and
%%outputs the last one
%% set is a 1 by m matrix
set = sort(set);
permutation = set; %First permutation
for ii=2:n
permutation = next_permute(permutation);
end
end
function [p] = next_permute(p)
%Following algorithm from https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
%Find the largest index k such that p[k] < p[k+1]
larger = p(1:end-1) < p(2:end);
k = max(find(larger));
%If no such index exists, the permutation is the last permutation.
if isempty(k)
display('Last permutation reached');
return
end
%Find the largest index l greater than k such that p[k] < p[l].
larger = [false(1, k) p(k+1:end) > p(k)];
l = max(find(larger));
%Swap the value of p[k] with that of p[l].
p([k, l]) = p([l, k]);
%Reverse the sequence from p[k + 1] up to and including the final element p[n].
p(k+1:end) = p(end:-1:k+1);
end

Creating all possible combination of rows in matlab

I have a matrix which is 9x10000 size.
So rows are R1, R2, upto R9.
I want to generate all possible combination of the rows such as
[R1;R2] [R1;R3].. [R1;R9]
[R1;R2;R3]...[R1;R2;R4]... [R1;R2:R3;R4;..R8]
I am currently doing this using for loops.
Is there any better way of doing this.
Basically, counting up the binary from 1 to 2^9-i indicates which rows need to be selected:
M=... your matrix
S=dec2bin(1:2^size(M,1)-1)=='1';
allSubsets=cell(size(S,1),1);
for ix=1:size(S,1)
allSubsets{ix}=M(find(S(ix,:)),:);
end
As in the comment, I'm not sure if you always want the first row. This code doesn't do that, but you can modify it for that easily enough. It still uses for loops, but relies on the "nchoosek" function for the row index generation.
%generate data matrix
nMax=9; %number of rows
M=rand(nMax,1e4); %the data
%cell array of matrices with row combinations
select=cell(2^nMax-nMax-1,1); %ignore singletons, empty set
%for loop to generate the row selections
idx=0;
for i=2:nMax
%I is the matrix of row selections
I=nchoosek(1:nMax,i);
%step through the row selections and form the new matrices
for j=1:size(I,1)
idx=idx+1; %idx tracks number of entries
select{idx}=M(I(j,:),:); %select{idx} is the new matrix with selected rows
%per Floris' comment above you could do
%select{idx}=I(j,:); %save the selection for later
end
end
The function nchoosek, when given a vector, will return all possible ways to choose k values from that vector. You can trick it into giving you what you want with
allCombis = unique(nchoosek([zeros(1,9) 1:9], 9), 'rows');
This will include all possible ways to select 9 values from the set that includes nine zeros, plus the indices of each of the rows. Now you have every possible combination (including "no row at all"). With this matrix generated just once, you can find any combination easily - without having to store them all in memory. You can now pick you combination:
thisNumber = 49; % pick any combination
rows = allCombis(thisNumber, :);
rows(rows==0)=[]; % get rid of the zeros
thisCombination = myMatrix(rows, :); % pick just the rows corresponding to this combination

Generating all possible combinations for selecting a particular number of rows in a large matrix

I would like to generate all possible combinations for selecting rows in batches of lets say 'k' size. For example, matrix A has 3 rows and I want all combinations for batch size 2, i.e. rows (1,2)(1,3)(2,3). What would be the simplest way to do it? Then I would like use them for some operation like myfunction();
I think nchoosek function does the trick of selecting the combination but then how can I use each row of the output from nchoosek as index for my matrix?
If you want to use each combination one by one you can do something like this:
A = rand(3);
comb = nchoosek(length(A), 2);
for i = 1:size(comb, 1)
myfunction(A(comb(i, :), :));
end
A(comb(i, :)) is a k x n matrix (here 3 x 2) corresponding to the i-th combination of rows.

MATLAB Tree Construction

Now, I have separate any pair that is in common between the two input files. Find out the mean between that pair like this : (correlation in first text file)X(correlation in second text file)/ (correlation in first text file)+(correlation in second text file). Again store these in a separate matrix.
Building a tree :
Now, out of all the elements in both the input files, select the 10 most frequent ones. Each of these form the root of a separate K tree.The algorithm goes like this : For the word at the root level, check all its harmonic mean values with the other tags in the matrix that is developed in the previous step. Select the top two highest harmonic means, and put the other word in the tag pair as the child node of the root.
Can someone please guide me through the MATLAB steps of going through this? Thank you for your time.
Okay, so start by putting the data in a useful format; maybe count the number of distinct words, and make an N-by-M matrix of binary values (I'll call this data1). Each of the N rows will describe the words associated with a single image. Each of the M columns will descibe the images for which a single word is tagged. Therefore, the value at (N, M) is 0 if tag M is not in image N, and 1 if it is.
From this matrix, to find correlation between all pairs of words, you could do:
correlations1 = zeros(M, M);
for i=1:M
for j=1:M
correlations1(i, j) = corr(data1(:, i), data1(:, j));
end
end
now the matrix correlations tells you the correlation between tags. Do the same for the other text file. You can make a matrix of harmonic means with:
h_means = correlations1.*correlations2./(correlations1+correlations2);
You can find the 30 most freqent tags by counting the number of 1s in each column of the data matrix. Since we want to find the most common tags in both files, we'll add the data matricies first:
[~, tag_ranks] = sort(sum(data1 + data2, 1), 'descending'); %get the indices in sorted order
top_tags = tag_ranks(1:30);
For the tree building at the end, you will either want to create a tree class (see classdef), or store the tree in an array. To find the top two highest harmonic means, you will want to look in the h_means matrix; for a tag m1, we can do:
[~, tag_ranks] = sort(h_means(m1, :), 'descending');
top_tag = tag_ranks(1);
second_tag = tag_ranks(2);
You will then need to insert these tags into the tree and repeat.

Randomly select subset of all possible combinations in Matlab?

I need to select random combinations of k elements from a set of n elements, where n can be fairly large. Given the size of the set, it is not feasible to simply use combnk or nchoosek to generate all possible combinations, and select randomly from those.
Is there an easy way to generate a unique random subset of M of those combinations?
When n is small, the following works:
M = 20; %want to pick M random combinations
n = 10; %number of elements
k = 5; %number of elements in each combination
allCombos = nchoosek([1:n], k); %for large n this is not feasible
numCombos = nchoosek(n,k);
permutationsToUse = randperm(numCombos, M);
randomCombos = allCombos(permutationsToUse, :);
When n is large, this is no longer feasible.
Related Posts
Retrieve a specific permutation without storing all possible permutations in Matlab
How to randomly pick a number of combinations from all the combinations efficiently?
Select a subset of combinations
You can try using randi and generate random combinations of 7 integers from 1 to Nelements and then check that you only have unique combinations:
Nelements=100;
M=10;
combsubset=randi(Nelements,[M 7]);
combsubset=unique(combsubset,'rows');
If you want to get exactly M combinations you can use a loop:
Nelements=100;
M=10;
combsubset=[];
while(size(combsubset,1)<M)
combsubset=[combsubset;randi(Nelements,[M 7])];
combsubset=unique(combsubset,'rows');
end
combsusbet=combsubset(1:M,:);
If you want to reuse this to get other combinations you can pretty much use the same code:
Nelements=100;
Mtotal=20
M=10;
while(size(combsubset,1)<Mtotal)
combsubset=[combsubset;randi(Nelements,[M 7])];
combsubset=unique(combsubset,'rows');
end
combsusbet=combsubset(1:Mtotal,:);
EDIT: Another method for your needs would be to order the combinations to be able to get only a given subset. One method to order them can be explained with the following example: if you have three indices i,j,k ranging from 0 to N-1 you can use a unique index n=i*N*N+j*N+k to go over all the possibilities. Then if you want to get the nth vector:
k=mod(n,N);
j=mod((n-k)/N,N);
i=mod((((n-k)/N)-j)/N,N);
I do not know if you will find this more elegant but with the help of a little function that uses recursion you could easily get a fixed subset of your combinations.