Skip to content

Commit

Permalink
Removing Boost and GLM from workflow and updating tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ifilot committed Dec 5, 2023
1 parent 521322d commit 0c35f19
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 71 deletions.
31 changes: 2 additions & 29 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
steps:
- name: Install dependencies
run: |
yum -y install eigen3-devel libgomp boost-devel mlocate gcc
yum -y install libgomp mlocate gcc
/opt/python/cp37-cp37m/bin/python -m pip install numpy scipy tqdm cython pytest
/opt/python/cp38-cp38/bin/python -m pip install numpy scipy tqdm cython pytest
/opt/python/cp39-cp39/bin/python -m pip install numpy scipy tqdm cython pytest
Expand Down Expand Up @@ -50,29 +50,6 @@ jobs:
environment-file: environment.yml
python-version: 3.8
auto-activate-base: false
- name: Download GLM
uses: suisei-cn/actions-download-file@v1.4.0
with:
url: "https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip"
- name: Unzip GLM
shell: bash -l {0}
run: |
7z x eigen-3.4.0.zip
- name: Download Boost
uses: suisei-cn/actions-download-file@v1.4.0
with:
url: "https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.zip"
- name: Unzip Boost
shell: bash -l {0}
run: |
7z x boost_1_82_0.zip
- name: Placing dependencies
shell: bash -l {0}
run: |
rm -v boost_1_82_0.zip eigen-3.4.0.zip
mkdir vendor
mv eigen-3.4.0 vendor/
mv boost_1_82_0 vendor/
- name: Set-up MSVC toolchain
uses: ilammy/msvc-dev-cmd@v1
with:
Expand All @@ -97,7 +74,7 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential libeigen3-dev libboost-all-dev
run: sudo apt-get update && sudo apt-get install -y build-essential
- name: Set-up miniconda
uses: conda-incubator/setup-miniconda@v2
with:
Expand All @@ -123,10 +100,6 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install dependencies
run: |
brew install eigen
brew install boost
- name: Set-up miniconda
uses: conda-incubator/setup-miniconda@v2
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,4 @@ wheelhouse/*
test.py
nose_debug
anaconda-upload/*
*.vscode
4 changes: 4 additions & 0 deletions pyqint/hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def rhf(self, mol, basis, calc_forces=False, itermax=100,
verbose: whether verbose output is given
"""

# crank up the tolerance when calculating forces
if calc_forces and tolerance > 1e-12:
tolerance = 1e-12

# create empty dictionary for time tracking statistics
time_stats = {}

Expand Down
36 changes: 30 additions & 6 deletions pyqint/integrals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ double Integrator::overlap_1D(int l1, int l2, double x1, double x2, double gamma

for(int i=0; i < (1 + std::floor(0.5 * (l1 + l2))); i++) {
sum += this->binomial_prefactor(2*i, l1, l2, x1, x2) *
(i == 0 ? 1 : boost::math::double_factorial<double>(2 * i - 1) ) /
(i == 0 ? 1 : this->double_factorial(2 * i - 1) ) /
std::pow(2 * gamma, i);
}

Expand Down Expand Up @@ -1042,7 +1042,7 @@ double Integrator::binomial(int a, int b) const {
if( (a < 0) | (b < 0) | (a-b < 0) ) {
return 1.0;
}
return boost::math::factorial<double>(a) / (boost::math::factorial<double>(b) * boost::math::factorial<double>(a-b));
return this->factorial(a) / (this->factorial(b) * this->factorial(a-b));
}

double Integrator::nuclear(const vec3& a, int l1, int m1, int n1, double alpha1,
Expand Down Expand Up @@ -1092,8 +1092,8 @@ std::vector<double> Integrator::A_array(const int l1, const int l2, const double

double Integrator::A_term(const int i, const int r, const int u, const int l1, const int l2, const double pax, const double pbx, const double cpx, const double gamma) const {
return std::pow(-1,i) * this->binomial_prefactor(i,l1,l2,pax,pbx)*
std::pow(-1,u) * boost::math::factorial<double>(i)*std::pow(cpx,i-2*r-2*u)*
std::pow(0.25/gamma,r+u)/boost::math::factorial<double>(r)/boost::math::factorial<double>(u)/boost::math::factorial<double>(i-2*r-2*u);
std::pow(-1,u) * this->factorial(i)*std::pow(cpx,i-2*r-2*u)*
std::pow(0.25/gamma,r+u)/this->factorial(r)/this->factorial(u)/this->factorial(i-2*r-2*u);
}

/**
Expand Down Expand Up @@ -1254,8 +1254,8 @@ double Integrator::B0(int i, int r, double g) const {
return fact_ratio2(i,r) * pow(4*g,r-i);
}

double Integrator::fact_ratio2(const int a, const int b) const {
return boost::math::factorial<double>(a) / boost::math::factorial<double>(b) / boost::math::factorial<double>(a - 2*b);
double Integrator::fact_ratio2(unsigned int a, unsigned int b) const {
return this->factorial(a) / this->factorial(b) / this->factorial(a - 2*b);
}

size_t Integrator::teindex(size_t i, size_t j, size_t k, size_t l) const {
Expand All @@ -1276,6 +1276,30 @@ size_t Integrator::teindex(size_t i, size_t j, size_t k, size_t l) const {
return ij * (ij + 1) / 2 + kl;
}

double Integrator::factorial(unsigned int n) const {
static const double ans[] = {
1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368000
};

if(n > 15) {
return n * this->factorial(n-1);
} else {
return ans[n];
}
}

double Integrator::double_factorial(unsigned int n) const {
static const double ans[] = {
1,1,2,3,8,15,48,105,384,945,3840,10395,46080,135135,645120,2027025
};

if(n > 15) {
return n * this->double_factorial(n-2);
} else {
return ans[n];
}
}

void Integrator::init() {
std::unordered_map<unsigned int, std::string> map{
{200505,"2.5"},
Expand Down
10 changes: 5 additions & 5 deletions pyqint/integrals.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@

#pragma once

#include <boost/math/special_functions/binomial.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <unordered_map>

Expand Down Expand Up @@ -681,7 +677,11 @@ class Integrator {

double fB(const int i, const int l1, const int l2, const double p, const double a, const double b, const int r, const double q) const;
double B0(int i, int r, double q) const;
double fact_ratio2(const int a, const int b) const;
double fact_ratio2(unsigned int a, unsigned int b) const;

double factorial(unsigned int n) const;

double double_factorial(unsigned int n) const;

void init();
};
5 changes: 0 additions & 5 deletions pyqint/plotter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@

#pragma once

#include <boost/math/special_functions/binomial.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <string>
#include <unordered_map>

#include "cgf.h"

class Plotter {
Expand Down
14 changes: 0 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,7 @@ def find_windows_versions():
os.environ['LIB'] += r";C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\%s\lib\x64" % msvc_ver
os.environ['LIB'] += r";C:\Program Files (x86)\Windows Kits\10\Lib\%s\um\x64" % winkit_ver
os.environ['LIB'] += r";C:\Program Files (x86)\Windows Kits\10\Lib\%s\ucrt\x64" % winkit_ver

# also specify some custom paths for libraries
os.environ['INCLUDE'] += r";C:\PROGRAMMING\LIBS\boost-1.74.0-win-x64\include" # boost library
os.environ['INCLUDE'] += r";D:\PROGRAMMING\LIBS\boost-1.74.0-win-x64\include" # boost library
os.environ['INCLUDE'] += r";C:\PROGRAMMING\LIBS\eigen-3.3.9" # eigen3 linear algebra library
os.environ['INCLUDE'] += r";D:\PROGRAMMING\LIBS\eigen-3.3.9" # eigen3 linear algebra library
else:
# if msvc_ver and winkit_ver are set to None, this means we are working on Gitlab Actions
# which requires the paths to be set differently; we here set the paths to eigen3 and boost
os.environ['INCLUDE'] += r";" + os.environ['GITHUB_WORKSPACE'] + r"\vendor\eigen-3.4.0"
os.environ['INCLUDE'] += r";" + os.environ['GITHUB_WORKSPACE'] + r"\vendor\boost_1_82_0"

# re-order paths to ensure that the MSVC toolchain is in front; this needs to be done
# because the Git bin folder precedes the MSVC bin folder, resulting in the wrong link.exe
# executable to be used in the linking step
Expand All @@ -94,9 +83,6 @@ def find_windows_versions():
extra_compile_args = ["/openmp"]
extra_link_args = []
elif sys.platform == 'darwin':
#os.environ['CC'] = "/usr/local/Cellar/gcc/11.2.0_3/bin/gcc-11"
#os.environ['CXX'] = "/usr/local/Cellar/gcc/11.2.0_3/bin/c++-11"
os.environ['CFLAGS'] = '-I/usr/local/Cellar/boost/1.76.0/include -I/usr/local/Cellar/eigen/3.4.0_1/include/eigen3'
extra_compile_args = ["-Wno-date-time", "-fPIC", "-std=c++11"]
extra_link_args = []

Expand Down
8 changes: 4 additions & 4 deletions tests/test_geometry_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_optimization_h2_p321(self):
mol.add_atom('H', -0.9, 0.0, 0.0)

res = GeometryOptimization(verbose=False).run(mol, 'p321')
np.testing.assert_almost_equal(res['opt'].fun, -1.1229598312004625, decimal=4)
np.testing.assert_almost_equal(res['opt'].fun, -1.1232790915, decimal=4)

self.assertEqual(len(res['energies']), len(res['forces']))
self.assertEqual(len(res['energies']), len(res['coordinates']))
Expand Down Expand Up @@ -75,7 +75,7 @@ def test_optimization_ch4(self):
mol.add_atom('H', dist, -dist, -dist, unit='angstrom')

res = GeometryOptimization(verbose=False).run(mol, 'sto3g')
np.testing.assert_almost_equal(res['opt'].fun, -39.7268635)
np.testing.assert_almost_equal(res['opt'].fun, -39.726905821)

self.assertEqual(len(res['energies']), len(res['forces']))
self.assertEqual(len(res['energies']), len(res['coordinates']))
Expand All @@ -102,7 +102,7 @@ def test_optimization_h2o(self):
mol.add_atom('H', 0.0, 0.8580158822, 0.5085242828, unit='angstrom')

res = GeometryOptimization(verbose=False).run(mol, 'sto3g')
np.testing.assert_almost_equal(res['opt'].fun, -74.96590013836217)
np.testing.assert_almost_equal(res['opt'].fun, -74.9658999323)

self.assertEqual(len(res['energies']), len(res['forces']))
self.assertEqual(len(res['energies']), len(res['coordinates']))
Expand Down Expand Up @@ -132,7 +132,7 @@ def test_optimization_c2h4(self):
mol.add_atom('H', 1.1288875372, -0.9156191261 ,0.1000000000, unit='angstrom')

res = GeometryOptimization(verbose=False).run(mol, 'sto3g')
np.testing.assert_almost_equal(res['opt'].fun, -77.0739544)
np.testing.assert_almost_equal(res['opt'].fun, -77.073956517)

self.assertEqual(len(res['energies']), len(res['forces']))
self.assertEqual(len(res['energies']), len(res['coordinates']))
Expand Down
4 changes: 2 additions & 2 deletions tests/test_hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def test_hartree_fock_h2o(self):
np.testing.assert_almost_equal(results['energy'], -73.21447132, 4)

# verify that terms are being calculated
np.testing.assert_almost_equal(results['density'], np.einsum('ik,jk,k->ij', results['orbc'], results['orbc'], [2,2,2,2,2,0,0]), decimal=7)
np.testing.assert_almost_equal(results['ekin'] + results['enuc'] + results['erep'] + results['ex'] + results['enucrep'], results['energy'], decimal=7)
np.testing.assert_almost_equal(results['density'], np.einsum('ik,jk,k->ij', results['orbc'], results['orbc'], [2,2,2,2,2,0,0]), decimal=5)
np.testing.assert_almost_equal(results['ekin'] + results['enuc'] + results['erep'] + results['ex'] + results['enucrep'], results['energy'], decimal=5)

def test_hartree_fock_ch4(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_hf_deriv.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_hartree_fock_forces_co2(self):
np.testing.assert_almost_equal(res['forces'], forces, decimal=3)

def perform_hf(mol):
sol = HF().rhf(mol, 'sto3g')
sol = HF().rhf(mol, 'sto3g', tolerance=1e-12)
return sol

def calculate_forces_finite_difference(mol):
Expand All @@ -97,7 +97,7 @@ def calculate_forces_finite_difference(mol):
"""
forces = np.zeros((len(mol.atoms),3))

sz = 1e-4
sz = 1e-3

for i in range(0, len(mol.atoms)): # loop over nuclei
for j in range(0, 3): # loop over directions
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hf_molecules.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def testC2H4(self):
results = HF().rhf(mol, 'sto3g')

# check that energy matches
np.testing.assert_almost_equal(results['energy'], -77.0739544, 5)
np.testing.assert_almost_equal(results['energy'], -77.07397265708258, 5)

def testBF3(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_molecule_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def build_mol_order1():
mol.add_atom('H', 1.2288875372, 0.9156191261 ,0.0000000000, unit='angstrom')
mol.add_atom('H', 1.2288875372, -0.9156191261 ,0.0000000000, unit='angstrom')

results = HF().rhf(mol, basis='sto3g', verbose=True)
results = HF().rhf(mol, basis='sto3g', tolerance=1e-12)

return results

Expand All @@ -54,7 +54,7 @@ def build_mol_order2():
mol.add_atom('H', 1.2288875372, 0.9156191261 ,0.0000000000, unit='angstrom')
mol.add_atom('H', 1.2288875372, -0.9156191261 ,0.0000000000, unit='angstrom')

results = HF().rhf(mol, basis='sto3g', verbose=True)
results = HF().rhf(mol, basis='sto3g', tolerance=1e-12)

return results

Expand Down
1 change: 0 additions & 1 deletion tests/test_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def test_version(self):
self.assertTrue(strver[0].isnumeric())
self.assertTrue(strver[1].isnumeric())
self.assertTrue(strver[2].isnumeric())
self.assertTrue(strver[3].isnumeric())

@nottest
def test_compiler_info(self):
Expand Down

0 comments on commit 0c35f19

Please sign in to comment.