Ответы, включающие функцию инициализатора f
, выполнят O (n ^ 2) работу для квадрата nxn Matrix. В идеале эта задача должна быть O (n), так как нужно заполнить чуть менее 3 * n записей.
Предположим также, что вам нужна результирующая матрица без какой-либо специальной (например, полосовой) функции хранения или индексирования (чтобы впоследствии вы могли произвольно записывать в любую ее часть). И предположим также, что вы не хотите обойти такую проблему, обернув структуру группы Matrix другим универсальным вызовом Matrix (), который удвоит временную используемую память и создаст коллекционный мусор.
Вот два способа сделать это (не применяя f к каждой записи способом O (n ^ 2) или используя отдельный цикл do). Первый включает создание трех полос в качестве временных файлов (что является мусором, который нужно собрать, но, по крайней мере, не размером n ^ 2).
М: = Матрица (100, [[- 1 $ 99], [2 $ 100], [- 1 $ 99]], сканирование = диапазон [1,1]);
Этот второй способ использует подпрограмму, которая обходит M и заполняет ее только тремя скалярными значениями (следовательно, явно не нуждается в трех списках диапазонов).
М: = Матрица (100):
ArrayTools: -fill (100,2, M, 0100 + 1)
ArrayTools: -fill (99, -1, M, 1,100 + 1);
ArrayTools: -fill (99, -1, M, 100,100 + 1);
Обратите внимание, что ArrayTools: -Fill - это скомпилированная внешняя подпрограмма, и поэтому в принципе она может быть быстрее, чем интерпретируемый метод языка Maple (правильный). Это было бы особенно быстро для Matrix M с аппаратным типом данных, таким как 'float [8]'.
Кстати, причина, по которой вышеприведенная процедура со стрелкой завершилась ошибкой «Недопустимая процедура со стрелкой», вероятно, связана с тем, что она была введена в режиме 2D Math. Парсер 2D Math Maple 13 не понимает синтаксис if ... then ... end как тело оператора стрелки. Альтернативный вариант (кроме записи f в качестве процедуры, как кто-то другой ответил) состоит в том, чтобы ввести f (неотредактированный) в режиме записи 1D Maple или отредактировать f, чтобы использовать форму оператора if
. Возможно, операторная форма if
здесь требует вложенного if
для обработки elif. Например,
f := (i,j) -> `if`(i=j,2,`if`(abs(i-j)=1,-1,0));
Matrix(100,f);