<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def committor(T, A, B, forward=True, mu=None):
 r"""Compute the committor between sets of microstates. The committor assigns to each microstate a probability that being at this state, the set B will be hit next, rather than set A (forward committor), or that the set A has been hit previously rather than set B (backward committor). See [1] for a detailed mathematical description. The present implementation uses the equations given in [2]. Parameters T : (M, M) ndarray or scipy.sparse matrix Transition matrix A : array_like List of integer state labels for set A B : array_like List of integer state labels for set B forward : bool If True compute the forward committor, else compute the backward committor. Returns ------- q : (M,) ndarray Vector of comittor probabilities. Notes ----- Committor functions are used to characterize microstates in terms of their probability to being visited during a reaction/transition between two disjoint regions of state space A, B. **Forward committor** The forward committor :math:`q^{(+)}_i` is defined as the probability that the process starting in `i` will reach `B` first, rather than `A`. Using the first hitting time of a set :math:`S`, .. math:: T_{S}=\inf\{t \geq 0 | X_t \in S \} the forward committor :math:`q^{(+)}_i` can be fromally defined as .. math:: q^{(+)}_i=\mathbb{P}_{i}(T_{A}<T_{B}). The forward committor solves to the following boundary value problem .. math:: \begin{array}{rl} \sum_j L_{ij} q^{(+)}_{j}=0 & i \in X \setminus{(A \cup B)} \\ q_{i}^{(+)}=0 & i \in A \\ q_{i}^{(+)}=1 & i \in B \end{array} :math:`L=T-I` denotes the generator matrix. **Backward committor** The backward committor is defined as the probability that the process starting in :math:`x` came from :math:`A` rather than from :math:`B`. Using the last exit time of a set :math:`S`, .. math:: t_{S}=\sup\{t \geq 0 | X_t \notin S \} the backward committor can be formally defined as .. math:: q^{(-)}_i=\mathbb{P}_{i}(t_{A}<t_{B}). The backward comittor solves another boundary value problem .. math:: \begin{array}{rl} \sum_j K_{ij} q^{(-)}_{j}=0 & i \in X \setminus{(A \cup B)} \\ q_{i}^{(-)}=1 & i \in A \\ q_{i}^{(-)}=0 & i \in B \end{array} :math:`K=(D_{\pi}L)^{T}` denotes the adjoint generator matrix. References .. [1] P. Metzner, C. Schuette and E. Vanden-Eijnden. Transition Path Theory for Markov Jump Processes. Multiscale Model Simul 7: 1192-1219 (2009). .. [2] F. Noe, C. Schuette, E. Vanden-Eijnden, L. Reich and T.Weikl Constructing the Full Ensemble of Folding Pathways from Short Off-Equilibrium Simulations. Proc. Natl. Acad. Sci. USA, 106: 19011-19016 (2009). Examples -------- array([ 0. , 0.5, 1. ]) array([ 1. , 0.45454545, 0. ]) """

    T = _types.ensure_ndarray_or_sparse(T, ndim=2, uniform=True, kind='numeric')
    A = _types.ensure_int_vector(A)
    B = _types.ensure_int_vector(B)
    if _issparse(T):
        if forward:
            return sparse.committor.forward_committor(T, A, B)
        else:
            """ if P is time reversible backward commitor is equal 1 - q+"""
            if is_reversible(T, mu=mu):
                return 1.0 - sparse.committor.forward_committor(T, A, B)

            else:
                return sparse.committor.backward_committor(T, A, B)

    else:
        if forward:
            return dense.committor.forward_committor(T, A, B)
        else:
            """ if P is time reversible backward commitor is equal 1 - q+"""
            if is_reversible(T, mu=mu):
                return 1.0 - dense.committor.forward_committor(T, A, B)
            else:
                return dense.committor.backward_committor(T, A, B)