Calling text file - matlab

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))

Related

How to select the average value from 3 matrices

I am new to MATLAB and I need help. I have 3 matrices (A, B, and C) and I want to create a new matrix average_ABC that contains average values.
A = [ 0.3 0.5 0.9
0.14 0.36 0.1
0.9 0.5 0.14]
B = [ 0.8 0.9 0.14
0.1 0.25 0.4
0.8 0.14 0.25]
C = [0.25 0.3 0.47
0.12 0.3 0.2
0.14 0.56 0.9]
The resulting matrix will be
average_matrix = [ 0.3 0.5 0.47
0.12 0.25 0.2
0.8 0.5 0.25]
Please, any suggestion, how can I do it?
You can first concatenate your matrices along the third dimension (using cat) and then compute whatever you want using the dim parameter that is available for most functions to specify that you want to perform that operation along the third dimension.
Also you've stated that you want the average (mean), but based on your example you actually want the median. Either way, we can compute them using this method.
data = cat(3, A, B, C);
% Compute the mean
mean(data, 3)
% 0.45 0.56667 0.50333
% 0.12 0.30333 0.23333
% 0.61333 0.4 0.43
% Compute the median (which seems to be what you actually want)
median(data, 3)
% 0.3 0.5 0.47
% 0.12 0.3 0.2
% 0.8 0.5 0.25
I hope this will work
average_matrix=(A+B+C)/3.;

Create matrices from a given cell-array of strings with different lengths

I have 3 sequences in a cell-array:
Input_cell= {'ABCD','ACD', 'ABD'}
S1= 'ABCD' % which means A<B<C<D
S2= 'ACD' % which means A<C<D % missing B in the full string of 'ABCD'
S3= 'ABD' % which means A<B<D % missing C in the full string of 'ABCD'
I want to convert each of the strings in the Input_cell into a matrix M (i-by-j) which has to satisfy these conditions:
M(i,j) and M(j,i) are random
M(i,i) = 0.5
M(i,j) + M(j,i) = 1
M(i,j) < M(j,i) For example if A<B then M(A,B) < M(B,A)
For example if we have S1 = 'ABCD' (which means A<B<C<D), the M1 matrix will be expected as follows:
A B C D
A 0.5 0.3 0.2 0.1
B 0.7 0.5 0 0.4
C 0.8 1 0.5 0.1
D 0.9 0.6 0.9 0.5
If we have S2 = 'ACD' (which means A<C<D), missing B in the full string of 'ABCD', we will put the value 0.5 in every position of B in the matrix, the M2 matrix will be expected as follows:
A B C D
A 0.5 0.5 0.2 0.1
B 0.5 0.5 0.5 0.5
C 0.8 0.5 0.5 0.1
D 0.9 0.5 0.9 0.5
If we have S3 = 'ABD' (which means A<B<D), missing C in the full string of 'ABCD', we will put the value 0.5 in every position of C in the matrix, the M3 matrix will be expected as follows:
A B C D
A 0.5 0.4 0.5 0.1
B 0.6 0.5 0.5 0.3
C 0.5 0.5 0.5 0.5
D 0.9 0.7 0.5 0.5
How to create that kind of above matrices from a given cell-array of sequences?
Firstly you need to work out how to do this just for a single sequence:
Create a matrix of random numbers between 0.5 and 1:
M = 0.5*rand(4) + 0.5;
Set the main diagonal to equal 0.5
M(logical(eye(4))) = 0.5;
Set the upper triangle of M equal to 1 - the lower triangle:
M(triu(true(4))) = 1 - M(tril(true(4))); %// Note the main diagonal doesn't matter...
Work out which letter is missing and set the row and column equal to 0.5 accordingly:
fullSeq = 'abcd';
idx = find(fullSeq == setdiff(fullSeq, 'abd'));
%// at this point you'll need to check if idx is empty first...
M(:,idx) = 0.5;
M(idx,:) = 0.5;
And now that you can do it for one matrix, just loop over your cell array or else encapsulate this into a function and use cellfun.

how can transform a matrix matlab into file .txt?

