MATLAB Matrix (Cell Array) Indexing - matlab

I have just started learning MATLAB .
Please find my codes below
m= ['A','B','C'];
cs=size(m,2);
for i=1:cs
for j=1:cs
if i~=j
s1=(m(i));s2=',';s3=(m(j));
s=strcat(s1,s2,s3);
disp(s);
end
end
end
It produces the following output on command window.
A,B
A,C
B,A
B,C
C,A
C,B
But , i want to wrap up all the outputs into a single matrix (or Cell Array ) , Lets say new_M .
So that the values of new_M shall contain the all above values like this .
new_M (6,1) =
[ A,B
A,C
B,A
B,C
C,A
C,B ]
Your help will be highly appreciatated . Thanks in advance.

The idiomatic way to do this would be to use nchoosek to get the indices you want and then use linear indexing:
m = ['A','B','C'] %// For a char array OR
m = {'A','B','C'} %// For a cell array
I = nchoosek(1:numel(m), 2)
new_M = m([I; I(:,end:-1:1)])

This will work. In 'c' you will find the values
m= ['A','B','C'];
cs=size(m,2);
c = cell(6,1)
t = 1;
for i=1:cs
for j=1:cs
if i~=j
s1=(m(i));s2=',';s3=(m(j));
s=strcat(s1,s2,s3);
disp(s)
c{t} = s;
t=t+1;
end
end
end

m= ['A','B','C'];
cs=size(m,2);
new_M = [];
for i=1:cs
for j=1:cs
if i~=j
s1=(m(i));s2=',';s3=(m(j));
s=strcat(s1,s2,s3);
new_M = [new_M;s];
end
end
end
The new_M matrix will contain all the values you need.

Related

How can we use nchoosek() to get all the combinations of the rows of a matrix?

