Creates the structure of the model

        Parameters
        ----------
        beta : np.array
            Contains untransformed starting values for latent variables

        mini_batch : int
            Mini batch size for the data sampling

        Returns
        ----------
        lambda : np.array
            Contains the values for the conditional volatility series

        Y : np.array
            Contains the length-adjusted time series (accounting for lags)

        scores : np.array
            Contains the score terms for the time series

def _mb_model(self, beta, mini_batch):
        """ Creates the structure of the model

        Parameters
        ----------
        beta : np.array
            Contains untransformed starting values for latent variables

        mini_batch : int
            Mini batch size for the data sampling

        Returns
        ----------
        lambda : np.array
            Contains the values for the conditional volatility series

        Y : np.array
            Contains the length-adjusted time series (accounting for lags)

        scores : np.array
            Contains the score terms for the time series
        """

        # Transform latent variables
        parm = np.array([self.latent_variables.z_list[k].prior.transform(beta[k]) for k in range(beta.shape[0])])

        rand_int =  np.random.randint(low=0, high=self.data_length-mini_batch+1)
        sample = np.arange(start=rand_int, stop=rand_int+mini_batch)
        sampled_data = self.data[sample]

        Y = np.array(sampled_data[self.max_lag:])
        X = np.ones(Y.shape[0])
        scores = np.zeros(Y.shape[0])
        lmda = np.ones(Y.shape[0])*parm[0]
        theta = np.ones(Y.shape[0])*parm[-1]

        # Loop over time series
        for t in range(0,Y.shape[0]):

            if t < self.max_lag:
                lmda[t] = parm[0]/(1-np.sum(parm[1:(self.p+1)]))
                theta[t] += (parm[-3] - (1.0/parm[-3]))*np.exp(lmda[t])*(np.sqrt(parm[-2])*sp.gamma((parm[-2]-1.0)/2.0))/(np.sqrt(np.pi)*sp.gamma(parm[-2]/2.0))
            else:

                # Loop over GARCH terms
                for p_term in range(0,self.p):
                    lmda[t] += parm[1+p_term]*lmda[t-p_term-1]

                # Loop over Score terms
                for q_term in range(0,self.q):
                    lmda[t] += parm[1+self.p+q_term]*scores[t-q_term-1]

                if self.leverage is True:
                    lmda[t] += parm[-4]*np.sign(-(Y[t-1]-theta[t-1]))*(scores[t-1]+1)

                theta[t] += (parm[-3] - (1.0/parm[-3]))*np.exp(lmda[t]/2.0)*(np.sqrt(parm[-2])*sp.gamma((parm[-2]-1.0)/2.0))/(np.sqrt(np.pi)*sp.gamma(parm[-2]/2.0))
            
            if (Y[t]-theta[t])>=0:
                scores[t] = (((parm[-2]+1.0)*np.power(Y[t]-theta[t],2))/float(np.power(parm[-3], 2)*parm[-2]*np.exp(lmda[t]) + np.power(Y[t]-theta[t],2))) - 1.0
            else:
                scores[t] = (((parm[-2]+1.0)*np.power(Y[t]-theta[t],2))/float(np.power(parm[-3],-2)*parm[-2]*np.exp(lmda[t]) + np.power(Y[t]-theta[t],2))) - 1.0    

        return lmda, Y, scores, theta