Build a relation between matrix components

1 Ansicht (letzte 30 Tage)
MarshallSc
MarshallSc am 30 Jun. 2021
Kommentiert: Rik am 3 Aug. 2021
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 Kommentare
Rik
Rik am 1 Jul. 2021
Did you try my answer? Does it do what you need?
MarshallSc
MarshallSc am 1 Jul. 2021
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.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Rik
Rik am 1 Jul. 2021
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 Kommentare
MarshallSc
MarshallSc am 3 Aug. 2021
Bearbeitet: MarshallSc am 3 Aug. 2021
@Rik Would it be possible to transform this script into a function so that I can use it for multiple matrices?
Rik
Rik am 3 Aug. 2021
As with all scripts in Matlab: yes. Can you guess how? Your first guess is probably correct.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Programming finden Sie in Help Center und File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by