Модераторы: Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Алгоритм] Умножение матриц 
:(
    Опции темы
salat
Дата 7.12.2009, 04:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



Уважаемые форумчане, необходима подсказка, а точнее помощь в написании алгоритма. Я уже голову сломал.

Надо умножить матрицу А на матрицу B.

матрица A (R nxn) - симметричная, содержимое храниться только в верхнетреугольной части матрицы.
матрица B (R nxm)- прямоугольная матрица.

Пишу на Си.

Буду благодарен за любую помощь. Заранее спасибо!
PM MAIL   Вверх
Reaver
Дата 7.12.2009, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.12.2006

Репутация: нет
Всего: нет



Все просто. Данный кусок кода написан на Delphi, но на Си перенести его можно без проблем:

Код

for i := 0 to MatrixB.Col - 1 do begin
  for j := 0 to MatrixA.Row - 1 do
    for k := 0 to MatrixA.Col - 1 do
      Result.element[i, j] := MatrixA.element[k, j] * MatrixB.element[i, k] + Result.element[i, j];
end;


Где:
MatrixB.Col - число столбцов матрицы В
MatrixА.Col - число столбцов матрицы А
MatrixА.Row - число строк матрицы A
PM MAIL   Вверх
salat
Дата 11.12.2009, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



Спасибо. Но этот алгоритм не совсем подходит. Данный алгоритм просто перемножает матрицы. А нужен именно алгоритм способный перемножать обычную прямоугольную матрицу и симметричную матрицу, причем в симметричной матрице, содержимое храниться в верней треугольной части, а нижняя часть, как я понимаю заполнена нулями, т.е. например C = A * B
где: 

A { {1, 2, 3} {0, 4, 5} {0, 0, 6} } - симметричная, содержимое храниться только в верхнетреугольной части матрицы.
B { {1, 2} {3, 4} {5, 6} } - прямоугольная матрица.


Вот как то так. Может кто знает ещё алгоритмы?
PM MAIL   Вверх
bilbobagginz
Дата 11.12.2009, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



Цитата(salat @  10.12.2009,  23:22 Найти цитируемый пост)
 Может кто знает ещё алгоритмы? 

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

а вопрос этот в раздел по алгоритмам не тянет.

Добавлено через 3 минуты и 29 секунд
salat, давай подумаем вместе...
где тут симметрия:
Код

1 2 3
0 4 5
0 0 6

?
эта матрица "верхнеугольная", но не симметричная.




--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
Reaver
Дата 11.12.2009, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 28.12.2006

Репутация: нет
Всего: нет



Приведенный выше алгоритм универсален. Абсолютно без разницы, обычные, треугольные или симметричные матрицы ему умножать. Главное, чтоб размерности подходили.
PM MAIL   Вверх
bilbobagginz
Дата 11.12.2009, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



Reaver, возможно имелось в виду оптимизация.
если время вычисления суммы на строке 4 и время доступа до ячеек = О(1), твой алгоритм имеет сложность:
O( MatrixB.Col x MatrixА.Col x MatrixА.Row), или грубо говоря О(n^3).

Возможно при понимании, что матрица симметрична, 
циклы сокращаются(т.к. a(i,j)=a(j,i)) и в результате все доходит до более высокой скорости, т.е. столбики можно проходит до половины, а остальное "угадывать".







--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
salat
Дата 12.12.2009, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



Как я понял из задания, что матрица симметричная т.е. 

1 2 3
2 4 5
3 5 6

Но, представлена она по хитрому, т.е.

1 2 3
0 4 5
0 0 6
    
Это значит, что для вычисления значения формулы, нужно обращаться только к тем элементам матрицы, которые находятся выше главной диагонали или на ней. Нижняя часть заполнена нулями и обращаться к этой части нельзя. А симметрия - это типа "подсказки" взадании, что вместо элементов из нижнего треугольника нужно использовать элементы из верхнего треугольника. Т.е. элементы из нижней части, тоже надо использовать при перемножении в результирующей матрице, но только за место них брать верхние при умножении.

P.S. да я согласен, что не силен в матрицах, поэтому и обратился за помощью. И вроде все просто, но возникли трудности. Требуют алгоритм оптимальный, он будет использоваться, для программирования процессора, поэтому и такие условия.
PM MAIL   Вверх
bilbobagginz
Дата 12.12.2009, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



Цитата(salat @  11.12.2009,  23:35 Найти цитируемый пост)
но возникли трудности

покажи свои "трудности", и мы тебе поможем его доработать.




--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
salat
Дата 12.12.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



Трудности собственно в написании алгоритма, как именно его реализовать, т.е. есть алгоритм перемножения матриц, для вышеописанного случая, вот такой например

for(i=0;i<3;i++) {
    for(j=0;j<2;j++) {
        for(k=0;k<3;k++) {
            matrix_c[i][j] += matrix_a[i][k] * matrix_b[k][j];
        }
    }
}

Первые два прохода j (т.е. первая строка результирующей матрицы - matrix_c[0][0] и matrix_c[0][1]) всё ок, ну это и понятно, но дело доходит до второй строки и в матрице А("симметричной") присутствует ноль(matrix_a[1][0]), но вместо этого нуля нужно брать так скажем "симметричный" ему элемент, т.е. 2-ку - matrix_a[0][1](опять же рассматривая описанный выше пример). Но записывать результат в  matrix_c[1][0]. Дальше не описываю, т.к. надеюсь мысль ясна. В итоге должна получиться матрица matrix_c размерностью 3х2. Ну как и с обычным перемножением. Вот собственно в организации такого алгоритма и состоит трудность. 
PM MAIL   Вверх
bilbobagginz
Дата 13.12.2009, 03:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



ты не заметил, что "симметричный" элемент элементу i,j - элемент j,i.
у тебя в левой матричке даны только элементы i,j, так, что i<=j. остальные - 0.

Добавлено через 13 минут и 29 секунд
Код

            for (i=0;i<l->height;i++){
                for (j=0;j<r->width;j++){
                    result->data[i][j]=0;
                    for (k=0;k<(l->width);k++){
                        if (i<=j){
                            result->data[i][j]+=(l->data[i][k])*(r->data[k][j]);
                        }
                        else{
                            result->data[i][j]+=(l->data[k][i])*(r->data[k][j]);
                        }
                    }
                }

            }




--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
salat
Дата 13.12.2009, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



К сожалению, и этот алгоритм не работает((
PM MAIL   Вверх
salat
Дата 14.12.2009, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



В итоге получился вот такой алгоритм, вроде работает, но не проверял ещё, только на бумаге))

       for(i=0; i<NSIZE; i++){
        for(j=0; j<MSIZE; j++){
            D[i][j] = 0.0;
            for(k=0; k<NSIZE; k++){
                if(i=0){
                    D[i][j] += (A[i][k]*B[k][j]);
                }
                else if(k<=i){
                    D[i][j] += (A[k][i]*B[k][j]);
                }
                else D[i][j] += (A[i][k]*B[k][j]);
            }
        }
    }

Правда условий мне кажется слишком много.... может как-нить его упростить можно...

Спасибо bilbobagginz за помощь!!!
PM MAIL   Вверх
bilbobagginz
Дата 14.12.2009, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



Цитата(salat @  13.12.2009,  22:40 Найти цитируемый пост)
К сожалению, и этот алгоритм не работает((

это не алгоритм а код. 
в каком случае мой код дает неверный ответ?
Цитата(salat @  13.12.2009,  23:35 Найти цитируемый пост)
if(i=0){

а вот за это ... линейкой по пальцам надо бить....
для избежания такого удобно писать постоянную слева:
Код

if (0=i) {

такой код не скомпилируется и выйдет ошибка. т.к. надо было писАть ==.
твой код - скомпилируется, и будешь отлавливать. суслика в поле.


Это сообщение отредактировал(а) bilbobagginz - 14.12.2009, 01:10


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
salat
Дата 14.12.2009, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.11.2009

Репутация: нет
Всего: нет



Да уж это точно, по запаре написал... не о синтаксисе думал...

В твоем коде, на элементе [1][0] в результирующей матрице, на 3-м проходе k, обращение происходит к A[2][1] который равен 0, ну и так далее...


PM MAIL   Вверх
bilbobagginz
Дата 14.12.2009, 04:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 2
Всего: 317



Цитата(salat @  14.12.2009,  00:30 Найти цитируемый пост)
В твоем коде, на элементе [1][0] в результирующей матрице, на 3-м проходе k, обращение происходит к A[2][1] который равен 0, ну и так далее...

блин я спутал, проверка должна быть:
Код

 if (i<=k){

тоже торможу  smile 


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0557 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.