Build a relation between matrix components

2 次查看(过去 30 天)
Hi, I wanted to ask whether there is an easier method to calculate the sum of relations for each component by considering the neghborhood of each point of a matrix. For example, by considering a 3*3 matrix:
a=[a11,a12,a13; a21,a22,a23; a31,a32,a33]
I want to calculate the sum of relations, in which the relation is:
r=(a-b)/(a+b)
So for example, for component a11, I would have:
r11=(a11-a12)/(a11+a12) + (a11-a22)/(a11+a22) + (a11-a21)/(a11+a21)
Essentially I want to calculate the sum of relations around each point. For example, for a11, there are 3 other points, so I have 3 relations summed up; for another point, for example, point a22, I have 8 other points in the neighborhood of a22, so I would have 8 relations that would be summed up. I've written a function for it but it's very long. A small portion of it:
function [c] = relation(y, i, j, m, n)
c=0;
if i~=1 && j~=1 && i~=m && j~=n
c = (y(i,j) - y(i,j+1))/ (y(i,j) + y(i,j+1));
c = c + (y(i,j) - y(i+1,j+1)) / (y(i,j) + y(i+1,j+1));
c = c + (y(i,j) - y(i+1,j))/ (y(i,j) + y(i+1,j));
c = c + (y(i,j) - y(i+1,j-1))/ (y(i,j) + y(i+1,j-1));
c = c + (y(i,j) - y(i-1,j-1))/ (y(i,j) + y(i-1,j-1));
c = c + (y(i,j) - y(i-1,j))/ (y(i,j) + y(i-1,j));
c = c + (y(i,j) - y(i-1,j+1))/ (y(i,j) + y(i-1,j+1));
c = c + (y(i,j) - y(i,j-1))/ (y(i,j) + y(i,j-1));
end
if i==1 && j==1
c = (y(i,j) - y(i,j+1))/ (y(i,j) + y(i,j+1));
c = c + (y(i,j) - y(i+1,j+1)) / (y(i,j) + y(i+1,j+1));
c = c + (y(i,j) - y(i+1,j))/ (y(i,j) + y(i+1,j));
end
.
.
.
I wanted to ask whether there would be an easier way to calculate the sum of relations.
Thank you.
  2 个评论
Rik
Rik 2021-7-1
Did you try my answer? Does it do what you need?
MarshallSc
MarshallSc 2021-7-1
Thanks a lot Rik, yes, it works very well. As you mentioned, I was thinking about the convolution method as well but didn't know how to apply it. But your method works great, thank you for your taking the time. Hopefully others will suggest their opinions to see if it can be solved using convolution. Thanks again.

请先登录,再进行评论。

采纳的回答

Rik
Rik 2021-7-1
It is almost possible to use a convolution to solve your question, but I couldn't see how, so I did it with a replicated array.
% example inputs
A = reshape(1:16,4,4);
n = numel(A)-1;
%first we pad the array with NaNs
A_pad=NaN(size(A)+2);
A_pad(2:(end-1),2:(end-1))=A;
%now we can replicate this for the 8 different shifts we need to apply
n=0;
B=repmat(A,[1 1 8]);
for k1=[-1 0 1]
tmp1=circshift(A_pad,k1,1);
for k2=[-1 0 1]
if k1==0 && k2==0,continue,end % skip the null shift
tmp2=circshift(tmp1,k2,2);
n=n+1;
B(:,:,n)=tmp2(2:(end-1),2:(end-1));
end
end
%calculate relations
%NB: pre-R2016b you need to use A=repmat(A,[1 1 8]); first
R=(A-B)./(A+B);
%sum over the third dimension, using only the valid shifts
R=sum(R,3,'omitnan')
R = 4×4
-1.7143 0.3853 0.0339 0.2752 -1.3508 0.8175 0.2677 0.5066 -1.1307 0.5767 0.2193 0.4672 -0.4632 0.4967 0.2527 0.3603
  2 个评论
MarshallSc
MarshallSc 2021-8-3
编辑:MarshallSc 2021-8-3
@Rik Would it be possible to transform this script into a function so that I can use it for multiple matrices?
Rik
Rik 2021-8-3
As with all scripts in Matlab: yes. Can you guess how? Your first guess is probably correct.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Programming 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by