If we have a vector v of 1- 5 numbers we can use nchoosek(v,2) to get all the combinations having two elements. But this function does now allow us to get all the combinations of a matrix. I want to use it to get all the combinations of rows of a matrix.
Here's one way to do it:
function p = q47204269(inMat)
% Input handling:
if nargin == 0 || isempty(inMat)
inMat = magic(5);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rowsCell = num2cell(inMat,2);
nRows = size(inMat,1);
p = cell(nRows,1);
for indR = 1:nRows
r = nchoosek(1:nRows,indR);
p{indR} = cell2mat(reshape(rowsCell(r.',:).',indR,1,[]));
end
See also:
The perms function, as it might come in handy in what you're doing.
This question.
with square matrix A
v = 1:size(A,1);
a = nchoosek(v,2);
B = zeros(2,size(A,1),length(a));
for i = 1:length(a)
B(:,:,i) = A(a(i,:)',:);
end
Each layer of array B is a 2 row matrix with the row combos from A
Not the most readable answer, but just for the sake of a one-liner :-)
A = randn(5,3); % example matrix
N = 2; % number of rows to pick each time
result = permute(reshape(A(nchoosek(1:size(A,1), N).', :), N, [], size(A,2)), [1 3 2]);
The result is a 3D array, such that each third-dim slice gives one of the a submatrices of A.

writing a matrix in a loop

I have a series of arrays of equal length, and want to make a matrix for each data point of these, and perform some sort of operation such a multiplying the matrices.
a=ones(1,10);
b=3*ones(1,10);
c=zeros(1,10);
for i=1:10
A(i)=[a(i) a(i);
b(i) b(i)];
B(i)=[c(i) c(i)];
C(i)=B(i)*A(i);
end
Is this possible without using cells?
A = zeros(2,2,length(a));
B = zeros(length(a),:);
C = zeros(size(B));
for i=1:10
A(:,:,i)=[a(i) a(i);
b(i) b(i)];
B(i,:)=[c(i) c(i)];
C(i,:)=B(i,:)*A(:,:,i);
end
Note you can make A and B without loops:
aa = permute(A, [3,2,1]);
bb = permute(B, [3,2,1]);
A = [aa,aa;bb,bb];
B = [c.', c.'];

Using classified variables in Parallel for loops in Matlab

Hi I am trying to run a code for image reconstruction of 2D projections using the iradon transform. My aim to reduce the time significantly for which I am trying to using parallel for loop in my local cluster profile of my laptop.
But I seem to get an error which I am finding it difficult to debug-
Error: The variable data in a parfor cannot be classified.
My code-
clc;
close all;
clear all;
tic
% projection_length = input('Define projection length (px) = ');
projection_length = 4100; % which means our ouput will have 4100 cross sectional images of the capillary tube
parfor q = 1:projection_length
for i = 1:5 % typically 500, since we take 500 projections around the capillary tube 0.72 deg inc
if length(num2str(i)) == 1
data(q,:, i) = imread(['pre00' num2str(i) '.tif'], 'PixelRegion', {[1 1600], [q q]});
elseif length(num2str(i)) == 2
data(q,:, i) = imread(['pre0' num2str(i) '.tif'], 'PixelRegion', {[1 1600], [q q]});
elseif length(num2str(i)) == 3
data(q,:, i) = imread(['pre' num2str(i) '.tif'], 'PixelRegion', {[1 1600], [q q]});
end
disp(['Analyzing projection ' num2str(q) ' of ' num2str(projection_length) ', Angle ' num2str(i) '...']);
end
H = iradon( data(q,:,:), 0.72, 'Hann', 0.8, 1600);
end
toc
Firstly, I would recommend using sprintf to build the filename, like so:
fname = sprintf('pre%03d.tif', i);
data(q, :, i) = imread(fname, ...);
This will correctly zero-pad fname.
The problem with data is that you're indexing it in different ways, and unfortunately parfor cannot understand that correctly. (This should show up as a "red" warning in the MATLAB editor, which can sometimes give you better information about parfor problems). I would be tempted to fix the problem something like this:
parfor q = 1:projection_length
tmpData = zeros(N, numFiles); % insert correct value of N here
for i = 1:numFiles
fname = ...;
tmpData(:, i) = imread(fname, ...);
end
data(q, :, :) = tmpData;
H = iradon(tmpData, ...);
end
I'm not sure what you're trying to do with H - parfor will treat that as a temporary variable, and the value will not be available after the loop.

Use function eval( )+ function find()

%%%%%%%%%%%%% 2 - Old %%%%%%%%%%%%%%%%%%%%
I modified the code as suggested by achieve greater efficiency. I have new errors in the code, not being an expert of access to the cell array
for i = first:N_Files
mat{i} = load(files(i).name);
A{i} = mat{1,i};
x{i} = A{:,i};
ind{i} = find(x{i}>= -0.5 & x{i}<=0.5);
% New error
B{i} = A{ind{i,:},:}; **Index exceeds matrix dimensions.**
xx{i} = B(:,1);
end
%%%%%%%%%%%%% 1 - Old %%%%%%%%%%%%%%%%%%%%
I wrote a routine to access files placed in different folders.
Then build a cell array where are stored file data with the routine:
for i = first:N_Files
mat{i} = load(files(i).name); % 1x3 cell
eval(['A' num2str(i) '= mat{1,i} ;']) % A1,A2,A3 dim : 114336x6 double
end
A = {A1, A2, A3}; cell array 1x3
I have a problem of access to some vectors created on the evaluation of a matrix cell.
for i = first:N_Files
eval(['x' num2str(i) '= A{:,i} ;']) % create x1, x2, x3
% incorrect code
eval(['ind' num2str(i) '= find('x' num2str(i) >= -0.5 & 'x' num2str(i)
<=0.5) ;'])
end
% need this indexing solution
ind1 = find(x1>= -0.5 & x1<=0.5);
ind2 = find(x2>= -0.5 & x2<=0.5);
ind3 = find(x3>= -0.5 & x3<=0.5);
I necessity to have the eval function with the find function,
it's possible?
have a useful solution?
thanks
%%%%%%%%%%%%% Complete Code %%%%%%
This is the code that I had to get.
for i = first:N_Files
A{i} = load(files(i).name); % 1x3 cell
x = A{:,1};
ind{i} = find(x(:,1)>= -0.5 & x(:,1)<=0.5); % This looks cleaner
B{i} = A{i}(ind{i},:); % Correct,first access element i in A then filter.
xx{i} = B{i}(:,1); %1x3 cell **what i really wanted**
yy{i} = B{i}(:,2);
zz{i} = B{i}(:,3);
u{i} = B{i}(:,4); % vettore velocità
v{i} = B{i}(:,5);
w{i} = B{i}(:,6);
c1{i} = [-0.5:0.01:0.5];
c2{i} = [0:0.01:2] ;
[X{i},Z{i}] = meshgrid(c1{i},c2{i});
U{i} = griddata(xx{i},zz{i},u{i},X{i},Z{i});
U{i}(isnan(U{i}))=0; % interpolazione ai bordi
W{i} = griddata(xx{i},zz{i},w{i},X{i},Z{i});
W{i}(isnan(W{i}))=0;
figure
pcolor(X{i},Z{i},(U{i}.^2+W{i}.^2).^0.5);
shading(gca,'interp')
title('Velocità')
colorbar;
axis square
hh = streamslice(X{i},Z{i},U{i},W{i});
set(hh,'color','k');
end
Ok I will try to help you as good as I can. First, if you have a cell that have the dimension 1xN, you do only need one index: A{i} = mat{i}. However, you then see that A==mat, which means that both are not needed. On the next row, you do x{i} = A{:,i} which seems to be the same as you do on the former row => x==mat. This means that we can remove two rows. Then I guess that your goal is to find the indices which have an absolute value smaller than 0.5 for each file and store each in a cell, right? Then to the error: By doing A{ind{i,:},:} you are actually sub-referencing A itself and not each element of A. The size of A is 1*nFiles. What you are trying to do is indeed this: B{i} = A{i}(ind{i}).
So if this is not what you want please comment. Otherwise, remove redundant variables. And make sure that you do not mix up cell with matrix. You use a cell as a container for arrays: a{n} refers to the array in cell element n and a{n}(m) refers to matrix element m in the array located in cell element n. Good luck!
for i = first:N_Files
mat{i} = load(files(i).name);
%A{i} = mat{1,i}; % not needed mat==x
%x{i} = A{:,i}; % not needed x==A
x = mat; % Fix this later, I do not want to change any variable names.
% ind{i} = find(x{i}>= -0.5 & x{i}<=0.5);
ind{i} = find(abs(x{i})<=0.5); % This looks cleaner
%B{i} = A{ind{i,:},:}; **Index exceeds matrix dimensions.**
B{i} = A{i}(ind{i}); % Correct,first access element i in A then filter.
xx{i} = B(:,1); %I do not know what you tries to do but probably
%xx{i}=B{i} => x==B so one variable is redundant.
end

How to Put Matrix in a Look and store values?

I want to put one matrix in a look and want to get values of that matrix after that loop and want to store it. Example:
N =10;
C=eye(N);
P=[.1 .2 .3];
for k=1:3
Rp=C;
for i=1:N
if(rand < P(1,k))
Rp(i,:) = 0;
end
end
end
From the above function it is clear that i will get 3 Rp matrix as i have 3 values of P. How to store the values of all these 3 Rp? Any suggestions?
I think this is what you are looking for, just simply store the results at the end of the main loop into a cell array.
N=10;
C=eye(N);
p=[.1 .2 .3];
RpMats = cell(1,numel(p));
for k=1:numel(p)
Rp=C;
for i=1:N
if(rand < p(1,k))
Rp(i,:) = 0;
end
end
RpMats{k} = Rp;
end
RpMats is a cell array where index 1 corresponds with the probability at index 1.