Instruction inside a While Loop Matlab - matlab

What does this instruction vector=[vector,sum(othervector)] does in matlab inside a while loop like:
vector=[];
while a - b ~= 0
othervector = sum(something') %returns a vector
vector=[vector,sum(othervector)]; %it keeps a new vector?
...
end
vector=vector./100

Executing a = [a,b] means append b to a, thus vector will eventually be a matrix where each column is the row-wise sum of something'.
More concretely: suppose something' is this matrix:
something' = [ 1, 2; 3, 4 ];
Then sum(something') is:
othervector = [ 3 ; 7 ]
And initially vector is empty, so this sets vector to
vector = [ 3 ; 7 ]
Suppose we repeat with a new something' consisting of
[ 5, 5; 5, 6 ]
Then sum(something') is:
othervector = [ 10; 11 ]
And now we augment this to vector using vector = [vector, sum(othervector)]:
vector = [ vector, [10; 11] ] = [ 3, 10 ; 7, 11 ]

Related

How can I omit a row-operation for elements in the diagonal

I'm trying to create a program which solves linear systems using Gaussian Elimination. The program should consist of two parts. The forwards phase and a phase for Back-substitution.
Right now I am working on the forward phase. However, I can't figure out a method for treating the diagonal elements.
I've tried implementing if-statments which should do the row-operation for the element below the element on the diagonal.
function A = mygausselm(A)
[m,n] = size(A);
for k=1:n-1 %columns
for i=1:m-1 %rows
L = A(i+1,k)/A(k,k);
A(i+1,:)= A(i+1,:)- L*A(k,:);
end
end
end
Take the matrix:
[ 1 2 3 ]
A= [ 4 3 2 ]
[ 7 5 4 ]
The expected output should then be after the row-operations
[ * * * ]
A= [ 0 * * ]
[ 0 0 * ]
Your i index was starting wrong. Don't start from line 1, start from the next line under the diagonal element k you work on:
for k=1:n-1 %columns
for i=k+1:m %rows
L = A(i,k)/A(k,k);
A(i,:)= A(i,:)- L*A(k,:);
end
end
Since you know that when working on column k, all rows under row k have their first (k-1) elements zero, you can avoid operations on them:
for k=1:n-1 %columns
for i=k+1:m %rows
L = A(i,k)/A(k,k);
A(i,k:end)= A(i,k:end)- L*A(k,k:end);
end
end

How to compare every elements in an array with every other element without repetition?

I want data to be processed as follows.
Eg.
say data x(i)=[1 2 3 5 2 1].
Comparisons should be elements INDEX [1 to 2, 1 to 3, 1 to 4, 1 to 5, 1 to 6, 2 to 3,2 to 4,2 to 5,2 to 6,3 to 4....]
following the above logic
hence elements values of distance = [1, 2 , 3 , 4 , 5 , 1 , 2, 3, 4, 1, 2, 3, 1, 2, 1].
hence elements values of difference = [1, 2 , 4 , 1 , 0 , 1 , 3, 0, 1, 2, 1, 2, 3, 4, 1].
I have written the following code for the same but i notice that the final matrix 'b' that i want is always changing size when it should be constant. I welcome any suggestions
clc;
close all;
clear all;
% read data set
I= imread('img2.bmp');
G=double(rgb2gray(I));
%choose 2 random numbers
n = 1;
s = [1 960];
k = round(rand(n,1)*range(s)+min(s));
for i = 1:length(k)
% choose a particular row from a matrix
row_no=k(i);
%G=R(row_no,:);
% compare every element with its neigbour to create distance and difference matrix
x1=row_no;
x2=row_no;
for y1 = 1:length(G)%size(G,2)
for y2 =1:length(G) %1:size(G,2)
distance_Mat(y1,y2) = round(sqrt((y2-y1)^2 + (x2-x1)^2));
difference_Mat(y1,y2) = 1*(G(x1,y1) - G(x2,y2))^2;
end
end
%% now remove repeating comparisons
b=horzcat(distance_Mat(:),(difference_Mat(:)));
[UniXY,Index]=unique(b,'rows');
DupIndex=setdiff(1:size(b,1),Index);
b(DupIndex,:)=[];
%calculate the cumulative sums and store it in different colums of data matrix
A1 = cumsum(b);
data(:,1)=A1;
end
If you have the stats toolbox then
distance_Mat = squareform(pdist(x'));
only does each comparison once and then mirrors the data. You can get just the lower half by
tril(distance_Mat,-1);
If you don't have the toolbox then try this:
I = tril(ones(numel(x)),-1);
[r,c] = find(I);
distance_Mat = zeros(numel(x));
distance_Mat(logical(I)) = round(sqrt((x(r)-x(c)).^2)

From struct to array

Let's say I have this structure:
Results(i,j).fo
Results(i,j).co
where i=19 and j=30. How can I save in a ixj matrix all Results(i,j).fo? Or even better, How can I say to bootci to read only Results(i,j).fo
Media_tot = mean(Matrix,2)
ci = bootci(1000, #mean, Matrix');
ci = abs(ci' - repmat(Media_tot,1,2));
hE = errorbar(xdata_m, ydata_m, ci(:,1), ci(:,2));
I think this should work for your first question:
reshape([Results.fo], 19, 30)
e.g.
%// Make a 3x3 matrix of structs with 2 fields
A = [];
for k = 1:9
A(k).x = k;
A(k).y = 9-k;
end
A= reshape(A,3,3)
Now
reshape([A.x], 3,3)
ans =
1 4 7
2 5 8
3 6 9
and
reshape([A.y], 3,3)
ans =
8 5 2
7 4 1
6 3 0
Given an array of equivalent structures, e.g.
Results = [ struct('fo',1, 'co',2) struct('fo',10, 'co',20); struct('fo',100, 'co',200) struct('fo',1000, 'co',2000) ]
You can access all 'fo` using the square brackets
all_fo = [Results.fo]
% >> [1 100 10 1000]
However, they are then in a 1D-array, to get them in the original format, use
all_fo = reshape([Results.fo], size(Results))
% >> [1 10; 100 1000]

How to "chop up" matrix in Matlab using combination of logical indexing and slicing?

I have a matrix M that looks similar to this:
M = [ 1, 2, 3, 0, 0;
1, 2, 0, 0, 0;
2, 3, 4, 5, 0;
4, 5, 6, 0, 0;
1, 2, 3, 4, 5;
]
I'm trying to get a column vector with the rightmost non-zero value of each row in A, but ONLY for the rows that have the first column == 1.
I'm able to calculate a filter for the rows:
r = M( :, 1 ) == 1;
> r = [ 1; 1; 0; 0; 1 ]
And I have a set of indices for "the rightmost non-zero value of each row in M":
> c = [ 3, 2, 4, 3, 5 ]
How do I combine these in a slicing of A in order to get what I'm looking for? I'm looking for something like:
A( r, c )
> ans = [ 3; 2; 5 ]
But doing this gets me a 3x3 matrix, for some reason.
The shortest way I can think of is as follows:
% Get the values of the last non-zero entry per row
v = M(sub2ind(size(M), 1:size(M,1), c))
% Filter out the rows that does not begin with 1.
v(r == 1)
This seems to work (I assume other operations defining r,c have been performed):
M(sub2ind(size(A),find(r==1).',c(r==1))).'
Short interpretation of the problem and solution:
M( r, c )
gives a 3 x 5 matrix (not 3 x 1 as desired) due to mixing of logical and subscript indices. The logical indices in r pick out rows in A with r==1. Meanwhile row array c picks out elements from each row according to the numeric index:
ans =
3 2 0 3 0
0 2 0 0 0
3 2 4 3 5
What you really want are indices into the rightmost nonzero elements in each row starting with 1. The solution uses linear indices (numeric) to get the correct elements from the matrix.
I think this should do the trick. I wonder if there is more elegant way of doing this though.
% get only rows u want, i.e. with first row == 1
M2 = M(r,:);
% get indices of
% "the rightmost non-zero value of each row in M"
% for the rows u want
indicesOfinterest = c(r==1);
noOfIndeciesOfinterest = numel(indicesOfinterest);
% desired output column vector
output = zeros(noOfIndeciesOfinterest, 1);
% iterate through the indeces and select element in M2
% from each row and column indicated by the indice.
for idx = 1:noOfIndeciesOfinterest
output(idx) = M2(idx, indicesOfinterest(idx));
end
output % it is [3; 2 ; 5]
You can use
arrayfun(#(x) M(x,c(x)), find(r))
But unless you need r and c for other purposes, you can use
arrayfun(#(x) M(x,find(M(x,:),1,'last')), find(M(:,1)==1))
Here is a way to do it using linear indexing:
N = M';
lin_index = (0:size(N,1):prod(size(N))-1) + c;
v = N(lin_index);
v(r)

Struct to cell (or matrix) in Matlab

I have a structure with fields ID,Coor,Misc,Conn. ID and Misc are doubles, however, Coor is a 1x3 vector and Conn is a 1xn vector (where n can theoretically be from 0 to inf).
Point(x).ID = [x]
Point(x).Coordinate = [xPos yPos zPos]
Point(x).Misc = [randomDouble]
Point(x).Conn = [someVectorOfNumbers]
I would like to have this mapped on a cell array, without using a FOR loop.
An example of the output:
'ID xPos yPos zPos Misc Conn'
1 0 0 0 0 '0 1 2'
2 1 1 1 1 ''
...
x x x x x '2'
Notice that Point.Conn, its vector of numbers gets converted into a string.
The issues that I am having is breaking up Point.Coordinate into its three elements, and converting Point.Conn into a string.
I feel like this can be done using struct2Cell and then changing the nesting level. I'm just not exactly sure how to do that.
First make some example data:
n = 10;
ID = num2cell(randperm(n)');
Coordinate = mat2cell(randn(n, 3), ones(n,1));
Misc = num2cell(randn(n,1));
Conn = arrayfun(#randperm, randperm(n), 'UniformOutput', 0)';
Point = struct('ID', ID, 'Coordinate', Coordinate, 'Misc', Misc, 'Conn', Conn);
Now inspect it:
>> Point
Point =
10x1 struct array with fields:
ID
Coordinate
Misc
Conn
>> Point(1)
ans =
ID: 7
Coordinate: [-0.0571 -1.1645 2.4124]
Misc: 0.0524
Conn: [3 2 1]
Now use arrayfun() to sweep through the elements of structure array Point. We define a generic function x to operate on each element of Point, formatting the row like you described:
Point_cell = arrayfun(#(x) [num2cell([x.ID x.Coordinate x.Misc]) num2str(x.Conn)], Point, 'UniformOutput', 0);
Point_cell = vertcat(Point_cell{:})
Now inspect the output:
ans =
[ 7] [-0.0571] [-1.1645] [ 2.4124] [ 0.0524] '3 2 1'
[ 5] [ 0.2918] [ 0.4948] [ 0.7402] [-1.9539] '1 2'
[ 3] [-0.6146] [-1.2158] [ 0.3097] [ 0.5654] '3 4 1 2'
[10] [-0.0136] [ 1.5908] [-0.5420] [ 0.0778] [1x25 char]
[ 2] [ 0.4121] [ 0.5265] [ 0.1223] [ 0.0807] [1x22 char]
[ 1] [-0.9371] [ 0.2648] [ 0.9623] [ 0.7947] '1 2 5 4 3'
[ 4] [ 0.8352] [-0.3936] [-0.2540] [ 1.0437] '6 2 3 7 4 1 5'
[ 8] [ 1.0945] [-2.1763] [ 1.8918] [ 0.8022] '1'
[ 6] [ 0.3212] [-1.1957] [-1.2203] [-0.4688] [1x37 char]
[ 9] [ 0.0151] [ 0.3653] [-0.3762] [-0.0466] '3 5 4 2 6 1'
Couldn't tell from your question, but if you want all the numeric fields as an array inside a single cell, that is an easy tweak to do. Good luck!
Here is a slightly different solution using STRUCT2CELL:
%# build a sample array of structures
id = num2cell((1:10)',2); %'
coords = num2cell(rand(10,3),2);
misc = num2cell(rand(10,1),2);
conn = arrayfun(#(n)randi(5,[1 n]), randi([0 6],[10 1]), 'UniformOutput',false);
p = struct('ID',id, 'Coordinate',coords, 'Misc',misc, 'Conn',conn);
%# convert to cell array
h = fieldnames(p)'; %'
X = struct2cell(p)'; %'
%# split 'coords' field into 3 separate columns
h2 = {'xPos' 'yPos' 'zPos'};
X2 = num2cell( cell2mat(X(:,2)) );
%# convert 'conn' field to string
X4 = cellfun(#num2str, X(:,4), 'UniformOutput',false);
X4 = regexprep(X4, '[ ]+', ' '); %# clean multiple spaces as one
%# build final cell array with headers
C = [h(1) h2 h(3:4) ; X(:,1) X2 X(:,3) X4]
The result:
>> C
C =
'ID' 'xPos' 'yPos' 'zPos' 'Misc' 'Conn'
[ 1] [0.78556] [ 0.46707] [0.66281] [ 0.46484] '3'
[ 2] [0.51338] [ 0.6482] [0.33083] [ 0.76396] '2 1 2 5 1 2'
[ 3] [ 0.1776] [0.025228] [0.89849] [ 0.8182] '1 3 1 5'
[ 4] [0.39859] [ 0.84221] [0.11816] [ 0.10022] '1 1 2'
[ 5] [0.13393] [ 0.55903] [0.98842] [ 0.17812] '3 1 5 2 2 1'
[ 6] [0.03089] [ 0.8541] [0.53998] [ 0.35963] ''
[ 7] [0.93914] [ 0.34788] [0.70692] [0.056705] '2 1 3 4 4'
[ 8] [0.30131] [ 0.44603] [0.99949] [ 0.52189] '1 1 4 5 3'
[ 9] [0.29553] [0.054239] [0.28785] [ 0.33585] '1 5 2'
[10] [0.33294] [ 0.17711] [0.41452] [ 0.17567] '2'
where for example the second structure was:
>> p(2)
ans =
ID: 2
Coordinate: [0.51338 0.6482 0.33083]
Misc: 0.76396
Conn: [2 1 2 5 1 2]