Help with a nested loop
1 次查看(过去 30 天)
显示 更早的评论
I am trying to create a function which loops through a data set by comparing each row to every other row, and returning a variable if a relationship between the two rows is true (in this case, a distance relationship). The function starts at row 2 and compares 2 to 3, 3 to 4, and so on, before the outer loop increases the starting row by 1, and then the function compares row 3 to row 2, row 3 to row 4, and so on, until every row is compared with every other row.
Currently, if I run this function without the outer loop, it seems to work fine. When I nest the inner loop in the outer loop to move the reference row by 1, it is not longer working properly.
There are two specific issues:
- The nested loop I have written currently returns the entire vector of the variable I want returned only if the relationship between two rows is true. So if I tell the function to return x when the relationship is true, it is currently just returning the entire vector of x.
- It is returning the entire vector of x as one long row. I would like it to return x (when the statement is true) but start a new row each time the outer loop repeats. So I end up with rows corresponding to all the values of x when I compared to row 2, a row of all the values when I compared to row 3, and so on.
Any help is much appreciated. I am still learning Matlab. Thank you. Here is the relevant chunk of code:
function [out] = EMA_location_compare(OutputVariable, Dist, xCartCoor, yCartCoor)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
len = length(xCartCoor); %number of rows
for n = 2:len %index reference row
for v = 2:len %index comparison row
if v == n
continue %skip iterations where n is compared with itself
elseif v ~=n
ipd = sqrt((xCartCoor(n) - xCartCoor(v))^2 + (yCartCoor(n) - yCartCoor(v))^2); %pythogrean distance
ipd = ipd * 1000; %convert kl to meters
if ipd <= (Dist) %if statement to define distance constraint
out(v) = OutputVariable(v); %output variable
end
end
end
end
0 个评论
采纳的回答
Guillaume
2017-2-12
The loops are not needed.
function out = EMA_location_compare(OutputVariable, Dist, xCartCoor, yCartCoor)
validateattribures(OutputVariable, {'numeric'}, {'vector'});
validateattributes(Dist, {'numeric'}, {'scalar', 'positive'});
validateattributes(xCartCoor, {'numeric'}, {'vector', 'size', size(OutputVariable)});
validateattributes(yCartCoor, {'numeric'}, {'vector', 'size', size(OutputVariable)});
%in R2016b:
d = hypot(xCartCoor - xCartCoor', yCartCoor - yCartCoor'); %calculate distance between all the points at once
%in version < R2016b
%d = hypot(bsxfun(@minus, xCartCoor, xCartCoor'), bsxfun(@minus, yCartCoor, yCartCoor')
[ref, comp] = find(d*1000 <= Dist);
out = accumarray(ref, OutputVariable(comp), [1 numel(OutpuVariable)], @(x){x});
end
The output is a cell array of vectors. out{i} contains all the OutputVariable values within distance of OutputVariable{i}.
The problem with your loop is that you're overwriting out(v) each time it matches an n. You could fix that in your original code with:
out = cell(size(xCartCoor)); %before the loop
for n = 2:numel(xCartCoor) %numel is safer than length
%...
out{v} = [out{v}, OutputVariable(v)];
%...
end
Also note, that
if somecond
%...
elseif oppositeofthesamecondition
%...
end
is simply
if somecond
%...
else
%...
end
But in your case,
if somecond
continue
else
%do something
end
would be better as
if ~somecond %i.e. if v ~= n
%comptue distance
end
2 个评论
Guillaume
2017-2-12
"Listed together as one large set" would be a matrix, but with a matrix all rows must have the same number of elements. There's no guarantee that it'll be the case, so no.
You could pad the shorter rows with 0 or NaN to put it all in a matrix, but for further processing it would actually be harder to use. If you still want that:
maxlength = max(cellfun(@numel, out));
out = cell2mat(cellfun(@(v) [v, nan(1, maxlength - numel(v))], out, 'UniformOutput', false);
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!