Finding the index k of square nilpotent matrix A
이전 댓글 표시
I am trying to find the k index of a nilpotent square matrix A. It doesn't seems to do the job precisely tho..
function k = nilIndex(A)
[n,n]=size(A);
l=0;
k=n;
B =A^l;
while k-l>1
m=round((l+k)/2);
d=m-l;
C=A^(d)*B;
if all(abs(C) == 0, 'all')
k = m;
else
l = m;
B = A^l;
end
end
if k-l==1
k=n;
end
end
채택된 답변
추가 답변 (3개)
Ayush Anand
2024년 4월 12일
Hi,
You can do away with the binary search entirely and do a simple linear search if n is not large:
function k = nilIndex(A)
n = size(A, 1); % Assuming A is square
k = 1; % Start checking from A^1
while k <= n
if all(all(A^k == 0))
return; % Return current k if A^k is zero
end
k = k + 1;
end
k = NaN; % Return NaN if no such k is found within n iterations
end
However, if you want to stick to the binary search approach, you can get rid of the
if k-l==1
k=n
end
part as in a scenario where k-l is 1 at the end of the loop, k does not need to be reset to n. An example would be for a matrix like A = [[3,3,3] ; [4,4,4] ; [-7,-7,-7]], at the end of the loop the value of l is 1 and the value of k is 2. In this case k-l = 1 at the end of the loop but k =2 is the correct answer and does not need to be reset to 3.
Hope this helps!
Bruno Luong
2024년 4월 15일
편집: Bruno Luong
2024년 4월 15일
I modify your original code and now it seems working:
function k = nilIndex(A)
[n,n]=size(A);
l=0;
k=n;
B =A^l;
while k-l>1
m=round((l+k)/2);
d=m-l;
C=A^(d)*B;
if all(C == 0, 'all') % no need abs
k = m;
else
l = m;
B = C; % aleady computed
end
end
% why destroy the binary search?
%if k-l==1
% y search.k=n;
%end
end
This modified version of binary search only use matrix multiplication and keep track of A^2^p, p = 0,1,2 ...The number of matrix products is 2*ceil(log2(k)) It seems the fastest
% Generate random binary nilpotent matrix
A = diag(rand(1,1000)>0.01, 1);
p = randperm(length(A));
A = A(p,p);
tic
k = nilpotentdegree(A);
toc
if isempty(k)
fprintf('A is not nilpotent\n')
else
% This test must return 1
test_k = all(A^k == 0,'all') && any(A^(k-1),'all'),
fprintf('A nilpotent with degree = %d\n', k)
end
function k = nilpotentdegree(A)
% Check if A is nilpotent, return the degree
% k is empty if A is not impotent
n = size(A,1);
if size(A,2) ~= n
error('A lusr be square')
end
q = nextpow2(n);
A2p = zeros([n n q+1]);
% Compue A^(2^p) for p = 0,1,2, ..., q
% stored in A2p(:,:,l) with l := p+1;
% A^2^q is 0 if A is nilpotent
AP = A;
tp = 1;
for p = 0:q
if nnz(AP) && tp<n
A2p(:,:,p+1) = AP;
AP = AP*AP;
tp = tp*2;
else
break
end
end
if nnz(AP)
k = [];
else
Ak = eye(n);
k = 1;
for l = p:-1:1
tp = tp/2;
Bk = Ak * A2p(:,:,l);
if nnz(Bk)
k = k + tp;
Ak = Bk;
end
end
end
end
카테고리
도움말 센터 및 File Exchange에서 Matrices and Arrays에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!