2

I want to calculate the euclidean distance between every element of an n-channeled matrix to every other and then apply the function exp(-dist) to it. My matrix is MxN so the output must be (MxN)x(MxN).

This is my code so far:

MAX=M*N;
A = zeros([MAX,MAX]);
dist= zeros([MAX,MAX]);
for x1=1:MAX
  for x2=1:MAX
    for i=1:M
      for j=1:N
        for s=1:M
          for z=1:N
            %every pixel is a vector rgb
            dist(x1,x2) = norm((imIn(i,j)-imIn(s,z)),3);
            A(x1,x2) = exp(-dist);
          end
        end
      end
    end
  end
end

It's really slow and doesn't work - it gives just ones.

Dev-iL
  • 23,742
  • 7
  • 57
  • 99
Christina J
  • 79
  • 2
  • 8
  • 2
    You have asked many questions here and not accepted any single answer. Accepting the answer helps the future visitors to know that the answer works. Consider taking a look back to mark the most helpful answers that solve your problem as [accepted](http://meta.stackexchange.com/a/5235/) in each question of yours by clicking *`✔`* on the left of the answers. One answer per question can be marked as accepted. You can also [upvote](http://meta.stackexchange.com/a/173400/) all the helpful answers by clicking *`▲`* on the left of the answers. This awards the volunteers the reward that they deserve. – Sardar Usama Jun 23 '18 at 18:46
  • What went through your mind when you wrote that many for loops? –  Jun 24 '18 at 00:16
  • i guess lack of inspiration – Christina J Jun 24 '18 at 02:08
  • Why are you asking about euclidian distance and `n` channels, but at the same time give an example with just 1 channel? Am I missing something, or is your input actually `MxNxC`? Do you, by any chance, intend to apply whatever solution you get, in a loop, to each channel separately? – Dev-iL Jun 24 '18 at 07:19

1 Answers1

1

I would use bsxfun:
*Note that since the distance is applied to scalar values, I just use abs(a-b). There is no point in call norm(), it's just dead time.

m = 3;
n = 4;
ImIn = rand(m,n)
% first transform to vector
vector = ImIn(:)
% edit: better solution for older versions, see comments
Distances = abs(bsxfun(@minus, vector', vector))
% for latest matlab versions
Distances = abs(vector'- vector)

Ouput:

ImIn =

    0.5833    0.9747    0.6369    0.6378
    0.4217    0.2235    0.6486    0.4072
    0.6525    0.1869    0.2085    0.5017


vector =

    0.5833
    0.4217
    0.6525
    0.9747
    0.2235
    0.1869
    0.6369
    0.6486
    0.2085
    0.6378
    0.4072
    0.5017


Distances =

         0    0.1616    0.0693    0.3915    0.3597    0.3964    0.0536    0.0654    0.3747    0.0546    0.1761    0.0816
    0.1616         0    0.2308    0.5530    0.1982    0.2348    0.2152    0.2269    0.2132    0.2161    0.0145    0.0800
    0.0693    0.2308         0    0.3222    0.4290    0.4656    0.0156    0.0039    0.4440    0.0147    0.2453    0.1508
    0.3915    0.5530    0.3222         0    0.7512    0.7879    0.3379    0.3261    0.7662    0.3369    0.5675    0.4731
    0.3597    0.1982    0.4290    0.7512         0    0.0366    0.4134    0.4251    0.0150    0.4143    0.1837    0.2782
    0.3964    0.2348    0.4656    0.7879    0.0366         0    0.4500    0.4618    0.0217    0.4509    0.2203    0.3148
    0.0536    0.2152    0.0156    0.3379    0.4134    0.4500         0    0.0117    0.4284    0.0009    0.2297    0.1352
    0.0654    0.2269    0.0039    0.3261    0.4251    0.4618    0.0117         0    0.4401    0.0108    0.2414    0.1469
    0.3747    0.2132    0.4440    0.7662    0.0150    0.0217    0.4284    0.4401         0    0.4293    0.1987    0.2932
    0.0546    0.2161    0.0147    0.3369    0.4143    0.4509    0.0009    0.0108    0.4293         0    0.2306    0.1361
    0.1761    0.0145    0.2453    0.5675    0.1837    0.2203    0.2297    0.2414    0.1987    0.2306         0    0.0945
    0.0816    0.0800    0.1508    0.4731    0.2782    0.3148    0.1352    0.1469    0.2932    0.1361    0.0945         0

Check:

>> size(ImIn)

ans =

     3     4

>> size(Distances)

ans =

    12    12
consthatza
  • 263
  • 1
  • 10
  • This is amazing ! Thank you very much!! – Christina J Jun 23 '18 at 23:10
  • @ChristinaJ: if it’s amazing, please click on the check mark to the left of the answer. This gives the answerer credit for his/her work, and will indicate to the community that the question has been answered. Prevents us from wasting more time on it. As Sardar said, please go through your old questions and accept answers that were helpful. Many thanks! – Cris Luengo Jun 24 '18 at 02:06
  • 1
    @ChristinaJ note that `bsxfun` does nothing in this case because it is being used incorrectly. `A-B` would not be computable if you used a MATLAB version w/o implicit expansion. Just try `abs(V-V.')` and you'd see it works equally well. To use `bsxfun` the right way, you should've done `out = abs(bsxfun(@minus,V,V.'))`, where `@minus` is one of the functions listed in [`bsxfun`'s supported functions list](https://www.mathworks.com/help/matlab/ref/bsxfun.html#bu903f1-2). `bsxfun` isn't just something you surround arbitrary expression with to "magically fix" incompatible dimension errors. – Dev-iL Jun 24 '18 at 07:42
  • A-B is computable in every matlab version. My version doesn't have imlicit expansion. I agree your bsxfun use is a bit better. But note that in older matlab versions you get: `vector - vector.' ` ` Error using -` `Matrix dimensions must agree.` – consthatza Jun 24 '18 at 11:36