What's going on in your code is that if you specify duplicate linear indices into the same location in a matrix, you expect all of the values that map to the same index to accumulate in sum. Unfortunately that's not how it works in MATLAB. It will only remember the update corresponding to the last time it sees the linear index.
Here is a very small example. Suppose I have this small 2 x 2 matrix:
>> A = [1 2; 3 4]
A =
1 2
3 4
Let's also say that I have the following 2 x 2 matrix of linear indices B
as well as a matrix C
that I want to accumulate with:
>> B = [1 1; 2 2]
B =
1 1
2 2
>> C = [10 20; 30 40]
C =
10 20
30 40
If I am interpreting your question correctly, the result that you are expecting should be:
A = [1 + 10 + 20, 2;
3 + 30 + 40, 4]
This is because the first two rows should map to linear index 1, which is the top left corner and we should accumulate those together. The same is said for linear index 2, which is the bottom left corner. However, this is what you get if you try to do what you coded above:
>> A(B) = A(B) + C
A =
21 2
43 4
As you can see, the top left corner only gets updated with 20 + 1 as the value 20 coincides with the last time we saw index 1 for the first row. Similarly, the bottom left corner only gets updated with 40 + 3, as 40 is the last time we saw index 2 for the second row.
If you want to perform this accumulation, one thing I can suggest is to use accumarray
to bin all of the values with the same linear index, add them up, then write them back to where they're supposed to go.
Something like this should work:
[vals,~,ind] = unique(GlobalPoint);
sums = accumarray(ind, LM(:));
A(vals) = A(vals) + sums;
The above code takes a bit of imagination, but it does work. The function unique
determines all unique linear indices in the matrix GlobalPoint
and returns this as a 1D vector stored in vals
. The third parameter ind
reparameterizes all values in GlobalPoint
so that they're changed into indices from 1 up to as many unique values there are in vals
. We then use accumarray
where ind
specifies which bin each corresponding value in LM
should go to. The result will be an array where each element corresponds to the sum of all values that corresponded to a single linear index. The last step is to take this sum array and update the right positions in A
.
Here's a quick example run of the steps I just talked about. The output of the first line of code given your data gives me this:
>> vals.'
ans =
1 2 10 82 83 84 92 164 165 174 730 739 812 821 894 903
>> ind.'
ans =
Columns 1 through 17
1 5 5 9 9 11 2 13 6 15 3 4 7 8 10 12 1
Columns 18 through 20
14 5 16
vals
contains all of the unique values in GlobalPoint
and ind
contains an ID which tells you which value in GlobalPoint
each value maps to. Therefore, the index of 1 maps to the value 1 in GlobalPoint, the value 3 maps to the value of 10 in GlobalPoint and so on. Take note that this is sorted and there are 16 unique points in total.
Once I run through accumarray
, I now get this for my sums:
>> sums.'
ans =
Columns 1 through 4
-1.0625 0.531250000000125 0.531249999999875 0.531250000000126
Columns 5 through 8
-1.12500000000033 0.249999999999812 0.343749999999875 0.250000000000332
Columns 9 through 12
-0.499999999999721 0.249999999999909 0.531249999999875 -0.531249999999875
Columns 13 through 16
0.343749999999875 -0.343749999999875 0.249999999999909 -0.249999999999909
We can see that each bin for a linear index is summed properly. The last step is to take our corresponding unique linear indices with this sum array and update the right positions. I don't have your data to do this to show you your final result, but you can trust me that it works. To be absolutely sure, here's what the linear index and corresponding sums are side by side:
>> [vals sums]
ans =
1 -1.0625
2 0.531250000000125
10 0.531249999999875
82 0.531250000000126
83 -1.12500000000033
84 0.249999999999812
92 0.343749999999875
164 0.250000000000332
165 -0.499999999999721
174 0.249999999999909
730 0.531249999999875
739 -0.531249999999875
812 0.343749999999875
821 -0.343749999999875
894 0.249999999999909
903 -0.249999999999909
Taking a look at linear index 1 already gives me confidence. We can see that both values that mapped to index 1 are summed properly. If you look at linear index 83 for example, we see that there are three values that coincide to this position: (2,1), (3,1) and (4,4). The values for these are -0.53125, -0.34375 and -0.25. Accumulating these gives roughly -1.125 and that's what we see in the result. If you repeat the calculation for the rest of the values, we can verify that the sums are calculated correctly.
1
is seen at position(2,4)
in your matrix which is0.53125
. The update only uses this value. Actually, the behaviour of specifying multiple values to reference a single location is undefined. If you want to accumulate these you need to use something else. – rayryeng