MATLAB - hierarchy clustering upon two data sets - matlab

I have two data sets (characteristic_1, characteristic_2) corresponding to five objects (each). Every object has tree attributes, att1, att2, att3.
So for characteristic_1, the matrix is:
d= [ 1 1 0; 1.1 1 2; 0.9 0.2 1; 1.2 0.8 1.3; 1 1 1]
and for characteristic_2, the matrix is:
e= [ 1.1 1 0; 1 1 2; 0.7 0.2 1.1; 1.2 0.8 1.3; 1.3 1 1]
I want to use the hierarchy method (i.e. single linkage), in order to cluster characteristic_1 & 2 (between them). The 5 objects, as well as the 3 attributes, are common in the two characteristics.
Thanks in advance.

Related

Interpolating matrices with 2 variables and 1 dependent value

I'm analyzing an induction motor, varying the frequency and absolute value of the stator current. Since the FEM-Tool only works with a current input, I need to vary the current over the frequency to obtain current-values of constant torque for each frequency.
To generate a mesh, I use 2 for-loops:
The outer loop sets the current.
The inner loop varies the frequency with said current, gets the machine's torque and finally, the matrices are appended adding the current stator-current, frequency and torque each in separate matrices. Plotted it looks like this:
Example of the plot using the raw data
For the plot I used smaller, more imprecise matrices and rather arbitrary values:
I_S = [ 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 ];
fre = [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ];
tor = [ 0 0.1 0.3 0.5 0.7 1 1.5 2 2.6 3.3 0 1.1 1.3 1.5 1.7 2 2.5 3 3.6 4.3 0 2.1 2.3 2.5 2.7 3 3.5 4 4.6 5.3 ];
While tor is shown as the colormap in the plot. Each matrix has a length of 30.
One simulation needs about 20-30 seconds. Thus, to get a precise mesh, the FEM-tool needs several hours to generate.
I would like to interpolate the spaces in between the known ones.
It seems that either the way of creating the matrices is the problem or the interp*...-functions of Octave/MATLAB simply don't work for this kind of interpolation.
Is there a way to achieve a mesh/grid-like interpolation from this type of matrices? I found many examples with x,y as variables and z as a math-function but rarely 3 linear/non-linear matrices.
Your data need to be in a meshgrid form, that is 2D:
// Known data
current = [0:2];
frequency = [0:9];
[current2D, frequency2D] = meshgrid(current,frequency);
torque2D = [ 0 0.1 0.3; 0.5 0.7 1; 1.5 2 2.6; 3.3 0 1.1; 1.3 1.5 1.7; 2 2.5 3; 3.6 4.3 0; 2.1 2.3 2.5; 2.7 3 3.5; 4 4.6 5.3 ];
// Interpolated data
currentToInterpolate = [0.5 1.5];
frequncyToInterpolate = [0.5 : 8.5];
[currentToInterpolate2D, frequencyToInterpolate2D] = meshgrid(currentToInterpolate,frequncyToInterpolate);
interpolatedTorque2D = interp2(current2D,frequency2D,torque2D,currentToInterpolate2D,frequencyToInterpolate2D);

How to find value from matrix

Let say I have a matrix
A=[0.8 0.9 0.7 0.5 0.3 0.8 0.2 0.1]; % 8 points
where A come from logical 1 from B
B=[1 0 1 0 0 1 0 1 0 1 1 0 1 1];
As I want to find location C that satisfies
C=find(A<0.6 & A>0.35)
where the ans is C=4. My question is how to get the true location in B=8?
Unless you do not have the indices stored away somewhere, I cannot see that you have much of a choice here.
tmp = find(B);
idx = tmp(C);
In case you actually want to use this mapping more than once, I would suggest that you store the indices instead of a binary vector. This will also be more memory efficient in case the binary vector is sparse (or not a boolean vector), since you will need less entries.
In case you also need the binary vector, you should store both in case memory allows. When I have done this kind of mapping in Matlab I have actually used both a binary vector (a mask) and an index vector. This have saved me from first mapping the mask to index and then index to filtered position (so to say, skipping the tmp = find(B); idx = tmp(C); part every time and go directly to idx = allIdx(C)).
This will get you the index in B
A=[0.8 0.9 0.7 0.5 0.3 0.8 0.2 0.1];
B=[1 0 1 0 0 1 0 1 0 1 1 0 1 1];
C=find(A<0.6 & A>0.35);
temp=0;
for i=1:size(B,2)
temp=temp+B(i);
if(temp==C)
break;
end
end
locationB=i;
locationB

