В Matlab есть способ скопировать нижнюю треугольную половину матрицы в верхнюю треугольную половину?В Matlab есть способ скопировать нижнюю треугольную половину матрицы в верхнюю треугольную половину?
Для квадратной матрицы А, я хочу быть в состоянии сделать
triu(A)=tril(A)';
для того, чтобы установить все A(i,j)
в A(j,i)
для I> J.
Есть ли удобный/эффективный способ сделать это?
Примечание: ответ может быть применен к разреженным матрицам.
На тему эффективности,
Я сделал некоторые испытания в отношении относительной стоимости времени для доступа к части матрицы. Я использовал версию R2014a
Некоторые результаты: логическое индексирование болезненно медленное и его следует избегать; хуже логическое индексирование с разреженными матрицами; добавление, включающее плотные матрицы в среде с разреженной матрицей, является tortu r ous, и его следует избегать любой ценой.
До сих пор данные свидетельствуют о том, что tril(A,-1)+tril(A)'
, пожалуй, лучший способ. (Цикличность не пробовали. Но это, скорее всего, по крайней мере, столь же медленно, как логическую индексацию.)
% Note: In each case, the posted results are those after a few "warm up" trials.
% providing the arrays
>> e=ones(1000,1);
>> temp=[e,zeros(1000,999)];
>> A=magic(1000);
>> temp2=[true(1000,1),false(1000,999)];
% matrix addition (without sparse matrix support)
>> tic;for i=1:1000; A=A+temp; A=A-temp; end; toc
Elapsed time is 1.903718 seconds.
>> tic;for i=1:1000; A=A+temp; A=A-temp; end; toc
Elapsed time is 1.898125 seconds.
>> tic;for i=1:1000; A=A+temp; A=A-temp; end; toc
Elapsed time is 1.896766 seconds.
% logical indexing to modify part of a matrix by a smaller matrix (a column vector)
>> tic;for i=1:1000; A(temp2)=A(temp2)+e; A(temp2)=A(temp2)-e; end; toc
Elapsed time is 4.916888 seconds.
>> tic;for i=1:1000; A(temp2)=A(temp2)+e; A(temp2)=A(temp2)-e; end; toc
Elapsed time is 4.926484 seconds.
>> tic;for i=1:1000; A(temp2)=A(temp2)+e; A(temp2)=A(temp2)-e; end; toc
Elapsed time is 4.929350 seconds.
% logical indexing to modify part of a matrix by a scalar
>> tic;for i=1:1000; A(temp2)=A(temp2)+1; A(temp2)=A(temp2)-1; end; toc
Elapsed time is 4.914185 seconds.
>> tic;for i=1:1000; A(temp2)=A(temp2)+1; A(temp2)=A(temp2)-1; end; toc
Elapsed time is 4.909323 seconds.
>> tic;for i=1:1000; A(temp2)=A(temp2)+1; A(temp2)=A(temp2)-1; end; toc
Elapsed time is 4.905367 seconds.
>> tic;for i=1:1000; A(temp2)=1; A(temp2)=-1; end; toc
Elapsed time is 2.472018 seconds.
>> tic;for i=1:1000; A(temp2)=1; A(temp2)=-1; end; toc
Elapsed time is 2.463884 seconds.
>> tic;for i=1:1000; A(temp2)=1; A(temp2)=-1; end; toc
Elapsed time is 2.462588 seconds.
% matrix addition with sparse matrix support (astounding?)
>> A=sparse(A); temp3=sparse(temp2);
>> tic;for i=1:1000; A=A+temp3; A=A-temp3; end; toc
Elapsed time is 13.648472 seconds.
>> tic;for i=1:1000; A=A+temp3; A=A-temp3; end; toc
Elapsed time is 13.485242 seconds.
>> tic;for i=1:1000; A=A+temp3; A=A-temp3; end; toc
Elapsed time is 13.551307 seconds.
% matrix addition with sparse matrix support between matrices with identical sparsity structure
>> tic;for i=1:1000; temp3=temp3+temp3; temp3=temp3-temp3; end; toc
Elapsed time is 0.013174 seconds.
>> tic;for i=1:1000; temp3=temp3+temp3; temp3=temp3-temp3; end; toc
Elapsed time is 0.018456 seconds.
>> tic;for i=1:1000; temp3=temp3+temp3; temp3=temp3-temp3; end; toc
Elapsed time is 0.009555 seconds.
% matrix addition with sparsity support between two very sparse matrix of completely different sparsity structure
>> temp4=sparse([zeros(1000,999),ones(1000,1)]);
>> tic;for i=1:1000; temp4=temp4+temp3; temp4=temp4-temp3; end; toc
Elapsed time is 0.019596 seconds.
>> tic;for i=1:1000; temp4=temp4+temp3; temp4=temp4-temp3; end; toc
Elapsed time is 0.014397 seconds.
>> tic;for i=1:1000; temp4=temp4+temp3; temp4=temp4-temp3; end; toc
Elapsed time is 0.010127 seconds.
>> tic;for i=1:1000; temp4=temp4+temp3; temp4=temp4-temp3; end; toc
% logical indexing with very sparse matrix
>> tic;for i=1:1000; temp4(temp2)=1; temp4(temp2)=-1; end; toc
Elapsed time is 6.333907 seconds.
>> tic;for i=1:1000; temp4(temp2)=1; temp4(temp2)=-1; end; toc
Elapsed time is 6.378107 seconds.
>> tic;for i=1:1000; temp4(temp2)=1; temp4(temp2)=-1; end; toc
Elapsed time is 6.486917 seconds.
% cost for creating logical arrays
>> tic;temp2=[true(10000,1),false(10000,9999)];toc
Elapsed time is 0.060349 seconds.
>> tic;temp2=[true(10000,1),false(10000,9999)];toc
Elapsed time is 0.063874 seconds.
>> tic;temp2=[true(10000,1),false(10000,9999)];toc
Elapsed time is 0.060837 seconds.
Хороший ответ. Для 'A = tril (A, -1) + tril (A) '' это создало бы другую копию A (которая наполовину завершена)? Создание дополнительных копий может быть проблематичным для больших матриц, даже если оно разреженное. Для 'A (triu (true (3), 1)) = A (tril (true (3), - 1))', это, по-видимому, модифицирует сам А. Но будет ли создание «tril (true (n), 1)« дорогостоящим? И если A (3,1) = 0, например, будет ли A (triu (true (3), 1)) = A (tril (true (3), - 1)) 'изменяет разреженность на A (3 , 1) '? Большое спасибо! – Argyll
@Argyll Оба момента кажутся действительными. Я пытаюсь придумать лучший способ сделать это с разреженными матрицами в Matlab. – Justin
@Argyll Существует ли какая-либо специальная структура матрицы? Это очень редко? Возможно, вам будет лучше с петлей. Я бы попробовал варианты и время их. – Justin