Что происходит в коде, так это то, что если вы укажете повторяющиеся линейные индексы в одном месте в матрице, вы ожидаете, что все значения, которые будут сопоставляться с одним и тем же индексом, будут суммироваться. К сожалению, это не так, как это работает в MATLAB. Он будет помнить только обновление, соответствующее в последний раз, оно видит линейный индекс.
Вот очень маленький пример. Предположим, у меня есть этот маленький 2 х 2 матрица:
>> A = [1 2; 3 4]
A =
1 2
3 4
Давайте также сказать, что у меня есть следующие 2 х 2 матрица линейных индексов B
, а также матрицу C
, что я хочу, чтобы аккумулировать с:
Если я правильно интерпретировать ваш вопрос, результат, который вы ожидаете, должно быть:
A = [1 + 10 + 20, 2;
3 + 30 + 40, 4]
Это происходит потому, что первые два ро ws должен отображаться в линейный индекс 1, который является верхним левым углом, и мы должны собирать их вместе. То же самое сказано для линейного индекса 2, который является нижним левым углом.Тем не менее, это то, что вы получите, если вы пытаетесь сделать то, что вы закодированы выше:
>> A(B) = A(B) + C
A =
21 2
43 4
Как вы можете видеть, в верхнем левом углу только обновляется с 20 + 1, как значение 20 совпадает с последним временем мы увидел индекс 1 для первой строки. Аналогично, нижний левый угол обновляется только с 40 + 3, так как 40 - это последний раз, когда мы видели индекс 2 для второй строки.
Если вы хотите выполнить это накопление, я могу предложить использовать только accumarray
, чтобы выровнять все значения с одним и тем же линейным индексом, добавить их, а затем записать их туда, куда они должны идти.
Что-то, как это должно работать:
[vals,~,ind] = unique(GlobalPoint);
sums = accumarray(ind, LM(:));
A(vals) = A(vals) + sums;
Приведенный выше код занимает немного фантазии, но это работает. Функция unique
определяет все уникальные линейные индексы в матрице GlobalPoint
и возвращает это как 1D-вектор, сохраненный в vals
. Третий параметр ind
перепараметрирует все значения в GlobalPoint
, так что они меняются на индексы от 1 до нескольких уникальных значений в vals
. Затем мы используем accumarray
, где ind
указывает , в котором корзина соответствует каждому соответствующему значению в LM
. Результатом будет массив, в котором каждый элемент соответствует сумме всех значений, которые соответствуют одному линейному индексу. Последний шаг - взять этот массив сумм и обновить правильные позиции в A
.
Вот краткий пример выполнения шагов, о которых я только что говорил. Выход первой строки кода данной ваши данные дает мне это:
>> 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
содержит все уникальные значения в GlobalPoint
и ind
содержит идентификатор, который говорит вам, какое значение в GlobalPoint
каждое значение карты для. Следовательно, индекс 1 сопоставляется с значением 1 в GlobalPoint, значение 3 сопоставляется с значением 10 в GlobalPoint и так далее. Обратите внимание, что это отсортировано, и всего 16 уникальных очков.
После того, как я бегу через accumarray
, теперь я получаю это для моих сумм:
>> 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
Мы можем видеть, что каждый бункер для линейного индекса суммируется правильно. Последний шаг - взять наши соответствующие уникальные линейные индексы с этим массивом сумм и обновить правильные позиции. У меня нет данных для этого, чтобы показать вам окончательный результат, но вы можете доверять мне, что он работает. Для того, чтобы быть абсолютно уверенными, вот что линейный индекс и соответствующие суммы соседствуют:
>> [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
Взглянув линейный индекс-уже дает мне уверенность. Мы видим, что оба значения, отображаемые в индекс 1, суммируются должным образом. Например, если вы посмотрите на линейный индекс 83, мы видим, что есть три значения, которые совпадают с этой позицией: (2,1), (3,1) и (4,4). Значения для них: -0.53125, -0.34375 и -0.25. Накопление их дает примерно -1,125, и это то, что мы видим в результате. Если вы повторите вычисления для остальных значений, мы можем проверить, правильно ли вычислены суммы.
А в самом деле большая редко встречающаяся матрица нулей, но поскольку я использую ссылку 1 дважды, это может быть только -0,53125.Этот код должен добавить -0,531249999999875 + -0,531250000000126. –
ах я вижу. Нет, к сожалению, это не так. Если у вас несколько значений доступа к одной координате, она будет помнить только последнее ** обновление ... поэтому последний индекс '1' отображается в позиции' (2,4) 'в вашей матрице, которая является' 0.53125'. Это обновление использует только обновление. На самом деле поведение указания нескольких значений для ссылки на одно местоположение не определено. Если вы хотите их накопить, вам нужно использовать что-то еще. – rayryeng
Я напишу вам ответ. Оставайтесь на линии. – rayryeng