'Create a learnable autoregressive (1) process.
Args:
batch_size: The size of the batch, i.e. 0th dim in 2D tensor of samples.
z_size: The dimension of the distribution, i.e. 1st dim in 2D tensor.
autocorrelation_taus: The auto correlation time constant of the AR(1)
process.
A value of 0 is uncorrelated gaussian noise.
noise_variances: The variance of the additive noise, *not* the process
variance.
do_train_prior_ar_atau: Train or leave as constant, the autocorrelation?
do_train_prior_ar_nvar: Train or leave as constant, the noise variance?
num_steps: Number of steps to run the process.
name: The name to prefix to learned TF variables.'

def __init__(self, batch_size, z_size, autocorrelation_taus, noise_variances, do_train_prior_ar_atau, do_train_prior_ar_nvar, num_steps, name):

    size_bx1 = tf.stack([batch_size, 1])
    size__xu = [None, z_size]
    log_evar_inits_1xu = tf.expand_dims(tf.log(noise_variances), 0)
    self.logevars_1xu = logevars_1xu = tf.Variable(log_evar_inits_1xu, name=(name + '/logevars'), dtype=tf.float32, trainable=do_train_prior_ar_nvar)
    self.logevars_bxu = logevars_bxu = tf.tile(logevars_1xu, size_bx1)
    logevars_bxu.set_shape(size__xu)
    log_atau_inits_1xu = tf.expand_dims(tf.log(autocorrelation_taus), 0)
    self.logataus_1xu = logataus_1xu = tf.Variable(log_atau_inits_1xu, name=(name + '/logatau'), dtype=tf.float32, trainable=do_train_prior_ar_atau)
    phis_1xu = tf.exp((- tf.exp((- logataus_1xu))))
    self.phis_bxu = phis_bxu = tf.tile(phis_1xu, size_bx1)
    phis_bxu.set_shape(size__xu)
    self.logpvars_1xu = ((logevars_1xu - tf.log((1.0 - phis_1xu))) - tf.log((1.0 + phis_1xu)))
    self.logpvars_bxu = logpvars_bxu = tf.tile(self.logpvars_1xu, size_bx1)
    logpvars_bxu.set_shape(size__xu)
    self.pmeans_bxu = pmeans_bxu = tf.zeros_like(phis_bxu)
    self.means_t = means_t = ([None] * num_steps)
    self.logvars_t = logvars_t = ([None] * num_steps)
    self.samples_t = samples_t = ([None] * num_steps)
    self.gaussians_t = gaussians_t = ([None] * num_steps)
    sample_bxu = tf.zeros_like(phis_bxu)
    for t in range(num_steps):
        if (t == 0):
            logvar_pt_bxu = self.logpvars_bxu
        else:
            logvar_pt_bxu = self.logevars_bxu
        z_mean_pt_bxu = (pmeans_bxu + (phis_bxu * sample_bxu))
        gaussians_t[t] = DiagonalGaussian(batch_size, z_size, mean=z_mean_pt_bxu, logvar=logvar_pt_bxu)
        sample_bxu = gaussians_t[t].sample
        samples_t[t] = sample_bxu
        logvars_t[t] = logvar_pt_bxu
        means_t[t] = z_mean_pt_bxu
