Симметричная матрица не симметрична

Недавно я написал код для метода конечных элементов. Поскольку мой алгоритм генерирует симметричную матрицу, после сбора данных для каждого элемента результирующая матрица должна быть симметричной.

Однако после того, как я запустил цикл над элементом, результирующая глобальная матрица не является симметричной. Базовая структура кода выглядит так:

A=zeros(dof,dof)

for (each element)
    loc_A = v'*(diagonal matrix)*v
         % (v is 1xN row vector)
         % loc_A is symmetric matrix

    A(K,K) = A(K,K)+loc_A
                 % (K is Nx1 column vector)
end

Поскольку я добавляю симметричные матрицы, результирующая матрица также должна быть симметричной.

Однако полученная матрица не является симметричной (я проверял с помощью issymmetric(A)). Я думаю, что это из-за ошибки округления. Если я добавлю A=(A+A')/2, результирующая матрица будет симметричной (конечно...). Однако я не хочу делать такие вещи. Есть ли какое-либо другое средство, которое делает A симметричным естественным образом без какой-либо постобработки?


person Dohyun    schedule 06.06.2016    source источник
comment
Вы правы в том, что добавление симметричных матриц также создает симметричную матрицу. Ваша теория верна, но я очень подозреваю, что с вашим кодом что-то не так. Вместо псевдокода покажите нам фактический фрагмент кода, который вы используете. Я чувствую, что вы что-то не правильно кодируете.   -  person rayryeng    schedule 06.06.2016
comment
Реальный вопрос: насколько матрица несимметрична? Я имею в виду что-то вроде (A-A.')/norm(A) или что-то в этом роде. Если это очень мало, продолжайте и просто симметризируйте его вручную. Если она не очень маленькая, найдите свою ошибку. Кроме того, убедитесь, что ваши матрицы реальны.   -  person Andras Deak    schedule 06.06.2016
comment
A(K,K) не дает вам length(K) элементов, как вы думаете. Это дает вам все перестановки K и K. Вместо этого вы хотите A(sub2ind(size(A), K,K))   -  person Suever    schedule 06.06.2016
comment
Возможно, это может быть проблемой: если вы имеете дело с комплексными числами, транспонирование (') отличается от (.'). Первый также спрягает значения.   -  person crazyGamer    schedule 06.06.2016
comment
Хотя у вас есть ошибка индексации, как уже отмечалось, ваша диагональная матрица должна быть скалярной. Кроме того, в других случаях вы можете приравнять свои записи, а не усреднять их. Используйте 1_. Следовательно, у вас есть симметричная числовая ошибка, загрязняющая записи.   -  person percusse    schedule 06.06.2016
comment
Почему вы не хотите делать A = (A+A')/2? Это очень распространенная и вполне приемлемая вещь.   -  person Sam Roberts    schedule 06.06.2016
comment
Разница очень мала (поэтому я подозревал, что это связано с ошибкой округления). Мой код отлично работает для результата. Но если матлаб распознает мою матрицу как симметричную матрицу, то он будет использовать специальный решатель, который быстрее, чем обычная матрица. Поскольку результирующая матрица у меня довольно большая, я подозревал, что (A+A')/2 также требует больших вычислений. Поскольку я добавляю много маленьких матриц к большой матрице, мне интересно, есть ли какая-либо априорная обработка (для маленькой матрицы), которая делает результирующую матрицу симметричной.   -  person Dohyun    schedule 07.06.2016


Ответы (1)


Это связано с ошибкой округления (если в вашем коде нет явной ошибки). Эта проблема обычно решается A = (A+A')/2 (это не дорогая операция), или вы можете указать решателю, что ваша глобальная матрица симметрична (некоторые решатели (например, MUMPS) имеют такую ​​опцию.)

person brkn4    schedule 02.08.2016