<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _hkt(eivals, timescales, normalization, normalized_laplacian):
 """ Computes heat kernel trace from given eigenvalues, timescales, and normalization. For precise definition, please refer to "NetLSD: Hearing the Shape of a Graph" by A. Tsitsulin, D. Mottin, P. Karras, A. Bronstein, E. Müller. Published at KDD'18. Parameters eivals : numpy.ndarray Eigenvalue vector timescales : numpy.ndarray Vector of discrete timesteps for the kernel computation normalization : str or numpy.ndarray Either 'empty', 'complete' or None. If None or any ther value, return unnormalized heat kernel trace. For the details how 'empty' and 'complete' are computed, please refer to the paper. If np.ndarray, they are treated as exact normalization constants normalized_laplacian: bool Defines whether the eigenvalues came from the normalized Laplacian. It only affects 'complete' normalization. Returns ------- numpy.ndarray Heat kernel trace signature """

    nv = eivals.shape[0]
    hkt = np.zeros(timescales.shape)
    for idx, t in enumerate(timescales):
        hkt[idx] = np.sum(np.exp(-t * eivals))
    if isinstance(normalization, np.ndarray):
        return hkt / normalization
    if normalization == 'empty' or normalization == True:
        return hkt / nv
    if normalization == 'complete':
        if normalized_laplacian:
            return hkt / (1 + (nv - 1) * np.exp(-timescales))
        else:
            return hkt / (1 + nv * np.exp(-nv * timescales))
    return hkt