Permutation vectors from the CLUSTERGRAM object (MATLAB) - matlab

I'm using the CLUSTERGRAM object from the Bioinformatics Toolbox (ver 3.7).
MATLAB version R2011a.
I'd like to get permutation vectors for row and columns for clustergram, as I can do with dendrogram function:
x = magic(10);
>> [~,~,permrows] = dendrogram(linkage(x,'average','euc'))
permrows =
9 10 6 7 8 1 2 4 5 3
>> [~,~,permcols] = dendrogram(linkage(x','average','euc'))
permcols =
6 7 8 9 2 1 3 4 5 10
I found that the clustering is not the same from clustergram and dendrogram, most probably due to optimal leaf ordering calculation (I don't want to disable it).
For example, for clustergram from:
clustergram(x)
('average' and 'eucledian' are default methods for clustergram)
the vectors (as on the figure attached) should be:
permrows = [1 2 4 5 3 10 9 6 7 8];
permcols = [1 2 8 9 6 7 10 5 4 3];
So, how to get those vectors programmatically? Anybody well familiar with this object?
Do anyone can suggest a good alternative? I know I can create a similar figure combining imagesc and dendrogram functions, but leaf ordering is much better (optimal) in clustergram, than in dendrogram.

From looking at the documentation, I guess that get(gco,'ColumnLabels') and get(gco,'RowLabels'), where gco is the clustergram object, should give you the reordered labels. Note that the corresponding set-methods take in the labels in original order and internally reorders them.
Consequently, if you have used custom labels (set(gco,'RowLabels',originalLabels))
[~,permrows] = ismember(get(gco,'RowLabels'),originalLabels)
should return the row permutation.

Related

How do I populate dynamic arrays in Julia similar to Matlab

My understanding of programming languages is limited, I have started 'coding' with matlab and wanted to transfer a simulation of mine from matlab to julia because there is no licensing fee. What I would like to know is in MATLAB I can auto populate array without ever initializing an array, while I know it is an inefficient way to it, I would like to know if there is similar way to do it on Julia.
Ex in MATLAB
for a in 1:10
x(a)=a;
end
will give me an array x = [ 1 2 3 4 5 6 7 8 9 10], is there a similar way to do that in julia? The way I have been doing it is declaring an empty array using Float64[] and append to it but it doesn't work the same way if the array is multidimensional.
my implementation in Julia for a 1D array
x = Float64[]
for a in 1:10
append!(x,a)
end
Any help regarding this will be greatly appreciated. Thank you!!!
MATLAB explicitly warns against the way you write this code and advises to preallocate for speed.
Julia, OTOH, cares more about performance and prohibits such pattern from the beginning. At the same time, it allows for more convenient and fast alternatives to do the same task.
julia> x = [a for a = 1:10] # OR x = [1:10;]
10-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
and for 2D arrays,
julia> x = [i+j-1 for i = 1:5, j = 1:5] # OR x = (1:5) .+ (1:5)' .- 1
5×5 Matrix{Int64}:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
And you have other convenience functions, like zeros(m,n), fill(val, dims), rand(Type, dims), etc., that you can use to initialize the arrays however you want.
Although #AboAmmar is correct that this generally isn't a good pattern, your code works if you use push! instead of append!. push! adds an element to a vector. append appends 2 vectors.

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: 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.

Set x-axis to non-monotonic values and avoid scaling

I use matlab to plot a graph where instead of having x-axis increase monotonically, I have my own values. eg 5 14 8 9 12 7 etc.I use set (gca,'XTickLabel',num2str(mydata)) which generally works. However, when mydata is more than four or five digits, Matlab scales the graph and thus x-axis values no longer correspond to their intended points. Any ideas on how to prevent this scaling? To clarify, when I make the figure larger, it shows the plot as it should.
The problem is in your num2str() conversion:
mydata = 1:10;
num2str(mydata)
ans =
1 2 3 4 5 6 7 8 9 10
This means, that each tick will be labelled with this long 1 by n char array. The axes will then be resized to fit the labels inside the figure.
A solution is to create one label per row of a char array:
reshape(sprintf('%2d',mydata),2,[])'
ans =
1
2
3
4
5
6
7
8
9
10
Sort of solution is to write set(gca,'xtick',1:myDataVectorLength) before set (gca,'XTickLabel',num2str(mydata))