Calling text file

if i have text file that has three column say
1 2 1
3 1 1
2 3 1
and also have a matrix s =
[0.3 0.4 0.6
0.1 0.5 0.7
0.2 0.11 0.9]
firstly:
with respect to text file, i want to consider first column as i and second column as j then if the third column equal 1 then put its corresponding value in matrix s in new array say A else put remaining value in matrix s in new another array say B.
i.e i want this result
A=[0.4, 0.2, 0.7] B=[0.3, 0.6, 0.1, 0.5, 0.11, 0.9]
coordinates = [1 2 1
3 1 1
2 3 1];
s = [0.3 0.4 0.6
0.1 0.5 0.7
0.2 0.11 0.9];
linindices = sub2ind(size(s), coordinates(:, 1), coordinates(:, 2))';
A = s(linindices)
B = s(setdiff(1:numel(s), linindices))

changing multiple columns of a matrix with respect to sorted indices of its specific columns

Let's say I have a 2 by 9 matrix. I want to replace the 2 by 3 matrices inside this matrix with respect to descending sort of a(2,3), a(2,6), and a(2,9) elements. For example:
a =
0.4 0.4 0.5 0.6 0.2 0.2 0.6 0.2 0.6
0.5 0.8 0.9 0.9 0.6 0.6 0.1 0.2 0.8
[b i] = sort(a(2,3:3:end),2,'descend')
b =
0.9 0.8 0.6
i =
1 3 2
So, I want to have the following matrix:
a =
0.4 0.4 0.5 0.6 0.2 0.6 0.6 0.2 0.6
0.5 0.8 0.9 0.1 0.2 0.8 0.9 0.6 0.6
Try converting to a cell matrix first and then using your i to rearrange the cells
[b i] = sort(a(2,3:3:end),2,'descend')
A = mat2cell(a, 2, 3*ones(1,3));
cell2mat(A(i))
If for whatever reason you don't want to convert the whole of a into a cell matrix, you can do it by extending your indexing vector i to index all the columns. In your case you'd need:
I = [1,2,3,7,8,9,4,5,6]
which you could generate using a loop or else use bsxfun to get
[1 7 4
2 8 5
3 9 6]
and then "flatten" using reshape:
I = reshape(bsxfun(#plus, 3*s-2, (0:2)'), 1, [])
and then finally
a(:,I)
Typically, when a 2d matrix is separated into blocks, best practice ist to use more dimensions:
a=reshape(a,size(a,1),3,[]);
Now you can access each block via a(:,:,1)
To sort use:
[~,idx]=sort(a(2,3,:),'descend')
a=a(:,:,idx)
If you really need a 2d matrix, change back:
a=reshape(a,2,[])
sortrows-based approach:
n = 3; %// number of columns per block
m = size(a,1);
a = reshape(sortrows(reshape(a, m*n, []).', -m*n).', m, []);
This works by reshaping each block into a row, sorting rows according to last column, and reshaping back.

How to sum rows of submatrices in Matlab?

Summary
I have a working that solves my problem as described below, but would like to improve on it by eliminating the loop.
Description
I have a matrix B in Matlab of dimension (2*5)x3which is a concatenation of 2 matrices of 5 rows and where the ikth element reports an index from {1,2,3,4,5}(breaks added for clarity) . The indices can be repeated across rows. For each submatrix of dimension 5x3 of B the listed indices and the order in which they are listed coincide.
B=[0.1 0.2 |1;
0.3 0.4 |2;
0.5 0.6 |2;
0.7 0.8 |3;
0.9 1.1 |1;
---------
1.2 1.3 |1;
1.4 1.5 |2;
1.6 1.7 |2;
1.8 1.9 |3;
2.1 2.2 |1;]
Inside each submatrix of dimension 5x3 of B I would like to sum the rows with same index and get
C = [1 1.3 |1;
0.8 1 |2;
0.7 0.8 |3;
---------
3.3 3.5 |1;
3 3.2 |2;
1.8 1.9 |3;]
without looping.
What have I tried
My incomplete, but working, attempt with one loop:
D = permute(reshape(B,5,2,[]),[1 3 2]);
sum=zeros(3,2,2);
for i=1:2
E=D(:,:,i);
[b,c] = size(E);
rows = ceil(1/(c-1):1/(c-1):b);
cols = repmat(1:c-1,1,b);
sum(:,:,i) = full(sparse(E(rows,end), cols, E(:,1:end-1).'));
end