time | Calls | line |
---|
| | 2 | function [Q, blk_nz, blk_sizes] = get_Q(basis)
|
| | 3 |
|
| | 4 |
|
| | 5 |
|
| | 6 | % INPUT:
|
| | 7 | % Given A basis b = {b_1,...,b_k} of the commutant of a permutation
|
| | 8 | % group G, i.e., b_i is a matrix such that P*b_{i}*P' = b_{i}
|
| | 9 |
|
| | 10 | % OUTPUT:
|
| | 11 | % 1. Q ==> the orthogonal matrix such that it simulatenously block diagonalize
|
| | 12 | % all the elements in the basis, i.e., Q'*bi*Q is a block-diagonal matrix.
|
| | 13 | % 2. blk_nz ==> the non-zero pattern of the block-diagonal matrices
|
| | 14 | % 3. blk_sizes ==> the size of each block
|
| | 15 |
|
| | 16 | tic;
|
| | 17 | fprintf('get_Q ')
|
50.134 | 1 | 18 |
|
| | 19 | % sample a symmetric matrix from the basis
|
| | 20 | B_sample = sample_basis(basis);
|
0.130 | 1 | 21 |
|
| | 22 | % perform a spectral decomposition of B_sample
|
| | 23 | [Q,~] = eig(B_sample); % Q is orthogonal s.t. Q'BiQ is block-diagonal
|
< 0.001 | 1 | 24 |
|
< 0.001 | 1 | 25 | % the default tolerance
|
| 1 | 26 | if nargin < 2
|
| | 27 | tol = 1e-10;
|
| | 28 | end
|
< 0.001 | 1 | 29 |
|
< 0.001 | 1 | 30 | % block-diagonalize each element B_{i} in the basis
|
< 0.001 | 1 | 31 | m = length(basis{1});
|
< 0.001 | 1 | 32 | nr_B = length(basis);
|
415.504 | 12187 | 33 | blk_nz = ~logical(m);
|
88.462 | 12187 | 34 | for i = 1:nr_B
|
12.357 | 12187 | 35 | basis_hat = Q'*basis{i}*Q; % block diagonalize the basis matrices B
|
0.008 | 12187 | 36 | basis_hat(abs(basis_hat)<tol) = 0; % remove zero-entires
|
| | 37 | blk_nz = or(blk_nz,basis_hat); % remember non-zero entires.
|
| | 38 | end
|
0.003 | 1 | 39 |
|
| | 40 | % find the ordering s.t. Q'BQ is block diagonal for every B in G
|
| | 41 | r = symrcm(blk_nz);
|
0.004 | 1 | 42 |
|
0.001 | 1 | 43 | % order Q and blk_nz correspondingly
|
| | 44 | Q = Q(:,r);
|
| | 45 | blk_nz = blk_nz(r,r);
|
| | 46 |
|
| | 47 |
|
| | 48 | % for convienience, we sort the blocks based on its size
|
0.006 | 1 | 49 |
|
< 0.001 | 1 | 50 | % get the size of each block
|
< 0.001 | 1 | 51 | blk_sizes = get_blk_sizes(blk_nz);
|
| | 52 | t = cumsum(blk_sizes); % the end index of each blocks
|
| | 53 | s = [1; t(1:end-1)+1]; % the begin index of each blocks
|
< 0.001 | 1 | 54 |
|
| | 55 | % sort the blocks in descending order
|
| 1 | 56 | [blk_sizes,idx] = sort(blk_sizes,'descend');
|
< 0.001 | 1 | 57 |
|
< 0.001 | 1 | 58 | k = 0;
|
| | 59 | r = zeros(m,1);
|
< 0.001 | 198 | 60 | for i = 1:length(blk_sizes)
|
| | 61 | % consider the b-th block
|
| | 62 | b = idx(i);
|
< 0.001 | 198 | 63 |
|
| | 64 | % map the entries b(s):s(t) to k:k+blk_sizes(i)
|
| | 65 | r(k+1:k+blk_sizes(i)) = s(b):t(b);
|
< 0.001 | 198 | 66 |
|
< 0.001 | 198 | 67 | % update the starting index
|
0.004 | 1 | 68 | k = k+blk_sizes(i);
|
0.001 | 1 | 69 | end
|
| | 70 | Q = Q(:,r);
|
| | 71 | blk_nz = blk_nz(r,r);
|
| | 72 |
|
< 0.001 | 1 | 73 |
|
< 0.001 | 1 | 74 | % save the output
|
< 0.001 | 1 | 75 | G.Q = Q;
|
| | 76 | G.blk_nz = blk_nz;
|
| | 77 | G.blk_sizes = blk_sizes;
|
0.002 | 1 | 78 |
|
| | 79 | fprintf(' %g \n', toc)
|
| | 80 | end
|
Other subfunctions in this file are not included in this listing.