Каковы способы суммирования матричных элементов в MATLAB?

Учитывая матрицу:

A = [1 2 3; 4 5 6; 7 8 9];
  • Как вы могли бы использовать цикл for для вычисления суммы элементов в матрице?
  • Напишите одну строку команды MATLAB, используя функцию sum, чтобы суммировать матричные элементы в A.

Мой ответ:

1)

for j=1:3,
    for i=j:3,
        A(i,:) = A(i,:)+A(j+1,:)+A(j+2,:)
    end
end

2)

sum(A)

Правильные ли ответы? Я не знал, как использовать if, while и for. Может ли кто-нибудь объяснить это мне?

Ответ 1

Для очень больших матриц с использованием sum(sum(A)) может быть быстрее, чем sum(A(:)):

>> A = rand(20000);
>> tic; B=sum(A(:)); toc; tic; C=sum(sum(A)); toc
Elapsed time is 0.407980 seconds.
Elapsed time is 0.322624 seconds.

Ответ 2

1)

total = 0;
for i=1:size(A,1)
  for j=1:size(A,2)
    total = total + A(i,j);
  end
end

2)

total = sum(A(:));

Ответ 3

Еще один ответ на первый вопрос - использовать один для цикла и выполнить линейную индексацию в массиве с помощью функции NUMEL, чтобы получить общее количество элементов:

total = 0;
for i = 1:numel(A)
  total = total+A(i);
end

Ответ 4

Избегайте использования петель, когда это возможно.

sum(A(:))

отлично, если у вас есть логическое индексирование, вы не можете использовать (:), но можете писать

% Sum all elements under 45 in the matrix
sum ( sum ( A *. ( A < 45 ) )

Так как сумма суммирует столбцы и суммирует вектор строки, который был создан первой суммой. Обратите внимание, что это работает, только если матрица 2-мерная.

Ответ 5

Лучшая практика - это, безусловно, избегать циклов или рекурсий в Matlab.

Между sum(A(:)) и sum(sum(A)). По моему опыту, массивы в Matlab, по-видимому, хранятся в непрерывном блоке в памяти в виде стоповых векторов столбцов. Таким образом, форма A не имеет большого значения в sum(). (Можно протестировать reshape() и проверить, быстро ли изменяется преобразование в Matlab. Если это так, то у нас есть причина полагать, что форма массива напрямую не связана с тем, как данные хранятся и обрабатываются.)

Таким образом, нет причин, по которым sum(sum(A)) должен быть быстрее. Было бы медленнее, если бы Matlab фактически создавал вектор строки, записывая сумму каждого столбца A сначала, а затем суммируя по столбцам. Но я думаю, что sum(sum(A)) очень широко распространен среди пользователей. Скорее всего, они будут жестким кодом sum(sum(A)) быть одним циклом, то же самое с sum(A(:)).

Ниже я предлагаю некоторые результаты тестирования. В каждом тесте в отображаемых текстах указывается A = rand (размер) и размер.

Сначала используется tic toc.

Size 100x100
sum(A(:))
Elapsed time is 0.000025 seconds.
sum(sum(A))
Elapsed time is 0.000018 seconds.

Size 10000x1
sum(A(:))
Elapsed time is 0.000014 seconds.
sum(A)
Elapsed time is 0.000013 seconds.

Size 1000x1000
sum(A(:))
Elapsed time is 0.001641 seconds.
sum(A)
Elapsed time is 0.001561 seconds.

Size 1000000
sum(A(:))
Elapsed time is 0.002439 seconds.
sum(A)
Elapsed time is 0.001697 seconds.

Size 10000x10000
sum(A(:))
Elapsed time is 0.148504 seconds.
sum(A)
Elapsed time is 0.155160 seconds.

Size 100000000
Error using rand
Out of memory. Type HELP MEMORY for your options.

Error in test27 (line 70)
A=rand(100000000,1);

Ниже используется cputime

Size 100x100
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 10000x1
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 1000x1000
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 1000000
The cputime for sum(A(:)) in seconds is 
0
The cputime for sum(sum(A)) in seconds is 
0

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312

Size 100000000
Error using rand
Out of memory. Type HELP MEMORY for your options.

Error in test27_2 (line 70)
A=rand(100000000,1);

По моему опыту, оба таймера имеют смысл только до .1s. Поэтому, если у вас есть аналогичный опыт с таймерами Matlab, ни один из тестов не может различать sum(A(:)) и sum(sum(A)).

Я попробовал самый большой размер, разрешенный на моем компьютере еще несколько раз.

Size 10000x10000
sum(A(:))
Elapsed time is 0.151256 seconds.
sum(A)
Elapsed time is 0.143937 seconds.

Size 10000x10000
sum(A(:))
Elapsed time is 0.149802 seconds.
sum(A)
Elapsed time is 0.145227 seconds.

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.2808
The cputime for sum(sum(A)) in seconds is 
0.312

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312

Size 10000x10000
The cputime for sum(A(:)) in seconds is 
0.312
The cputime for sum(sum(A)) in seconds is 
0.312

Они кажутся эквивалентными. Любой из них хорош. Но sum(sum(A)) требует, чтобы вы знали, что размер вашего массива равен 2.

Ответ 6

Вы пытаетесь суммировать все элементы 2-D массива

В Matlab используйте

Array_Sum = sum (sum (Array_Name));