@jit(nopython=True, cache=True)<EOL>def _viterbi(log_prob, log_trans, log_p_init, state, value, ptr):  
n_steps, n_states = log_prob.shape<EOL>value[<NUM_LIT:0>] = log_prob[<NUM_LIT:0>] + log_p_init<EOL>for t in range(<NUM_LIT:1>, n_steps):<EOL><INDENT>trans_out = value[t - <NUM_LIT:1>] + log_trans.T<EOL>for j in range(n_states):<EOL><INDENT>ptr[t, j] = np.argmax(trans_out[j])<EOL>value[t, j] = log_prob[t, j] + trans_out[j, ptr[t][j]]<EOL><DEDENT><DEDENT>state[-<NUM_LIT:1>] = np.argmax(value[-<NUM_LIT:1>])<EOL>for t in range(n_steps - <NUM_LIT:2>, -<NUM_LIT:1>, -<NUM_LIT:1>):<EOL><INDENT>state[t] = ptr[t+<NUM_LIT:1>, state[t+<NUM_LIT:1>]]<EOL><DEDENT>
Core Viterbi algorithm.

    This is intended for internal use only.

    Parameters
    ----------
    log_prob : np.ndarray [shape=(T, m)]
        `log_prob[t, s]` is the conditional log-likelihood
        log P[X = X(t) | State(t) = s]

    log_trans : np.ndarray [shape=(m, m)]
        The log transition matrix
        `log_trans[i, j]` = log P[State(t+1) = j | State(t) = i]

    log_p_init : np.ndarray [shape=(m,)]
        log of the initial state distribution

    state : np.ndarray [shape=(T,), dtype=int]
        Pre-allocated state index array

    value : np.ndarray [shape=(T, m)] float
        Pre-allocated value array

    ptr : np.ndarray [shape=(T, m), dtype=int]
        Pre-allocated pointer array

    Returns
    -------
    None
        All computations are performed in-place on `state, value, ptr`.