Build a relation between matrix components

1 visualizzazione (ultimi 30 giorni)
MarshallSc
MarshallSc il 30 Giu 2021
Commentato: Rik il 3 Ago 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 Commenti
Rik
Rik il 1 Lug 2021
Did you try my answer? Does it do what you need?
MarshallSc
MarshallSc il 1 Lug 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.

Accedi per commentare.

Risposta accettata

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

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Programming in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by