Я пытаюсь установить некоторые ограничения YALMIP следующим образом:
for i=1:q
Constraints = [Constraints, trace(As(:, :, i)) == 1]
end
Таким образом, я, по сути, просто пытаюсь утверждать, что все (квадратные) матрицы на первых q страницах трехмерного массива As
имеют след 1.
Как мне векторизовать это, чтобы мне не приходилось постоянно изменять размер массива Constraints
?
@CrisLuengo Не думаю, что это возможно, см. второй комментарий разработчика YALMIP: groups.google.com/g/yalmip/c/w2FK3jTgl9A
Я не знаю, что они сделали для реализации этого класса ограничений, но если вы не можете заранее выделить массив, это потому, что они не реализовали соответствующую функцию. Предварительное выделение всегда должно быть возможно в MATLAB. Кроме того, a = [a, 0]
— худший способ увеличения массива в MATLAB, поскольку на каждой итерации необходимо копировать все данные. a(end+1) = 0
намного лучше, поскольку MATLAB при необходимости удвоит базовое хранилище, поэтому таким образом копирования будет намного меньше. Смотрите вопросы и ответы.
Как сказал Крис Луенго, чтобы избежать изменения размера, вам не нужно векторизовать, достаточно предварительно выделить.
Но если вы хотите векторизовать, вот способ, используя линейное индексирование:
As = randn(4,4,3); % example data
m = size(As, 1); % number of rows. The number of columns should be the same
q = size(As, 3); % number of pages
ind = (1:m+1:m^2).' + (0:q-1)*m^2; % linear index. Each diagonal is a column
Constraints = sum(As(ind), 1) == 1;
Часть линейного индексирования работает следующим образом. Рассмотрим пример массива 4×4×3 ( As
). При раздельном отображении трех страниц (третьемерных фрагментов) линейный порядок записей равен
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
17 21 25 29
18 22 26 30
19 23 27 31
20 24 28 32
33 37 41 45
34 38 42 46
35 39 43 47
36 40 44 48
Линия lin = ...
сначала строит вектор-столбец.
1
6
11
16
что соответствует диагонали первой страницы. Затем вектор-строка [0 16 32]
добавляется к этому вектор-столбцу. Благодаря неявному расширению получается следующая матрица линейных индексов (переменная lin
):
1 17 33
6 22 38
11 27 43
16 32 48
Как видно, каждый столбец содержит индексы диагонали страницы из исходного массива. Последняя строка кода применяет эту матрицу в качестве индекса, вычисляет сумму каждого столбца и сравнивает с 1
.
Пожалуйста, прочтите мой ответ на комментарий Криса Луенго.
@gen Извините, я не уверен, о чем идет речь в теме, на которую вы ссылаетесь. Но если вы хотите векторизовать вычисление трассировки (вычислить все трассировки одновременно), вы можете использовать мой код
Не могли бы вы добавить дополнительные пояснения к последним двум строкам?
@gen Готово. Пожалуйста, смотрите отредактированный ответ
Вам следует просто предварительно выделить массив.