Suppose I have the following code
mc = {[2 5],[2 5],[8 9 2],[33 77 4],[102 6],[110 99],[2 5]}
(Identifying uniques in a cell array:Jonas Answer):
%# convert to strings
mcs = cellfun(#(x)(mat2str(x)),mc,'uniformoutput',false);
%# run unique
[uniqueCells,idxOfUnique,idxYouWant] = unique(mcs);
fileName = ['C:\Users\MATLAB\matrice_Result.mat'];
save(fileName,'uniqueCells');
to load the result and use it as a cell, Can I do that ?:
load('C:\Users\MATLAB\matrice_Result.mat');
A = uniqueCells;
B = [5 77 41 66 7];
(Finding the vectors of the cell A that contain at least one element of the vector B: Divakar Answer)
R = A(arrayfun(#(n) any(ismember(B,A{n})),1:numel(A)));
I have the impression that the second code does not recognize A !!!
Just use str2num(A{n}) to convert each cell of A back into numeric form:
R = A(arrayfun(#(n) any(ismember(B,str2num(A{n}))),1:numel(A)));
The above gives the result in string form, because A{n} is converted to numbers within ismember but A is left in string form. If you want the result in numeric form, first convert A and then apply your (Divakar's) original line to the converted A:
A_num = cellfun(#str2num, A, 'uniformoutput', 0);
R = A_num(arrayfun(#(n) any(ismember(B,A_num{n})),1:numel(A)));
Related
I have multiple array, number can be arbitrary. but the size of all array is same. How do i add each element of with respective element of all the arrays and maybe save it in another array
A1 = [1 2 3 4 5 6]
A2 = [1 2 3 4 5 6]
.
.
.
.
final = [1+1+1+... 2+2+2+.... 3+3+3+3.... 4+4+4.... 5+5+5+5... 6+6+6+6...]
As your arrays are all the same length you can just add the arrays forming a new array.
final = A1+A2
This function searches in your workspace looking for all variables containing capital 'A'. The for loop adds all found variables. If there are other variables containing 'A', other restrictions has to be made.
variables = who %# all variable names from workspace
index = strmatch('A',variables) %# indices matching "A"
newarray = 0
for j = 1:numel(index)
tmp = eval(char(variables(index(j)))); %# store variable in tmp
newarray = newarray + tmp; %# sum
end
If you have an unknown number of A's, you can try something like this:
final = 0
i = 1
while exist(['A' num2str(i)]) == 1 % ['A' num2str(i)] constructs the variable name, eval calls it
final = final + eval(['A' num2str(i)]);
i = i + 1;
end
This should work as long as the variables are stored in the workspace, are of the same length and are named A1, A2, A3, ... A9, A10, ...
Let's say you have this structure (as you write in the comments):
main = struct('err',{1:6,5:10,1:6,1:6},'seg_err',{1:6,5:10,1:6,5:10});
you can convert it to matrix:
m = vertcat(main.seg_err);;
And than take the sum in a simple command:
final = sum(m)
which results:
final =
12 16 20 24 28 32
and thanks to #beaker :)
So my main objective is to take a matrix of form
matrix = [a, 1; b, 2; c, 3]
and a list of identifiers in matrix[:,1]
list = [a; c]
and generate a new matrix
new_matrix = [a, 1;c, 3]
My problem is I need to import the data that would be used in 'matrix' from a tab-delimited text file. To get this data into Matlab I use the code:
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
which outputs a cell array of two 3x1 arrays. I want to get this into one 3x2 matrix where the first column is a character, and the second column an integer (these data formats will be different in my implementation).
So far I've tried the code:
matrix_1 = cell2mat(matrix(1,1));
matrix_2 = cell2mat(matrix(1,2));
matrix = horzcat(matrix_1, matrix_2)
but this is returning a 3x2 matrix where the second column is empty.
If I just use
cell2mat(matrix)
it says it can't do it because of the different data formats.
Thanks!
This is the help of matlab for the cell2mat function:
cell2mat Convert the contents of a cell array into a single matrix.
M = cell2mat(C) converts a multidimensional cell array with contents of
the same data type into a single matrix. The contents of C must be able
to concatenate into a hyperrectangle. Moreover, for each pair of
neighboring cells, the dimensions of the cell's contents must match,
excluding the dimension in which the cells are neighbors. This constraint
must hold true for neighboring cells along all of the cell array's
dimensions.
From what I understand the contents you want to put in a matrix should be of the same type otherwise why do you want a matrix? you could simply create a new cell array.
It's not possible to have a normal matrix with characters and numbers. That's why cell2mat won't work here. But you can store different datatypes in a cell-array. Use cellstr for the strings/characters and num2cell for the integers to convert the contents of matrix. If you have other datatypes, use an appropriate function for this step. Then assign them to the columns of an empty cell-array.
Here is the code:
fn_matrix = 'data.txt';
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
X = cell(size(matrix{1},1),2);
X(:,1) = cellstr(matrix{1});
X(:,2) = num2cell(matrix{2});
The result:
X =
'a' [1]
'b' [2]
'c' [3]
Now we can do the second part of the question. Extracting the entries where the letter matches with one of the list. Therefore you can use ismember and logical indexing like this:
list = ['a'; 'c'];
sel = ismember(X(:,1),list);
Y(:,1) = X(sel,1);
Y(:,2) = X(sel,2);
The result here:
Y =
'a' [1]
'c' [3]
Say, we have an array of structs
data = struct('position',[]);
data(1,1).position = 11;
data(1,2).position = 12;
data(2,1).position = 21;
data(2,2).position = 22;
I learned that to get the entries from a field from all structs in the array, we can use
>> [data.position]
ans =
11 21 12 22
But this gives the data in a row. How can we get it in the original shape of the array, without looping the array in MCode?
Desired output:
position =
11 12
21 22
Use reshape. This will restructure an input vector / matrix into another vector / matrix of a desired shape. Specifically, you can specify the dimensions of data into reshape as well as the row vector produced by [data.position] and it'll reshape the vector with the right dimensions for you.
data = struct('position',[]);
data(1,1).position = 11;
data(1,2).position = 12;
data(2,1).position = 21;
data(2,2).position = 22;
position = reshape([data.position], size(data))
position =
11 12
21 22
Note that the elements are shaped in column-major format so the values are stacked column-wise. As you can see, the first two elements become the first column of the output matrix, while the last two elements become the second column of the output matrix.
If you are working with empty entries, you can use struct2cell to convert the struct data into cell array that enables us to store empty entries as empty cells -
data_cell = permute(struct2cell(data),[2 3 1])
out = data_cell(:,:,strcmp(fieldnames(data),'position'))
So, if you have something like this with the (2,2) missing -
data = struct('position',[]);
data(1,1).position = 11;
data(1,2).position = 12;
data(2,1).position = 21;
You would have -
out =
[11] [12]
[21] []
Based on #CitizenInsane's nice observation and which might be very close to #rayryeng's answer, but one that deals with cell arrays instead of numeric arrays, would be this -
out = reshape({data.position}, size(data))
I have 64 characters in a 4*4 matrix.I need to convert it into a cell array such that cell has 4 characters.For eg
Consider A=[TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT]
i need to get a cell array as below
B={[TCTG][CTCT][CGGT][TATA]
[TACA][CTGC][CCAG][AACA]
[CGTC][AACA][AGGC][CAGT]
[GTAT][CCTT][CTTT][GTGT]}
i tried using the mat2cell function but im not able to understand it.please help.
Using a for-loop:
clc
clear
A = 'TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT';
B = cell(4,4);
currentIdx = 0; % Use index to increment by steps of 4 when going through A
for k = 1:16
B{k} = A(currentIdx+1:currentIdx+4);
currentIdx = currentIdx+4;
end
B = B'
B =
'TCTG' 'CTCT' 'CGGT' 'TATA'
'TACA' 'CTGC' 'CCAG' 'AACA'
'CGTC' 'AACA' 'AGGC' 'CAGT'
'GTAT' 'CCTT' 'CTTT' 'GTGT'
You are starting with a 1xN matrix and want to convert it to a 1xN/4 cell array of 1x4 matrices. Your command should then be:
N = length(A);
M = 4;
B = mat2cell(A,1,ones(1,N/M)*M);
The first dimension is the 1, the second dimension is a string of 4's the size of the output cell array. The result:
B =
Columns 1 through 12
'TCTG' 'CTCT' 'CGGT' 'TATA' 'TACA' 'CTGC' 'CCAG' 'AACA' 'CGTC' 'AACA' 'AGGC' 'CAGT'
Columns 13 through 16
'GTAT' 'CCTT' 'CTTT' 'GTGT'
You can use method vec2mat that breaks your input vector to matrix
M = vec2mat(A, numberOfColumns)
(In your case numberOfColumns would be 16) and then use mat2cell. In your case, it would be:
C = mat2cell(M, [1,1,1,1], [4,4,4,4])
It means that all cels will have one row and 4 columns).
Effect of function c = mat2cell(x, [10, 20, 30], [25, 25]) would be:
The image shows why you have to convert vector to matrix. (example from matlab documentation)
You can also (ab)use the very versatile accumarray for this task:
A = 'TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT';
n = 4;
B = accumarray(ceil(1/n:1/n:numel(A)/n).', A(:), [], #(x) {x.'}).'
I would like to compute the maximum and, more importantly, its coordinates of an N-by-N...by-N array, without specifying its dimensions.
For example, let's take:
A = [2 3];
B = [2 3; 3 4];
The function (lets call it MAXI) should return the following values for matrix A:
[fmax, coor] = MAXI(A)
fmax =
3
coor =
2
and for matrix B:
[fmax, coor] = MAXI(B)
fmax =
4
coor=
2 2
The main problem is not to develop a code that works for one class in particular, but to develop a code that as quickly as possible works for any input (with higher dimensions).
To find the absolute maximum, you'll have to convert your input matrix into a column vector first and find the linear index of the greatest element, and then convert it to the coordinates with ind2sub. This can be a little bit tricky though, because ind2sub requires specifying a known number of output variables. For that purpose we can employ cell arrays and comma-separated lists, like so:
[fmax, coor] = max(A(:));
if ismatrix(A)
C = cell(1:ndims(A));
[C{:}] = ind2sub(size(A), coor);
coor = cell2mat(C);
end
EDIT: I've added an additional if statement that checks if the input is a matrix or a vector, and in case of the latter it returns the linear index itself as is.
In a function, it looks like so:
function [fmax, coor] = maxi(x)
[fmax, coor] = max(A(:));
if ismatrix(A)
C = cell(1:ndims(A));
[C{:}] = ind2sub(size(A), coor);
coor = cell2mat(C);
end
Example
A = [2 3; 3 4];
[fmax, coor] = maxi(A)
fmax =
4
coor =
2 2