Solution

ID: past-exam-of-the-mathematical-and-computational-biology-course-of-the-university-of-cambridge/2024/paper-2/b5/b/solution

Starting with the identity matrix, multiply by once per iteration and test the resulting power. Using integer objects keeps the calculation exact and avoids fixed-width integer overflow accidentally turning a nonzero power into zero:
def kzero(matrix,kmax=100):
    a=np.asarray(matrix,dtype=object)
    if a.ndim!=2 or a.shape[0]!=a.shape[1]:raise ValueError('square matrix required')
    power=np.eye(len(a),dtype=object)
    for k in range(1,kmax+1):
        power=power@a
        if np.equal(power,0).all():return k
    return None

print([kzero(rand_triu(10)) for _ in range(5)])
Continuing the random-number stream from the displayed example gives . These are the least positive zero powers, rather than the number of nonzero powers; in particular, a zero matrix has nilpotency index one.
For a strictly upper triangular matrix, a nonzero entry of can only lie at least positions above the diagonal. Thus , and every one of these examples must return an integer at most ten. The code interprets “up to” as including kmax; if the final strict inequality in the question is intended instead, replace range(1,kmax+1) by range(1,kmax).

New to topics? Read the docs here!