Using nested for-loop to generate a table of numbers - matlab

I try to write a function in which print this output:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
I wrote this code, but I'm not getting the desired output:
rows = 5;
% there are 5 rows
for i=1:rows
for j=1:i
b=i*j;
end
fprintf('%d\n',b)
end
How to I need to correct this algorithm or can you tell me, if there are any other alternate methods to solve this?

I don't know what you mean by "print", but this is how you could start:
%// initial vector
a = 1:5;
A = tril( bsxfun(#plus,a(:)*[0:numel(a)-1],a(:)) )
%// or
A = tril(a.'*a) %'// thanks to Daniel!
mask = A == 0
out = num2cell( A );
out(mask) = {[]}
A =
1 0 0 0 0
2 4 0 0 0
3 6 9 0 0
4 8 12 16 0
5 10 15 20 25
out =
[1] [] [] [] []
[2] [ 4] [] [] []
[3] [ 6] [ 9] [] []
[4] [ 8] [12] [16] []
[5] [10] [15] [20] [25]
To print it to a file, you can use.
out = out.'; %'
fid = fopen('output.txt','w')
fprintf(fid,[repmat('%d \t',1,n) '\r\n'],out{:})
fclose(fid)
and you get:
just for the command window:
out = out.'; %'
fprintf([repmat('%d \t',1,n) '\r\n'],out{:})
will be sufficient. Choose your desired delimiter, if you don't like '\t'.
If you insist on a nested for loop, you can do it like this:
rows = 5;
% there are 5 rows
for ii = 1:rows
for jj = 1:ii
b = ii*jj;
if ii <= jj
fprintf('%d \n',b)
else
fprintf('%d ',b)
end
end
end
displays:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25

Related

How to get all elements of a matrix except its first element, in Matlab?

To find the output of the following formula in Matlab, I need to get all elements of a matrix (PDA in the following code) except its first element without using any loop.
Formula(Goal): % EVec = (A11-B11).^2 - (A12-B12).^2 - .. - (Aij-Bij).^2
Ex:
A(:,:,1) = [1 2 3 4; 4 5 6 1];
A(:,:,2) = [0 5 4 3; 2 7 6 0];
A(:,:,3) = [1 2 3 9; 0 6 7 0];
B(:,:,1) = [4 0 3 4; 4 8 0 1];
B(:,:,2) = [0 5 6 1; 0 9 4 3];
B(:,:,3) = [2 0 3 5; 8 6 7 2];
PDA = (A-B).^2;
EVec = PDA(1,1,:) - sum(PDA(?, ?, :)); % The problem is sum(PDA(?, ?,:)).
The result of PDA is:
PDA(:,:,1) =
9 4 0 0
0 9 36 0
% All of them except Val(1,1) = 9.
PDA(:,:,2) =
0 0 4 4
4 4 4 9
% All of them except Val(1,1) = 0.
PDA(:,:,3) =
1 4 0 16
64 0 0 4
% All of them except Val(1,1) = 1.
And my problem is in the output of PDA(1,1,:) - sum(PDA(?, ?, :)) that should be:9-(4+0+0+0+0+9+36+0), 0-(0+4+4+4+4+4+9), 1-(4+0+16+64+0+0+4) = [-40, -29, -87]..Unfortunately it doesn't.
How to get all elements of a matrix except its first element in Matlab?
The first element minus the sum of the remaining elements is just twice the first element minus the sum of all elements, so
>> squeeze(2*PDA(1,1,:) - sum(sum(PDA,1),2))
ans =
-40
-29
-87
Or in newer releases
>> squeeze(2*PDA(1,1,:) - sum(PDA,[1,2]))
ans =
-40
-29
-87

Matlab determine index position in matrix

Hin everyone..I have matrix
col = [1 2 3 9 10 15 16 17]
I need to divide A into 3 with length B = [3 2 3],
result required :
col1 = [1 2 3] -> from col(1:3)
col2 = [9 10] -> from col(4:5)
col3 = [15 16 17] -> from col(6:8)
Thank you so much...
mat2cell can be use:
A = [1 2 3 9 10 15 16 17];
B = [3 2 3];
mat2cell(A,1, B)
Result:
{
[1,1] =
1 2 3
[1,2] =
9 10
[1,3] =
15 16 17
}
I assume that lenghts in B match col length, so every element is accounted for. If so, you can do it using simple for loop as follows:
col = [1 2 3 9 10 15 16 17];
B = [3 2 3];
start_idx = 1;
for b = B
col_part = col(start_idx : start_idx+b-1)
start_idx = start_idx+b;
end
Results in:
col_part =
1 2 3
col_part =
9 10
col_part =
15 16 17

How to combine numbers in different columns using matlab

excel has an equation or function to combine number in different column, as you can see in the picture below. having the same data in matlab , how can i combine numbers in a different columns.
having a d data:
a b c d
1 1 1 3
2 1 0 5
1 2 5 30
3 4 1 26
-1 1 1 3
since 111 and -111 have the same values of d, so i combine it so that 1st cell in 1st column became 111,-111 and their d become 6 because i add it up, so can matlab do that? thanks
a=[1 1 1 3;2 1 0 5; 1 2 5 30; 3 4 1 26; -1 1 1 3]
len=size(a);
x2=[]
for i=1:len(1)
s=num2str(a(i,1:len(2)-1));
s=s(s~=' ');
x2(i,:)=[str2num(s) (a(i,len(2)))];
end
Result:
x2 =
111 3
210 5
125 30
341 26
-111 3
now to find the repeated indices:
u=unique(x2(:,2));
n=histc(x2(:,2),u);
ind=find(x2(:,2)==u(n>1))
Result:
ind =
1
5
Ok now to sum and combine:
xx=x2(ind,:)
ss=sum(xx(:,2));
s=num2str(xx(:,1)');
s=strrep(s, ' ', ',')
x2(min(ind),2) = ss;
x2(ind(ind~=min(ind)),:) = []
C = num2cell(x2);
C(min(ind),1) = cellstr(s)
The final result is:
C =
'111,-111' [ 6]
[ 210] [ 5]
[ 125] [30]
[ 341] [26]

Creating new matrix from cell with some empty cells disregarding empty cells

I have in Matlab a cell named: elem
[36 29]
[]
[30 29]
[30 18]
[]
[31 29]
[]
[]
[8 9]
[32 30]
and a matrix named: conn
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
and i want to make 2 new matrices which will contain only the elements that correspond to non-empty cells of elem without using a for loop.
For example the correct result would be:
29 36
29 30
18 30
29 31
8 9
30 32
and:
1 2
1 4
1 5
2 4
3 5
4 5
Any help would be greatly appreciated.
inds = ~cellfun('isempty', elem); %// NOTE: faster than anonymous function
conn = conn(inds,:);
elem = elem(inds); %// (preservative)
or
inds = cellfun('isempty', elem); %// NOTE: faster than anonymous function
conn(inds,:) = [];
elem(inds ) = []; %// (destructive)
or
inds = cellfun(#(x)isequal(x,[]), elem) %// NOTE: stricter; evaluates to false
conn = conn(inds,:); %// when the 'empties' are '' or {}
elem = elem(inds); %// or struct([])
or
inds = cellfun(#(x)isequal(x,[]), elem) %// "
conn(inds,:) = [];
elem(inds ) = [];
or
inds = cellfun(#numel, elem)==2 %// NOTE: even stricter; only evaluates to
conn = conn(inds,:); %// true when there are exactly 2 elements
elem = elem(inds); %// in the entry
or
inds = cellfun(#numel, elem)==2 %// "
conn(inds,:) = [];
elem(inds ) = [];
or (if you're just interested in elem)
elem = cell2mat(elem)
or
elem = cat(1,elem{:}) %// NOTE: probably the fastest of them all
Your first output can be obtained by:
cellfun(#fliplr, elem(~cellfun(#isempty, elem)), 'UniformOutput', 0);
Note that I included #fliplr, assuming that the element order reversal in your question was intentional
Your second output can be obtained by:
conn(~cellfun(#isempty, elem), :);
conn = [1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5];
elem = { [36 29]
[]
[30 29]
[30 18]
[]
[31 29]
[]
[8 9]
[32 30]};
conn(~cellfun(#isempty, elem), :)
you can use the #isempty function for cellfun() together with logical operators like this:
EmptyCells=cellfun(#isempty,elem); %Detect empty cells
elem(EmptyCells)=[]; %Remove empty cells
conn=conn(~EmptyCells); %Remove elements corresponding the empty cells in elem
Hope that works!

Ismember by row in MATLAB

I'm trying to figure out a matrix-oriented way to perform the ismember function by row in MATLAB. That is, if I have matrices
[1 2 3 4 5 6]
[7 8 9 10 11 12]
And I put in
[3 4 5]
[10 11 12]
Into some ismember-ish function, I'd like it to return
[0 0 1 1 1 0]
[0 0 0 1 1 1]
Other than looping over each row of the matrix in a for loop, is there a way to do this?
Assuming that your data are available as matrices A and B
A = [
1 2 3 4 5 6
7 8 9 10 11 12
];
B = [
3 4 5
10 11 12];
you can convert them to cells and then use cellfun
cellA = mat2cell(A, ones(1, size(A,1)), size(A,2));
cellB = mat2cell(B, ones(1, size(B,1)), size(B,2));
membership = cell2mat(cellfun(#ismember, cellA, cellB, 'UniformOutput', false));
This returns
membership =
0 0 1 1 1 0
0 0 0 1 1 1
A = [5 3 4 2]; B = [2 4 4 4 6 8];
[Lia1,Locb1] = ismember(A,B)
Lia1 =
1 1 1 1 0 0
Locb1 =
4 3 3 3 0 0