# Path: phydmslib/constants.py
# N_CODON = len(CODON_TO_INDEX)
# 
# CODON_NONSYN = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_TRANSITION = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_SINGLEMUT = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# ALMOST_ZERO = 1.0e-6
# 
# CODON_NT_INDEX = numpy.full((3, N_CODON), -1, dtype='int')
# 
# STOP_CODON_TO_NT_INDICES = []
# 
# N_STOP = 0
# 
# N_NT = len(INDEX_TO_NT)
# 
# N_AA = len(INDEX_TO_AA)
# 
# INDEX_TO_NT = dict(enumerate('ACGT'))
# 
# CODON_NT_MUT = numpy.full((N_NT, N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_NT_COUNT = numpy.zeros((N_NT, N_CODON), dtype='int')
# 
# CODON_TO_AA = []
# 
# INDEX_TO_AA = dict(enumerate('ACDEFGHIKLMNPQRSTVWY'))
# 
# AA_TO_INDEX = {aa: i for (i, aa) in INDEX_TO_AA.items()}
# 
# CODON_NT = numpy.full((3, N_NT, N_CODON), False, dtype='bool')


import copy
import six
import abc
import warnings
import numpy
import scipy.misc
import scipy.optimize
import scipy.linalg
import scipy.stats
import scipy.special
    import doctest
from phydmslib.numutils import (broadcastMatrixMultiply,
                                broadcastMatrixVectorMultiply,
                                broadcastGetCols)
from phydmslib.constants import (N_CODON, CODON_NONSYN, CODON_TRANSITION,
                                 CODON_SINGLEMUT, ALMOST_ZERO, CODON_NT_INDEX,
                                 STOP_CODON_TO_NT_INDICES, N_STOP, N_NT, N_AA,
                                 INDEX_TO_NT, CODON_NT_MUT, CODON_NT_COUNT,
                                 CODON_TO_AA, INDEX_TO_AA, AA_TO_INDEX,
                                 CODON_NT)
        These are `pi_codon`, `ln_pi_codon`, `piAx_piAy`, `piAx_piAy_beta`,
        `ln_piAx_piAy_beta`.

        Update using current `pi` and `beta`.
        """
        with numpy.errstate(divide='raise', under='raise', over='raise',
                            invalid='raise'):
            for r in range(self.nsites):
                self.pi_codon[r] = self.pi[r][CODON_TO_AA]
                # [x][y] is piAy
                pim = numpy.tile(self.pi_codon[r], (N_CODON, 1))
                self.piAx_piAy[r] = pim.transpose() / pim
            self.ln_pi_codon = numpy.log(self.pi_codon)
            self.piAx_piAy_beta = self.piAx_piAy**self.beta
            self.ln_piAx_piAy_beta = numpy.log(self.piAx_piAy_beta)

    def _update_Frxy(self):
        """
        Update `Frxy` from `piAx_piAy_beta`,`ln_piAx_piAy_beta`,
        `omega`,`beta`.
        """
        self.Frxy.fill(1.0)
        self.Frxy_no_omega.fill(1.0)
        with numpy.errstate(divide='raise', under='raise', over='raise',
                            invalid='ignore'):
            (numpy
             .copyto(self.Frxy_no_omega, -self.ln_piAx_piAy_beta / (1 - self.piAx_piAy_beta),  # noqa: E501
                     where=numpy.logical_and(CODON_NONSYN, numpy.fabs(1 - self.piAx_piAy_beta)  # noqa: E501
                                             > ALMOST_ZERO)))
        numpy.copyto(self.Frxy, self.Frxy_no_omega * self.omega,

# Path: phydmslib/constants.py
# N_CODON = len(CODON_TO_INDEX)
# 
# CODON_NONSYN = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_TRANSITION = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_SINGLEMUT = numpy.full((N_CODON, N_CODON), False, dtype='bool')
# 
# ALMOST_ZERO = 1.0e-6
# 
# CODON_NT_INDEX = numpy.full((3, N_CODON), -1, dtype='int')
# 
# STOP_CODON_TO_NT_INDICES = []
# 
# N_STOP = 0
# 
# N_NT = len(INDEX_TO_NT)
# 
# N_AA = len(INDEX_TO_AA)
# 
# INDEX_TO_NT = dict(enumerate('ACGT'))
# 
# CODON_NT_MUT = numpy.full((N_NT, N_CODON, N_CODON), False, dtype='bool')
# 
# CODON_NT_COUNT = numpy.zeros((N_NT, N_CODON), dtype='int')
# 
# CODON_TO_AA = []
# 
# INDEX_TO_AA = dict(enumerate('ACDEFGHIKLMNPQRSTVWY'))
# 
# AA_TO_INDEX = {aa: i for (i, aa) in INDEX_TO_AA.items()}
# 
# CODON_NT = numpy.full((3, N_NT, N_CODON), False, dtype='bool')


# Path: phydmslib/models.py
import copy
import six
import abc
import warnings
import numpy
import scipy.misc
import scipy.optimize
import scipy.linalg
import scipy.stats
import scipy.special
    import doctest
from phydmslib.numutils import (broadcastMatrixMultiply,
                                broadcastMatrixVectorMultiply,
                                broadcastGetCols)
from phydmslib.constants import (N_CODON, CODON_NONSYN, CODON_TRANSITION,
                                 CODON_SINGLEMUT, ALMOST_ZERO, CODON_NT_INDEX,
                                 STOP_CODON_TO_NT_INDICES, N_STOP, N_NT, N_AA,
                                 INDEX_TO_NT, CODON_NT_MUT, CODON_NT_COUNT,
                                 CODON_TO_AA, INDEX_TO_AA, AA_TO_INDEX,
                                 CODON_NT)

        These are `pi_codon`, `ln_pi_codon`, `piAx_piAy`, `piAx_piAy_beta`,
        `ln_piAx_piAy_beta`.

        Update using current `pi` and `beta`.
        """
        with numpy.errstate(divide='raise', under='raise', over='raise',
                            invalid='raise'):
            for r in range(self.nsites):
                self.pi_codon[r] = self.pi[r][CODON_TO_AA]
                # [x][y] is piAy
                pim = numpy.tile(self.pi_codon[r], (N_CODON, 1))
                self.piAx_piAy[r] = pim.transpose() / pim
            self.ln_pi_codon = numpy.log(self.pi_codon)
            self.piAx_piAy_beta = self.piAx_piAy**self.beta
            self.ln_piAx_piAy_beta = numpy.log(self.piAx_piAy_beta)

    def _update_Frxy(self):
        """
        Update `Frxy` from `piAx_piAy_beta`,`ln_piAx_piAy_beta`,
        `omega`,`beta`.
        """
        self.Frxy.fill(1.0)
        self.Frxy_no_omega.fill(1.0)
        with numpy.errstate(divide='raise', under='raise', over='raise',
                            invalid='ignore'):
            (numpy
             .copyto(self.Frxy_no_omega, -self.ln_piAx_piAy_beta / (1 - self.piAx_piAy_beta),  # noqa: E501
                     where=numpy.logical_and(CODON_NONSYN, numpy.fabs(1 - self.piAx_piAy_beta)  # noqa: E501
                                             > ALMOST_ZERO)))
        numpy.copyto(self.Frxy, self.Frxy_no_omega * self.omega,

                     where=CODON_NONSYN)