def standardise(X, how='range=2', mean=None, std=None, midrange=None,
                ptp=None):
    """Standardise.
    ftp://ftp.sas.com/pub/neural/FAQ2.html#A_std_in

    Parameters
    ----------
    X : matrix
        Each sample is in range [0, 1]
    how : str, {'range=2', 'std=1'}
        'range=2' sets midrange to 0 and enforces
        all values to be in the range [-1,1]
        'std=1' sets mean = 0 and std = 1

    Returns
    -------
    new_X : matrix
        Same shape as `X`.  Sample is in range [lower, upper]

    See also
    --------
    unstandardise
    """
    if how == 'std=1':
        if mean is None:
            mean = X.mean()
        if std is None:
            std = X.std()
        centered = X - mean
        if std == 0:
            return centered
        else:
            return centered / std
    elif how == 'range=2':
        if midrange is None:
            midrange = (X.max() + X.min()) / 2
        if ptp is None:
            ptp = X.ptp()
        return (X - midrange) / (ptp / 2)
    else:
        raise RuntimeError("unrecognised how '" + how + "'")