Subtract corresponding nonzero element from each element in a vector
1 次查看(过去 30 天)
显示 更早的评论
Ok, I want to create an M x M matrix A with the following.
Vec1=[0 1 1 0] Vec2=[1 3 5 7]
Then, matrix A has size M = size(Vec1) = size(Vec2) and all elements start at some constant value c.
I want to update the matrix A such that, for each index where Vec1 is not zero, create a matrix row where the row values are obtained by subtracting the value of Vec2 at that same index from each other value and getting the absolute values.
So in the above example, if I initialize matrix A as:
c c c c
c c c c
c c c c
c c c c
then, the first row stays the same (Vec 1 is zero) the second row becomes [abs(3-1), abs(3-3), abs(3-5), abs(3-7)], Third row becomes [abs(5-1), abs(5-3), abs(5-5), abs(5-7)]. Fourth row stays the same, so we end up with:
c c c c
2 0 2 4
4 2 0 2
c c c c
I would like to accomplish this without loops or possibly without even repmats and the like, since the matrices and vectors in question are huge.
Thanks!
0 个评论
采纳的回答
Sean de Wolski
2011-4-11
%EDIT again
Vec1=[0 1 1 0];
Vec1(~Vec1) = nan;
Vec2=[1 3 5 7];
C2 = bsxfun(@times,Vec1.',abs(bsxfun(@minus,Vec2.',Vec2)));
C2(isnan(C2)) = A(isnan(C2));
7 个评论
Sean de Wolski
2011-4-11
You could remove one call to isnan by defining an index matrix:
idx = isnan(C2);
C2(idx) = A(idx);
更多回答(2 个)
Walter Roberson
2011-4-11
In order to avoid having at least one temporary matrix the same size as A, you would need to update A "in-place", which would require using a loop.
Possibly you might be able to do the whole calculation with a single bsxfun() call; I would have to think more about how to handle the vectorization efficiently in the face of the fact that bsxfun() expects user-provided functions to work on column vectors.
2 个评论
Sean de Wolski
2011-4-11
I wasn't able to figure out how do it all with one call to BSXFUN. I'd like to see it since it seems easily possible.
Matt Fig
2011-4-11
Try this for speed. On my machine it is much faster than the double BSXFUN call. I assume random V1 (your Vect1). .
.
.
EDIT Putting the call to ABS inside the loop is faster(?).
A = 3*ones(length(V1)); % This is your starting matrix... (Example)
TMP = 1:length(V1);
TMP = TMP(logical(V1));
for ii = TMP
A(ii,:) = abs(V2-V2(ii));
end
.
.
EDIT2
What was I thinking with that inner FOR loop? I was thinking I need to brew some more coffee...
2 个评论
另请参阅
类别
在 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!