フィルターのクリア

Value assignment to vector, without loop

19 ビュー (過去 30 日間)
ckara
ckara 2020 年 5 月 13 日
コメント済み: Tommy 2020 年 5 月 14 日
Any possible ways (-fastest preferably) of doing the following without a for loop:
out = zeros(20,1)
value = [1 2 3 4]
frm = [4 9 14 16]
to = [4 12 14 17]
for i=1:length(frm)
out(frm(i):to(i)) = value(i)
end

採用された回答

Tommy
Tommy 2020 年 5 月 13 日
Here's an option:
N = 20;
idx = (1:N)';
out = (idx >= frm & idx <= to)*value';
The indices in frm and to can't overlap, and out will have 0s wherever the values in value aren't placed.
Here's a similar method which doesn't use matrix multiplication:
N = 20;
out = zeros(N,1);
idx = (1:N)';
tf = idx >= frm & idx <= to;
out(any(tf,2)) = repelem(value, sum(tf));
No idea how these compare to other methods - including a for loop.
  2 件のコメント
ckara
ckara 2020 年 5 月 13 日
Such an elegant solution. Thanks!
Your solution is way better than using arrayfun(), but out of pure curiosity, is there any solution using arrayfun, like: arrayfun(@(x) out(from:to)=value, x) ?
Tommy
Tommy 2020 年 5 月 14 日
Happy to help!
The way you've written it, I don't believe so, no. When you use arrayfun, assignment to your variable happens outside the call to arrayfun, e.g.
out = arrayfun(@(i) value(i), 1:numel(value))
% ^ equal sign is here
arrayfun can't selectively place values, then. It could work if the function you supply to arrayfun returns every value in out, including the 0s. Then you've got to create a function that will return an element of value where appropriate and a 0 elsewhere, which would require checking if the input index falls within any elements in frm and to.
Or, your arrayfun function could return just the non-zero values as well as the indices required to fill out, and then you could fill out in the next line of code. Or there's this monstrosity that I came up with, which returns []s in place of 0s (requiring the use of a cell array), then replaces the []s with 0s, and then converts to a matrix:
N = 20;
out = arrayfun(@(i) value(i>=frm&i<=to), 1:N, 'uni', 0);
out(cellfun(@isempty, out)) = {0};
out = cell2mat(out)';
There are loads of ways you could do it, but I doubt any of them beat the for loop you wrote above. Of course I may be overlooking something!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by