2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Быстрая нормировкаматрицы на 1 в Matlab
Сообщение23.04.2014, 19:51 


18/06/13
58
В Matlabe часто нужно нормировать каждый столбец матрицы, что бы сумма элементов каждого столбца давала 1.
Я делаю это циклом по всем столбцам:
for i=1:D
M(:,i)=M(:,i)/sum(M(:,i));
end

Может быть кто-то может предложить более быстрый способ ? Может есть способ избежать цикла for или встроенная функция?

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение24.04.2014, 01:49 
Аватара пользователя


17/04/14
4
Санкт-Петербург
Я попробовал следующие варианты:

Ваш способ:
Используется синтаксис Matlab M
tic, for iter=1:100 M=rand(1000,1000); for i=1:1000 M(:,i)=M(:,i)/sum(M(:,i)); end; end;toc
Elapsed time is 4.650408 seconds.


Векторный вариант, без циклов... (который описан еще и здесь:http://stackoverflow.com/questions/4521593/fast-technique-for-normalizing-a-matrix-in-matlab)

Используется синтаксис Matlab M
tic, for iter=1:100 M = rand(1000,1000); M=M./repmat(sum(M), [length(M), 1]); end; toc
Elapsed time is 9.929461 seconds.


Но, это все сделано в виртуальной машине, в Matlab 7.7.0 R2008b. Поэтому, возможно, что-то изменится на реальном железе?!

Есть еще в matlab функция normc, возможно ее функционал в последующих версиях изменился и она может выполнять такое преобразование матрицы.

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение24.04.2014, 10:01 
Заслуженный участник
Аватара пользователя


11/04/08
2749
Физтех
Вот как это работает у меня (8.3.0.532 (R2014a)).

Первый вариант:
Используется синтаксис Matlab M
tic, for iter=1:100 M=rand(1000,1000); for i=1:1000 M(:,i)=M(:,i)/sum(M(:,i)); end; end;toc
Elapsed time is 3.222425 seconds.


Второй вариант:
Используется синтаксис Matlab M
tic, for iter=1:100 M = rand(1000,1000); M=M./repmat(sum(M), [length(M), 1]); end; toc
Elapsed time is 3.023139 seconds.


Но я бы применил встроенную функцию bsxfun:
Используется синтаксис Matlab M
tic, for iter=1:100 M = rand(1000,1000); M = bsxfun(@rdivide,M,sum(M)); end; toc
Elapsed time is 2.814161 seconds.


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

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение24.04.2014, 12:04 
Заслуженный участник


11/05/08
32166
Используется синтаксис Matlab M
a=rand(3,4)
b=a/diag(sum(a))

Время не засекал.

-- Чт апр 24, 2014 13:08:57 --

А, ну засёк: Elapsed time is 0.137243 seconds для матрицы 1100*900 (время от запуска к запуску, естественно, немного плавает).

Т.е. оно плавает где-то в пределах 0.12 - 0.15 секунд. Время на собственно нормировку довольно стабильно чуть превышает 0.10 секунд.

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение24.04.2014, 13:15 
Заслуженный участник
Аватара пользователя


11/04/08
2749
Физтех
ewert
Ваш вариант:

Используется синтаксис Matlab M
tic, for iter=1:100 M = rand(1000,1000); M = M/diag(sum(M)); end; toc
Elapsed time is 13.386494 seconds.


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

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение25.04.2014, 20:26 


18/06/13
58
Благодарю всех за ответы.

Я протестировал все варианты, работают примерно одинакового, но вариант с bsxfun немного лучше. Но на больших матрицах (больших для оперативной памяти) варианты с repmat diag выдавали out of memory, а другие варианты еще работали.

 Профиль  
                  
 
 Re: Быстрая нормировкаматрицы на 1 в Matlab
Сообщение26.04.2014, 10:16 
Заслуженный участник


11/05/08
32166
ShMaxG в сообщении #853830 писал(а):
довольно долгий, по сравнению с предыдущими...

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group