:py:mod:`pycmtensor.functions`
==============================

.. py:module:: pycmtensor.functions

.. autoapi-nested-parse::

   PyCMTensor functions module



Module Contents
---------------

.. py:function:: exp_mov_average(batch_avg: aesara.tensor.var.TensorVariable, moving_avg: aesara.tensor.var.TensorVariable, alpha: float = 0.1)

   Calculates the exponential moving average (EMA) of a new minibatch

   :param batch_avg: the new batch value of the mean
   :type batch_avg: TensorVariable
   :param moving_avg: the moving value of the accumulated mean
   :type moving_avg: TensorVariable
   :param alpha: the moving average factor of the batch mean
   :type alpha: float

   :returns: the new moving average
   :rtype: TensorVariable

   .. note::

      The moving average will decay by the difference between the existing value
      and the new value multiplied by the moving average factor. A higher ``alpha``
      value results in faster changing moving average.
      
      Formula:
      
      .. math::
      
          x_{EMA} = \alpha * x_t + x_{EMA} * (1-\alpha)


.. py:function:: logit(utility: Union[list, tuple, aesara.tensor.var.TensorVariable], avail: Union[list, tuple, aesara.tensor.var.TensorVariable] = None)

   Computes the Logit function, with availability conditions.

   :param utility: list of :math:`M` utility equations
   :type utility: list, tuple, TensorVariable
   :param avail: list of :math:`M` availability conditions,
                 if no availability conditions are provided, defaults to 1 for all
                 availabilities.
   :type avail: list, tuple, TensorVariable

   :returns: A NxM matrix of probabilities.
   :rtype: TensorVariable

   .. note:: The 0-th dimension is the numbering of alternatives.


.. py:function:: rmse(y_hat: aesara.tensor.var.TensorVariable, y: aesara.tensor.var.TensorVariable)

   Computes the root mean squared error (RMSE) between pairs of observations

   :param y_hat: model estimated values
   :type y_hat: TensorVariable
   :param y: ground truth values
   :type y: TensorVariable

   :returns: symbolic scalar representation of the rmse
   :rtype: TensorVariable

   .. note::

      Tensor is flattened to an N-vector if the input args are :math:`N\times 1`
      matrices.
      
      Formula:
      
      .. math::
      
          RMSE = \sqrt{\frac{1}{N}\sum_{i=1}^N(\hat{y}_i-y_i)^2}


.. py:function:: mae(y_hat: aesara.tensor.var.TensorVariable, y: aesara.tensor.var.TensorVariable)

   Computes the mean absolute error (MAE) between pairs of observations

   :param y_hat: model estimated values
   :type y_hat: TensorVariable
   :param y: ground truth values
   :type y: TensorVariable

   :returns: symbolic scalar representation of the mae
   :rtype: TensorVariable

   .. note::

      Tensor is flattened to an N-vector if the input args are :math:`N\times 1` matrices.
      
      Formula:
      
      .. math::
      
          MAE = \frac{\sum_{i=1}^N|\hat{y}_i-y_i|}{N}


.. py:function:: kl_divergence(p: aesara.tensor.var.TensorVariable, q: aesara.tensor.var.TensorVariable)

   Computes the KL divergence loss between discrete distributions ``p`` and ``q``.

   :param p: model output probabilities
   :type p: TensorVariable
   :param q: ground truth probabilities
   :type q: TensorVariable

   :returns: a symbolic representation of the KL loss with
   :rtype: TensorVariable

   .. note::

      Formula:
      
      .. math::
      
          L = \begin{cases}
              \sum_{i=1}^N (p_i * log(p_i/q_i)) & p>0\\
              0 & p<=0
          \end{cases}


.. py:function:: kl_multivar_norm(m0, v0, m1, v1, epsilon=1e-06)

   Computes the KL divergence loss between two multivariate normal distributions.

   :param m0: mean vector of the first Normal m.v. distribution :math:`N_0`
   :param v0: (co-)variance matrix of the first Normal m.v. distribution :math:`N_0`
   :param m1: mean vector of the second Normal m.v. distribution :math:`N_1`
   :param v1: (co-)variance of the second Normal m.v. distribution :math:`N_1`
   :param epsilon: small value to prevent divide-by-zero error
   :type epsilon: float

   .. note::

      k = dimension of the distribution.
      
      Formula:
      
      .. math::
      
          D_{KL}(N_0||N_1) = 0.5 * \Big(\ln\big(\frac{|v_1|}{|v_0|}\big) + trace(v_1^{-1} v_0) + (m_1-m_0)^T v_1^{-1} (m_1-m_0) - k\Big)
      
      In variational inference, the kl divergence is the relative entropy between a
      diagonal multivariate Normal and a standard Normal distribution, N(0, 1),
      therefore, for VI, ``m1=aet.constant(0)``, ``v1=aet.constant(1)``
      
      For two univariate distributions, dimensions of m0,m1,v0,v1 = 0


.. py:function:: errors(prob: aesara.tensor.var.TensorVariable, y: aesara.tensor.var.TensorVariable)

   Symbolic representation of the discrete prediction as a percentage error.

   :param prob: matrix describing the choice probabilites
   :type prob: TensorVariable
   :param y: the ``TensorVariable`` referencing the choice column
   :type y: TensorVariable

   :returns: the mean prediction error over the input ``y``
   :rtype: TensorVariable


.. py:function:: hessians(ll: aesara.tensor.var.TensorVariable, params: list[pycmtensor.expressions.Beta])

   Symbolic representation of the Hessian matrix given the log likelihood.

   :param ll: the loglikelihood to compute the gradients over
   :type ll: TensorVariable
   :param params: list of params to compute the gradients over
   :type params: list

   :returns: the Hessian matrix
   :rtype: TensorVariable

   .. note:: Parameters with status=1 are ignored.


.. py:function:: bhhh(ll: aesara.tensor.var.TensorVariable, params: list[pycmtensor.expressions.Beta])

   Symbolic representation of the Berndt-Hall-Hall-Hausman (BHHH) algorithm given
   the log likelihood.

   :param ll: the loglikelihood to compute the gradients over
   :type ll: TensorVariable
   :param params: list of params to compute the gradients over
   :type params: list

   :returns: the outer product of the gradient with ndim=2
   :rtype: TensorVariable

   .. note:: Parameters with status=1 are ignored.


.. py:function:: gnorm(cost: aesara.tensor.var.TensorVariable, params: list[pycmtensor.expressions.Beta])

   Symbolic representation of the gradient norm given the cost.

   :param cost: the cost to compute the gradients over
   :type cost: TensorVariable
   :param params: list of params to compute the gradients over
   :type params: list

   :returns: the gradient norm value
   :rtype: TensorVariable

   .. note:: Parameters with status=1 are ignored.