I have a matrix proba (size :10 * 5).
proba=[0.5 0.3 0.8 0.9 0.8;
0.50 0.36 0.58 0.58 0.98;
0.1 0.25 0.6 0.8 0.9;
0.5 0.3 0.8 0.9 0.8;
0.2 0.9 0.58 0.58 0.69;
0.58 0.14 0.1 0.2 0.3;
0.25 0.9 0.8 0.7 0.5;
0.58 0.69 0.25 0.1 0.1;
0.1 0.25 0.36 0.2 0.3;
0.5 0.3 0.8 0.9 0.8 ];
I want to transform this matrix into a text file (proba.txt) with which the index column is written and the value of the column for each line as follows :
1 0.5 2 0.3 3 0.8 4 0.9 5 0.8
1 0.50 2 0.36 3 0.58 4 0.58 5 0.98
.
.
.
1 0.5 2 0.3 3 0.8 4 0.9 5 0.8
Please I need help, how can I do it?thanks in advance
You can use this function, it is useful for every matrix.
function data = addIndex(X)
[r, c] = size(X);
index = ones(r, 1);
data = zeros(r, 2 * c);
for i = 1:c
data(:, 2 * i - 1) = i .* index;
data(:, 2 * i) = X(:, i);
end
dlmwrite('proba.txt', data, '\t')
end
you can easily do this using dlmwrite, but first you want to add the column of indexes in front of your matrix:
function result = writematrix(proba)
rowind = 1:size(proba,2);
for t = 1:size(proba,1);
C(t,:,:) = [rowind',proba(t,:)']';
D(t,:) = C(t(:),:);
end
dlmwrite('filename.txt',D,'\t') %//I assume you want tab delimiter, if you want space, it is ' ' instead
%//dlmwrite('filename.txt',D,' ')
end
Note that this will write the text file into your local directory, and that it only works for numerical values, not strings, for strings, it is better to use csvwrite.
EDIT : Ops, didn't read the question fully, this should now work fine.

reshape matrix in matlab

I don't see the bug anymore...maybe (very probably :-) ) there's even a much more easier and faster way of doing it...
I summarized the important columns of my huge data frame in a little expData (see below).
The problem is actually quite easy, but I'm just blind for the easy idea of solving it..
My objective is to reshape columns b,c,d into one column that expData afterwards looks like expData2.
I would be really happy, if someone could help me out.
My code so far:
a = [1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5]';
b = [0.3 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9]';
c = [0.4 0.4 0.4 0.4 0.4 0.6 0.6 0.6 0.6 0.6 0.8 0.8 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9 0.1 0.1 0.1 0.1 0.1]';
d = [0.5 0.5 0.5 0.5 0.5 0.1 0.1 0.1 0.1 0.1 0.7 0.7 0.7 0.7 0.7 0.2 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.3]';
e = rand(25,1);
f = rand(25,1);
a2 = [2 3 4 2 3 4 2 3 4 2 3 4 2 3 4]';
b2 = [0.3 0.4 0.5 0.4 0.6 0.1 0.5 0.8 0.7 0.8 0.9 0.2 0.9 0.1 0.3]';
c2 = rand(15,1);
d2 = rand(15,1);
expData = horzcat(a,b,c,d,e,f);
expData2 = horzcat(a2,b2,c2,d2); % for explanation of my objective
k = horzcat(expData(:,2),expData(:,3),expData(:,4))'; % How I wanted to do it
expData(:,2:4) = [];
k = reshape(k,[],1);
for index = 1:size(expData,1)
if expData(index,1) == 1
expData(index,:) = [];
end
if expData(index,1) == 5
expData(index,:) = [];
end
end
k = k(1:size(expData,1),:);
expData2 = [expData k];
Your current code throws an error, since the number of loop iterations gets determined at the beginning of the loop. As you are removing rows of expData, you run out of rows to index at some point.
The quick fix would be to start looping from the back, i.e. use for index = size(expData,1):-1:1. This way, you can safely remove rows without running into indexing problems.
The elegant fix is to use ismember to identify rows to remove:
rows2remove = ismember(expData(:,1),[1 5]);
expDate(rows2remove,:) = [];

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.