GMMExpectationMaximization::Real GMMExpectationMaximization::gauss(const VectorX & mean, const MatrixX & cov,const VectorX & pt) const { Real det = cov.determinant(); uint dim = mean.size(); // check that the covariance matrix is invertible if (std::abs(det) < std::pow(m_epsilon,dim) * 0.1) return 0.0; // the gaussian has approximately zero width: the probability of any point falling into it is approximately 0. // else, compute pdf MatrixX inverse_cov = cov.inverse(); VectorX dist = pt - mean; Real exp = - (dist.dot(inverse_cov * dist)) / 2.0; Real den = std::sqrt(std::pow(2.0 * M_PI,dim) * std::abs(det)); return std::exp(exp) / den; }
void SlaterSet::initCalculation() { if (m_initialized) return; m_normalized.resize(m_overlap.cols(), m_overlap.rows()); SelfAdjointEigenSolver<MatrixX> s(m_overlap); MatrixX p = s.eigenvectors(); MatrixX m = p * s.eigenvalues().array().inverse().array().sqrt() .matrix().asDiagonal() * p.inverse(); m_normalized = m * m_eigenVectors; if (!(m_overlap * m * m).eval().isIdentity()) cout << "Identity test FAILED - do you need a newer version of Eigen?\n"; m_factors.resize(m_zetas.size()); m_PQNs = m_pqns; // Calculate the normalizations of the orbitals. for (size_t i = 0; i < m_zetas.size(); ++i) { switch (m_slaterTypes[i]) { case S: m_factors[i] = pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(1.0 / (4.0 * M_PI) / factorial(2 * m_pqns[i])); m_PQNs[i] -= 1; break; case PX: case PY: case PZ: m_factors[i] = pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(3.0 / (4.0 * M_PI) / factorial(2 * m_pqns[i])); m_PQNs[i] -= 2; break; case X2: m_factors[i] = 0.5 * pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(15.0 / (4.0 * M_PI) / factorial(2 * m_pqns[i])); m_PQNs[i] -= 3; break; case XZ: m_factors[i] = pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(15.0 / (4.0 * M_PI) / factorial(2 * m_pqns[i])); m_PQNs[i] -= 3; break; case Z2: m_factors[i] = (0.5 / sqrt(3.0)) * pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(15.0 / (4.0 * M_PI) / factorial(2 * m_pqns[i])); m_PQNs[i] -= 3; break; case YZ: case XY: m_factors[i] = pow(2.0 * m_zetas[i], m_pqns[i] + 0.5) * sqrt(15.0 / (4.0*M_PI) / factorial(2*m_pqns[i])); m_PQNs[i] -= 3; break; default: cout << "Orbital " << i << " not handled, type " << m_slaterTypes[i] << endl; } } // Convert the exponents into Angstroms for (size_t i = 0; i < m_zetas.size(); ++i) m_zetas[i] = m_zetas[i] / BOHR_TO_ANGSTROM; m_initialized = true; }