Как инициализировать все записи матрицы с определенным значением?

40

В Хаскеле, если бы я хотел получить список из 10 элементов, который содержал бы только число 5, я мог бы сделать что-то вроде этого:

take 10 $ repeat 5

Выход:

[5,5,5,5,5,5,5,5,5,5]

Есть ли что-нибудь подобное в Matlab?

Теги:
arrays

5 ответов

68
Лучший ответ

Массиву легко присвоить повторяющиеся значения:

x(1:10) = 5;

Если вы хотите сгенерировать массив элементов, встроенных в оператор, попробуйте что-то вроде этого:

ones(1,10) * 5

или с repmat

repmat(5, 1, 10)
  • 1
    x(1:10) также работает для символа, а repmat(..) также работает для строки. Например: repmat('ab', 1, 10) дает abababababababababab .
23

Этот метод намного быстрее, чем использование repmat:

>> tic; for i = 1:1e6, x=5*ones(10,1); end; toc
Elapsed time is 3.426347 seconds.
>> tic; for i = 1:1e6, y=repmat(5,10,1); end; toc
Elapsed time is 20.603680 seconds. 

И, на мой взгляд, делает гораздо более удобочитаемый код.

5

Учитывая предопределенный размер матрицы m-by-n и целевое значение val, в вашем примере:

m = 1;
n = 10;
val = 5;

На данный момент мне на ум приходят 7 разных подходов:


1) Использование функции repmat (0,094066 секунд)

A = repmat(val,m,n)

2) Индексирование по неопределенной матрице с присваиванием (0,091561 секунд)

A(1:m,1:n) = val

3) Индексирование по целевому значению с помощью функции ones (0,151357 секунд)

A = val(ones(m,n))

4) Инициализация по умолчанию с полным назначением (0,104292 секунды)

A = zeros(m,n);
A(:) = val

5) Используя одни функции с умножением (0.069601 секунд)

A = ones(m,n) * val

6) Использование функции нулей с добавлением (0,057883 секунды)

A = zeros(m,n) + val

7) Используя repelem функцию (0.168396 секунд)

A = repelem(val,m,n)

После описания каждого подхода, в скобках, соответствующий тест выполняется в Matlab 2017a и с 100000 итераций. Победителем стал 6th подход, и это меня не удивляет.

Объяснение простое: выделение обычно производит заполненные нулями слоты памяти... следовательно, никакие другие операции не выполняются, кроме добавления val к каждому члену матрицы, и, кроме того, санация входных аргументов очень коротка.

То же самое нельзя сказать о 5th подходе, который является вторым самым быстрым, потому что, несмотря на то, что процесс очистки входных аргументов в основном одинаков, на стороне памяти выполняются три операции вместо двух:

  • первоначальное распределение
  • преобразование каждого элемента в 1
  • умножение на val
5

См. repmat в документации.

B = repmat(5,1,10)
0

Как упоминалось в других ответах, вы можете использовать:

>> tic; x=5*ones(10,1); toc
Elapsed time is 0.000415 seconds.

Еще более быстрый способ:

>> tic;  x=5; x=x(ones(10,1)); toc
Elapsed time is 0.000257 seconds.
  • 1
    Используя timeit (который является более надежным, чем tic / toc ) и пример с более чем 10 элементами, можно показать, что это ложно . Первый метод - более быстрый, тест, такой же быстрый, как и ваш, вряд ли будет точным - например, если просто несколько раз повторить ваш пример, вы получите другие выводы. Попробуйте: m1 = @() 5*ones(1e7,1); x = 5; m2 = @() x(ones(1e7,1)); Чтобы настроить анонимные функции, которые запускают ваши тесты, затем используйте timeit(m1) и timeit(m2) . Я понимаю, что m2 примерно в 3 раза медленнее . Да, это допустимый метод для создания однозначного массива, но это не более быстрый метод.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню