Reputation: 10040
I am trying to set up some YALMIP constraints as follows:
for i=1:q
Constraints = [Constraints, trace(As(:, :, i)) == 1]
end
So I am essentially just trying to assert that all the (square) matrices in the first q pages of the 3d array As
have trace 1.
How do I vectorize this so that I don't have to keep resizing my Constraints
array?
Upvotes: 0
Views: 99
Reputation: 112669
As Cris Luengo said, to avoid resizing you don't need to vectorize, it suffices to preallocate.
But if you want to vectorize, here's a way, using linear indexing:
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;
The linear indexing part works as follows. Consider a 4×4×3 example array ( As
). Displaying its 3 pages (third-dimension slices) separately, the linear order of the entries is
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
The line lin = ...
first builds the column vector
1
6
11
16
which corresponds to the diagonal of the first page. Then, the row vector [0 16 32]
is added to that column vector. Thanks to implicit expansion, this produces the following matrix of linear indices (variable lin
):
1 17 33
6 22 38
11 27 43
16 32 48
As can be seen, each column contains the indices of the diagonal of a page from the original array. The last line of the code applies this matrix as an index, computes the sum of each column and compares with 1
.
Upvotes: 2