Сумма в матрице
Sep. 30th, 2010 10:00 amЕсть задача.
Предположим, у нас есть некий вектор X (для читабельности все картинки ниже), нам нужно просуммировать элементы вектора таким образом, чтобы получился новый вектор Sx. Делается это просто, надо умножить X на треугольную матрицу:

Если X — квадратная матрица, но с помощью той же треугольной матрицы мы суммируем содержимое каждой колонки.
А теперь, собственно, задача: предположим, нам нужно суммировать содержимое квадратной матрицы не по колонкам, а по диагоналям. То есть элементы новой матрицы должны быть следующего вида:

Задача скорее программистская, чем математическая, то есть мне не обязательно получить красивую формулу, главное, чтобы MatLab её считал быстро. В настоящее время я вынужден использовать написанную мною функцию shift, которая преобразовывает матрицу NxN в матрицу 2N-1xN, сдвигая колонки таким образом, чтобы суммируемые элементы находились в одной строке (лишние элементы в углах новой матрицы заполняются нулями). Затем я суммирую строки и вызываю unshift, которая возвращает матрице квадратную форму, отбрасывая ненужные элементы по уголкам.
P.S. Как ни странно, тупой вариант с двумя вложенными циклами тормозит жутко. Мой вариант в shift/unshift работает на2-3 порядка быстрее. Но матрицы всё равно большие. Да и вообще, код некрасивый.
Предположим, у нас есть некий вектор X (для читабельности все картинки ниже), нам нужно просуммировать элементы вектора таким образом, чтобы получился новый вектор Sx. Делается это просто, надо умножить X на треугольную матрицу:

Если X — квадратная матрица, но с помощью той же треугольной матрицы мы суммируем содержимое каждой колонки.
А теперь, собственно, задача: предположим, нам нужно суммировать содержимое квадратной матрицы не по колонкам, а по диагоналям. То есть элементы новой матрицы должны быть следующего вида:

Задача скорее программистская, чем математическая, то есть мне не обязательно получить красивую формулу, главное, чтобы MatLab её считал быстро. В настоящее время я вынужден использовать написанную мною функцию shift, которая преобразовывает матрицу NxN в матрицу 2N-1xN, сдвигая колонки таким образом, чтобы суммируемые элементы находились в одной строке (лишние элементы в углах новой матрицы заполняются нулями). Затем я суммирую строки и вызываю unshift, которая возвращает матрице квадратную форму, отбрасывая ненужные элементы по уголкам.
P.S. Как ни странно, тупой вариант с двумя вложенными циклами тормозит жутко. Мой вариант в shift/unshift работает на
no subject
Date: 2010-09-30 09:08 am (UTC)no subject
Date: 2010-09-30 09:24 am (UTC)no subject
Date: 2010-09-30 11:13 am (UTC)no subject
кгхм
no subject
Date: 2010-09-30 12:08 pm (UTC)no subject
Date: 2010-09-30 12:20 pm (UTC)no subject
Date: 2010-09-30 02:21 pm (UTC)Я, правда, и так там уже миллисекунды ловлю, но всё равно.
а так?
Date: 2010-09-30 04:19 pm (UTC)n = length(M), for i = -(n-2):n, M0 = [zeros(size(M)); M]; sumdiag(i+n-1) = sum(M0(i+n:(2*n+1):end)); end; sumdiag
no subject
Date: 2010-10-01 07:23 am (UTC)Там небольшое осложнение из-за того, что мне нужны не суммы, а обратные cumsum (то есть результат — не вектор 2N-1×1, а матрица того же размера NxN), но это решается.
no subject
Date: 2010-10-01 01:24 pm (UTC)