I have a 10 x 10 struct with four fields a,b,c,d.
How do I convert this struct to a 10 x 10 matrix with entries only from the field a?
You can rely on the fact that str.a returns a comma-separated list. We can therefore concatenate the values together and reshape the resulting array to be the same size as the input struct.
% If a contains scalars
out = reshape([str.a], size(str));
% If a contains matrices
out = reshape({str.a}, size(str));
One liner solution
res = cellfun(#(strctObj) strctObj.a,str,'UniformOutput',false);
Further explanation
Define a one-line function which extract the a value.
getAFunc = #(strctObj) strctObj.a;
use MATLAB's cellfun function to apply it on your cell and extract the matrix:
res = cellfun(#(strctObj) getAFunc ,strctCellObj,'UniformOutput',false);
Example
%initializes input
N=10;
str = cell(N,N);
for t=1:N*N
str{t}.a = rand;
str{t}.b = rand;
str{t}.c = rand;
str{t}.d = rand;
end
%extracts output matrix
res = cellfun(#(strctObj) strctObj.a,str,'UniformOutput',false);
Related
I have a structure 1x300 called struct with 3 fields but I'm using only the third field called way. This field is, for each 300 lines, a vertor of index.
Here an exemple with 3 lines to explain my problem : I woud like to search if the last index of the first line is present in an other vector (line) of the field way.
way
[491751 491750 491749 492772 493795 494819 495843 496867]
[491753 491754 491755 491756]
[492776 493800 494823 495847 496867]
I tried with intersect function :
Inter=intersect(struct(1).way(end), struct.way);
but Matlab returns me an error :
Error using intersect (line 80)
Too many input arguments.
Error in file2 (line 9)
Inter=intersect(struct(1).way(end), struct.way);
I don't understand why I have this error. Any explanations and/or other(s) solution(s)?
Let the data be defined as
st(1).way = [491751 491750 491749 492772 493795 494819 495843 496867];
st(2).way = [491753 491754 491755 491756];
st(3).way = [492776 493800 494823 495847 496867]; % define the data
sought = st(1).way(end);
If you want to know which vectors contain the desired value: pack all vectors into a cell array and pass that to cellfun with an anonymous function as follows:
ind = cellfun(#(x) ismember(sought, x), {st.way});
This gives:
ind =
1×3 logical array
1 0 1
If you want to know for each vector the indices of the matching: modify the anonymous function to output a cell with the indices:
ind = cellfun(#(x) {find(x==sought)}, {st.way});
or equivalently
ind = cellfun(#(x) find(x==sought), {st.way}, 'UniformOutput', false);
The result is:
ind =
1×3 cell array
[8] [1×0 double] [5]
Or, to exclude the reference vector:
n = 1; % index of vector whose final element is sought
ind = cellfun(#(x) {find(x==st(n).way(end))}, {st([1:n-1 n+1:end]).way});
You propbably want to use ismember.
Consider what you are passing to the intersect/ismember functions too, struct.way isn't a valid argument, you may need to loop to iterate over each line of your struct (in this case it would be easier to have a cell array, or matrix with equal length rows).
output = zeros(300);
for ii = 1:300
for jj = 1:300
if ii ~= jj && ismember(struct(ii).way(end), struct(jj).way)
output(ii,jj) = 1;
end
end
end
Now you have a matrix output where the elements which are 1 identify a match between the last element in way in the struct row ii and the vector struct(jj).way, where ii are the matrix row numbers and jj the column numbers.
I have a Matrix of 100 sub matrix . Each of this sub matrix have 6 elements (1*6),
I need to compute the mean of the first element of each sub matrix then the
second, etc
Example:
B=[4,**3**,2,1,1,2]
C=[4,**3**,5,1,1,2]
D=[6,**3**,2,1,1,2]
A={B,C,D}
...etc
So I want the mean of the surlined numbers, then the next etc
How can I do that ???
Thanks by advance,
i think what you need here is the command cell2mat. here a small script of how to compute means automatically without knowing the size of the data. let me know if that was what you were looking for.
% Problem
vec1 = [4,3,2,1,1,2];
vec2 = [4,3,5,1,1,2];
vec3 = [6,3,2,1,1,2];
A = {vec1,vec2,vec3};
% get dimensions
cols = numel(cell2mat(A(1)));
rows = numel(A);
% convert list of vectors to matrix
M = cell2mat(A);
M = reshape(M,[cols,rows]);
M = M';
means = mean(M)
I have a 1-by-4 cell array, D. Each of the cell elements contains 2-by-2 double matrices. I want to do random permutation over each matrix independently which in result I will have the same size cell array as D but its matrices' elements will be permuted and then the inverse in order to obtain the original D again.
for a single matrix case I have the code and it works well as follows:
A=rand(3,3)
p=randperm(numel(A));
A(:)=A(p)
[p1,ind]=sort(p);
A(:)=A(ind)
but it doesn't work for a cell array.
The simplest solution for you is to use a loop:
nd = numel(D);
D_permuted{1,nd} = [];
D_ind{1,nd} = [];
for d = 1:nd)
A=D{d};
p=randperm(numel(A));
A(:)=A(p)
[~,ind]=sort(p);
D_permuted{d} = A;
D_ind{d} = ind;
end
Assuming your D matrix is just a list of identically sized (e.g. 2-by-2) matrices, then you could avoid the loop by using a 3D double matrix instead of the cell-array.
For example if you hade a D like this:
n = 5;
D = repmat([1,3;2,4],1,1,n)*10 %// Example data
Then you can do the permutation like this
m = 2*2; %// Here m is the product of the dimensions of each matrix you want to shuffle
[~,I] = sort(rand(m,n)); %// This is just a trick to get the equivalent of a vectorized form of randperm as unfortunately randperm only accepts scalars
idx = reshape(I,2,2,n);
D_shuffled = D(idx);
in Matlab, I have a scalar structure S with some fields. Each field contains a numeric vector, and all these vectors have the same size, say nx1.
Now I would like to create a numeric matrix based on a selection of the fields.
The starting point is a logical mask sized mx1, where m is the number of fields of S. mask(i) is true if the ith field of S should be included in the matrix. So the matrix size would be n x sum(mask).
Example (in my code, the structure is not built in this way, of course :-)
vec = rand(1000,1);
S.f1 = vec;
S.f2 = vec;
S.f3 = vec;
S.f4 = vec;
S.f5 = vec;
mask = [false true true false false]; % 5 elements because S has 5 fields
The expected output would be:
output = [S.f2 S.f3];
But of course, the creation of output should depend dynamically on the fields of S and on mask.
Is there any way to achieve this without using an ugly construction including a filter of the struct field names, loop, etc.?
Thank you very much!
Philip
Here's one way -
fns = fieldnames(S) %// Get all fieldnames
S = rmfield(S,fns(~mask)) %// Remove all fields with masking values as false
Next, to get your numeric array, use struct2array -
output = struct2array(S)
You can convert the struct into a cell using struct2cell, and use normal cell indexing to get the fields you want.
a = (1:5).';
s.f1 = a; s.f2 = 2*a; s.f3 = 3*a; s.f4 = 4*a; s.f5 = 5*a;
c = struct2cell(S);
[c{mask}]
ans =
2 3
4 6
6 9
8 12
10 15
You can do something like:
msks = fieldnames(S);
msks = msks(mask);
n = numel(msks);
output = zeros(1000,n);
for i = 1:n
output(:,i) = S.(msks{i});
end
I am working in matlab. I have a row vector in and a scalar number fuzzy_no. I want to create a matrix output of size fuzzy_no x (numel(in)-fuzzy_no). such that the ith col of the matrix output has the elements from i:i+fuzzy_no-1 of row vector in.
In other words I want to implement the following loop without using loops
n = numel(in);
output = zeros(fuzzy_no,n-fuzzy_no);
for i = 1:size(output,2)
output(:,i) = in(1,i:i+fuzzy_no-1);
end
Note that in your example the last element from in is missing in the output. Assuming you want all the elements, you could use indexing like so:
[ii, jj] = meshgrid(1:fuzzy_no, 0:n-fuzzy_no);
output = in(ii+jj)
Or you could use the slightly more satisfying hankel built-in:
output = hankel(in(1:fuzzy_no), in(fuzzy_no:end))
Try this -
n = numel(in);
lim1 = n-fuzzy_no
t1 = bsxfun(#times,in',ones(1,lim1)) %//'
uind = triu(ones(size(t1)),1)>0
lind = [zeros(fuzzy_no,lim1) ; tril(ones([size(t1,1)-fuzzy_no lim1]))]>0
t1(uind | lind)=[];
output = reshape(t1,fuzzy_no,n-fuzzy_no)