def tpm(tpm, check_independence=True):
    """Validate a TPM.

    The TPM can be in

        * 2-dimensional state-by-state form,
        * 2-dimensional state-by-node form, or
        * multidimensional state-by-node form.
    """
    see_tpm_docs = (
        'See the documentation on TPM conventions and the `pyphi.Network` '
        'object for more information on TPM forms.'
    )
    # Cast to np.array.
    tpm = np.array(tpm)
    # Get the number of nodes from the state-by-node TPM.
    N = tpm.shape[-1]
    if tpm.ndim == 2:
        if not ((tpm.shape[0] == 2**N and tpm.shape[1] == N) or
                (tpm.shape[0] == tpm.shape[1])):
            raise ValueError(
                'Invalid shape for 2-D TPM: {}\nFor a state-by-node TPM, '
                'there must be ' '2^N rows and N columns, where N is the '
                'number of nodes. State-by-state TPM must be square. '
                '{}'.format(tpm.shape, see_tpm_docs))
        if tpm.shape[0] == tpm.shape[1] and check_independence:
            conditionally_independent(tpm)
    elif tpm.ndim == (N + 1):
        if tpm.shape != tuple([2] * N + [N]):
            raise ValueError(
                'Invalid shape for multidimensional state-by-node TPM: {}\n'
                'The shape should be {} for {} nodes. {}'.format(
                    tpm.shape, ([2] * N) + [N], N, see_tpm_docs))
    else:
        raise ValueError(
            'Invalid TPM: Must be either 2-dimensional or multidimensional. '
            '{}'.format(see_tpm_docs))
    return True
Validate a TPM.

    The TPM can be in

        * 2-dimensional state-by-state form,
        * 2-dimensional state-by-node form, or
        * multidimensional state-by-node form.