Replace elements of a matrix by a smaller matrix which contains circular shaped values margins

1 回表示 (過去 30 日間)
Hello,
I'm having problems to efficiently replace some values of a result matrix.
The process is taking place ~50k times, so its very time intensive (result matrix: m,n > 1000).
Each time a much smaller matrix replaces a corresponding area in the result matrix.
The problem is, that the values in the small matrix form "the shape of a circle" and represent the presence of an attribute.
Like this:
A = result matrix (in reality: much bigger):
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
B = small matrix (in reality: more elements in matrix, so that the value margins form the shape of a circle):
0 0 0 0
0 5 5 0
0 5 5 0
0 0 0 0
By performing "A(1:4, 1:4) = B" I get the result C:
0 0 0 0 1
0 5 5 0 1
0 5 5 0 1
0 0 0 0 1
1 1 1 1 1
I want the result:
1 1 1 1 1
1 5 5 1 1
1 5 5 1 1
1 1 1 1 1
1 1 1 1 1
I managed to get the result by first deleting the specific area of the result to "0" (only the ones that are not "0" in the small matrix "B") and then adding only the values of the small matrix that are not "0" by using two for-loops element-wise (50k times).
Unfortunately this takes very long....
Is there a more efficient way to do so?
Thank you very much in advance!

採用された回答

Bruno Luong
Bruno Luong 2019 年 7 月 14 日
編集済み: Bruno Luong 2019 年 7 月 15 日
C = A;
sB = size(B);
idx = {1+(1:sB(1)),1+(1:sB(2))}; % adjust offset 1 and 1 if B to be moved at other place
C(idx{:}) = B
or depends on desired result
C(idx{:})= max(C(idx{:}), B)

その他の回答 (2 件)

KALYAN ACHARJYA
KALYAN ACHARJYA 2019 年 7 月 14 日
編集済み: KALYAN ACHARJYA 2019 年 7 月 14 日
A=[1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1];
B=[0 0 0 0;0 5 5 0;0 5 5 0;0 0 0 0];
[r c]=find(B>1);
A(r,c)=B(r,c)
Result:
A =
1 1 1 1 1
1 5 5 1 1
1 5 5 1 1
1 1 1 1 1
1 1 1 1 1
  1 件のコメント
Image Analyst
Image Analyst 2019 年 7 月 14 日
Krassor's "Answer" to Kalyan moved here (to be a "Comment") since it's not an answer to the original question.
Thank you for your answer!
At first that looked exactly like what I wanted...
But when implementing, the result didn't seem right:
For example:
A=[1 1 1 1 1 1 1;1 1 1 1 1 1 1;1 1 1 1 1 1 1;1 1 1 1 1 1 1;1 1 1 1 1 1 1; 1 1 1 1 1 1 1;1 1 1 1 1 1 1];
B=[0 5 0; 5 5 5;0 5 0]
[r, c]=find(B>1)
A(1+r,1+c)=B(r,c)
B(r,c)
results in:
B =
0 5 0
5 5 5
0 5 0
r =
2
1
2
3
2
c =
1
2
2
2
3
A =
1 1 1 1 1 1 1
1 0 5 0 1 1 1
1 5 5 5 1 1 1
1 0 5 0 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
B =
5 5 5 5 5
0 5 5 5 0
5 5 5 5 5
0 5 5 5 0
5 5 5 5 5
As you can see, matrix A contains "0"s again.
I also don't understand the output r, c of the find-function.
Neither the result of B(r, c) and why A replaces the original "B" matrix (3x3) and not the B(r,c) (5x5)...
I'm very confused right now :)

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


Krassor
Krassor 2019 年 7 月 15 日
By doing this, I just replace the area in "A" by "B" with all the "0"s...
This is what I try to avoid.
I tried the following:
A=[1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1;1 1 1 1 1];
B=[0 5 0; 5 5 5;0 5 0]
[r c]=find(B)
A(r(1):r(size(r)), c(1):c(size(c)))=B(r(1):r(size(r)), c(1):c(size(c)))
Result:
B =
0 5 0
5 5 5
0 5 0
r =
2
1
2
3
2
c =
1
2
2
2
3
A =
1 1 1 1 1
5 5 5 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
Basically I think the "find"-approach is the right one... If I replace each element of the "rows" and "columns"-vector one by one (for example: A(r(1), c(1)) = B(r(1), c(1)) ... ) the result is perfect.
Only I want to avoid using a loop.
  6 件のコメント
Bruno Luong
Bruno Luong 2019 年 7 月 15 日
[i,j,b] = find(B);
A(sub2ind(size(A),i+1,j+1)) = b
Krassor
Krassor 2019 年 7 月 15 日
That looks like the solution!
Perfect!
Thank you! :)

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

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by