def mean_zero_unit_variance(arr, mean_vector=None, std_vector=None, samples_in='row'):
    """
    Normalize input data to have zero mean and unit variance.
    Return the normalized data, the mean, and the calculated standard
    deviation which was used to normalize the data

    [normalized, meanvec, stddev] = mean_zero_unit_variance(data)
            or
    [normalized, meanvec, stddev] = mean_zero(data, mean_vector=provided_mean_vector)
       etc. 
    """
    samplesIn = 1 if samples_in == 'col' else 0
    dimsIn = int(not samplesIn)
    nSamples = arr.shape[samplesIn]
    nDims = arr.shape[dimsIn]
    theshape = [1, 1]
    theshape[dimsIn] = nDims 

    if not mean_vector:
        mean_vector = arr.mean(axis=samplesIn).reshape(theshape)
    if not std_vector:
        std_vector  = arr.std(axis=samplesIn).reshape(theshape)
    # If you have a row with absolutely no information, you will divide by zero. Hence...
    std_vector[std_vector < 1e-6] = 1
    norma = (arr - mean_vector) / std_vector
    return norma, mean_vector, std_vector