Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
df21116
Add N-center Gaussian overlap engine with screening and sparse builde…
Feb 14, 2026
15bb7f7
Remove experimental sparse builder test (not part of Week 1–2)
Feb 14, 2026
76d843d
Move overlap test files to tests directory as requested in review
Feb 20, 2026
ff83f68
Remove unrelated/extra test files from PR
Feb 20, 2026
2736394
Remove incorrect duplicate integrals package
Feb 20, 2026
9019e15
Remove multi_overlap.py (belongs to Week 3, not this PR)
Feb 20, 2026
a1a43c3
Week 3: Add arbitrary order overlap tests (N=1 to N=6)
Feb 22, 2026
07791e2
Week 4: Add intracule and extracule density API
Feb 24, 2026
30adfdd
Week-5: Add tests, benchmarks, and real-basis validation for density API
Feb 28, 2026
274c5bc
Style: format code with black as requested
Mar 2, 2026
8808549
Add N-center Gaussian overlap engine with screening and sparse builde…
Feb 14, 2026
c7f4855
Week 3: Add arbitrary order overlap tests (N=1 to N=6)
Feb 22, 2026
f35fb6c
Week 4: Add intracule and extracule density API
Feb 24, 2026
6699cab
Week-5: Add tests, benchmarks, and real-basis validation for density API
Feb 28, 2026
5713d20
Style: format code with black as requested
Mar 2, 2026
fae8598
Move performance benchmark out of tests as suggested in review
Mar 11, 2026
c0d035a
Add benchmark script for compute_intracule and compute_extracule
Mar 11, 2026
a0070c8
Improve documentation and apply black formatting
Mar 13, 2026
da9e530
Improve documentation for density API functions
Mar 13, 2026
446e674
Merge branch 'master' into feat/woc-final-weeks1-5
kir943 Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gbasis/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base class for arrays that depend on one or more contracted Gaussians."""

import abc

from gbasis.contractions import GeneralizedContractionShell
Expand Down
1 change: 1 addition & 0 deletions gbasis/base_four_symm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base class for arrays that depend on four contracted Gaussians."""

import abc
import itertools as it

Expand Down
1 change: 1 addition & 0 deletions gbasis/base_one.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base class for arrays that depend on one contracted Gaussian."""

import abc

from gbasis.base import BaseGaussianRelatedArray
Expand Down
1 change: 1 addition & 0 deletions gbasis/base_two_asymm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base class for arrays that depend on two contracted Gaussians."""

import abc

from gbasis.base import BaseGaussianRelatedArray
Expand Down
5 changes: 2 additions & 3 deletions gbasis/evals/_deriv.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Derivative of a Gaussian Contraction."""

import numpy as np
from scipy.special import comb, eval_hermite, perm

Expand Down Expand Up @@ -129,9 +130,7 @@ def _eval_deriv_contractions(coords, orders, center, angmom_comps, alphas, prim_
# to evaluate multiple orders at the same time. Creating/finding a better function for
# evaluating the hermite polynomial at different orders (in sequence) may be nice in the
# future.
hermite = np.sum(
coeffs * eval_hermite(indices_herm, alphas**0.5 * nonzero_coords), axis=0
)
hermite = np.sum(coeffs * eval_hermite(indices_herm, alphas**0.5 * nonzero_coords), axis=0)
hermite = np.prod(hermite, axis=1)

# NOTE: `hermite` now has axis 0 for primitives, 1 for angular momentum vector, and axis 2
Expand Down
9 changes: 6 additions & 3 deletions gbasis/evals/electrostatic_potential.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module for computing electrostatic potential integrals."""

from gbasis.integrals.point_charge import point_charge_integral
import numpy as np

Expand Down Expand Up @@ -121,9 +122,11 @@ def electrostatic_potential(
elif isinstance(coord_type, (list, tuple)):
if (
sum(
cont.num_sph * cont.num_seg_cont
if j == "spherical"
else cont.num_cart * cont.num_seg_cont
(
cont.num_sph * cont.num_seg_cont
if j == "spherical"
else cont.num_cart * cont.num_seg_cont
)
for cont, j in zip(basis, coord_type)
)
!= one_density_matrix.shape[0]
Expand Down
1 change: 1 addition & 0 deletions gbasis/evals/stress_tensor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module for computing properties related to the stress tensor."""

from gbasis.evals.density import (
evaluate_density_laplacian,
evaluate_deriv_density,
Expand Down
3 changes: 3 additions & 0 deletions gbasis/integrals/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
"""Collection of modules that compute different integrals of the contractions."""

from .density import compute_intracule
from .density import compute_extracule
1 change: 1 addition & 0 deletions gbasis/integrals/_diff_operator_int.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Integrals over differential operator involving contracted Cartesian Gaussians."""

from gbasis.integrals._moment_int import (
_cleanup_intermediate_integrals,
_compute_multipole_moment_integrals_intermediate,
Expand Down
1 change: 1 addition & 0 deletions gbasis/integrals/_moment_int.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Multipole moment integrals involving Contracted Cartesian Gaussians."""

import numpy as np


Expand Down
1 change: 1 addition & 0 deletions gbasis/integrals/_one_elec_int.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""One-electron integrals involving Contracted Cartesian Gaussians."""

import numpy as np
from gbasis.utils import factorial2

Expand Down
1 change: 1 addition & 0 deletions gbasis/integrals/_two_elec_int.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Two-electron integrals involving Contracted Cartesian Gaussians."""

import numpy as np
from gbasis.utils import factorial2

Expand Down
137 changes: 137 additions & 0 deletions gbasis/integrals/density.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
"""
Density API built on top of the arbitrary-order Gaussian overlap engine.

This module provides high-level routines for constructing matrices of
Gaussian overlap integrals between shells. These matrices serve as
building blocks in density-related calculations such as intracule and
extracule analysis.

The overlap integrals are evaluated using the arbitrary-order Gaussian
overlap engine implemented in ``arbitrary_order_overlap``.
"""

import numpy as np

from .overlap_n import arbitrary_order_overlap


def compute_intracule(shells):
"""
Compute pairwise intracule overlap matrix between Gaussian shells.

This function constructs a matrix whose elements correspond to
two-center overlap integrals between Gaussian basis functions.
Each matrix element represents the overlap integral

.. math::

S_{ij} = \\int \\phi_i(\\mathbf{r}) \\phi_j(\\mathbf{r}) \\, d\\mathbf{r}

where :math:`\\phi_i` and :math:`\\phi_j` are Cartesian Gaussian basis
functions centered on different atoms or centers.

The overlap integrals are evaluated using the
:func:`arbitrary_order_overlap` engine, which computes Gaussian
overlap tensors of arbitrary order.

Parameters
----------
shells : list[GeneralizedContractionShell]
List of Gaussian shells defining the basis functions.

Returns
-------
numpy.ndarray
Array of shape ``(n, n)`` containing pairwise Gaussian
overlap integrals between shells.

Notes
-----
The intracule matrix is constructed by evaluating pairwise
two-center overlap integrals between Gaussian shells. Each
integral is extracted from the sparse tensor returned by the
arbitrary-order overlap engine.

References
----------
Helgaker, T., Jørgensen, P., Olsen, J.
*Molecular Electronic-Structure Theory*, Wiley (2000).

Szabo, A., Ostlund, N. S.
*Modern Quantum Chemistry*, Dover (1996).
"""
n = len(shells)

result = np.zeros((n, n))
Comment on lines +13 to +65
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gbasis.integrals.density introduces new public APIs but the module and functions have no docstrings and no input validation (contrast with other integrals modules like overlap.py / point_charge.py which document parameters/returns and type-check GeneralizedContractionShell). Adding docstrings and basic type/shape checks would make the API safer and consistent with the rest of the package.

Copilot uses AI. Check for mistakes.

for i in range(n):
for j in range(n):

tensor = arbitrary_order_overlap([shells[i], shells[j]])

# Extract scalar overlap value from sparse tensor returned by
# the arbitrary-order overlap engine.
value = tensor.data[0] if tensor.nnz > 0 else 0.0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, but I don't understand this function. Needs more documentation.


result[i, j] = value
Comment on lines +70 to +76
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compute_intracule calls arbitrary_order_overlap([shells[i], shells[j]]), but arbitrary_order_overlap returns a tensor over all shell index combinations for the provided list (via product(range(len(shells)), repeat=N) in build_n_overlap_tensor). Reading tensor.data[0] therefore does not reliably correspond to the (i,j) pair and will return arbitrary nonzero entries depending on COO ordering. Consider computing the specific 2-center overlap block directly (e.g., via contracted_n_overlap([shells[i], shells[j]]) / existing Overlap.construct_array_contraction) or building the full 2-center tensor once and indexing the correct element deterministically.

Copilot uses AI. Check for mistakes.

return result


def compute_extracule(shells):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have two functions that do the same?

"""
Compute pairwise extracule overlap matrix between Gaussian shells.

This function constructs a matrix of pairwise overlap integrals
between Gaussian shells using the arbitrary-order overlap engine.

Each matrix element corresponds to the two-center Gaussian
overlap integral

.. math::

S_{ij} = \\int \\phi_i(\\mathbf{r}) \\phi_j(\\mathbf{r}) \\, d\\mathbf{r}

where :math:`\\phi_i` and :math:`\\phi_j` are Cartesian Gaussian
basis functions.

Parameters
----------
shells : list[GeneralizedContractionShell]
List of Gaussian shells defining the basis functions.

Returns
-------
numpy.ndarray
Array of shape ``(n, n)`` containing pairwise Gaussian
overlap integrals between shells.

Notes
-----
This function provides an API wrapper around the
:func:`arbitrary_order_overlap` routine for density-related
calculations involving Gaussian basis functions.
This function currently constructs the same overlap matrix as
:func:`compute_intracule`, but is provided as a separate API
entry point for extracule-related density calculations.

References
----------
Helgaker, T., Jørgensen, P., Olsen, J.
*Molecular Electronic-Structure Theory*, Wiley (2000).
"""
n = len(shells)

result = np.zeros((n, n))

for i in range(n):
for j in range(n):
# evaluate two-center Gaussian overlap tensor between shells i and j
tensor = arbitrary_order_overlap([shells[i], shells[j]])

# extract scalar overlap value from sparse tensor
value = tensor.data[0] if tensor.nnz > 0 else 0.0

result[i, j] = value

return result
Comment on lines +123 to +137
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compute_extracule is currently identical to compute_intracule (same 2-center overlap call and scalar extraction). Unless intracule/extracule are intentionally the same quantity in this codebase, this looks like a placeholder implementation and will mislead API consumers. Please implement the distinct definition for extracule (or remove/rename one of the APIs).

Suggested change
n = len(shells)
result = np.zeros((n, n))
for i in range(n):
for j in range(n):
tensor = arbitrary_order_overlap([shells[i], shells[j]])
value = tensor.data[0] if tensor.nnz > 0 else 0.0
result[i, j] = value
return result
"""
Compute the extracule density matrix.
This function is currently not implemented. It previously duplicated
the intracule implementation, which is misleading because the
extracule and intracule are generally distinct quantities.
"""
raise NotImplementedError(
"compute_extracule is not implemented: previous implementation "
"was a placeholder duplicating compute_intracule."
)

Copilot uses AI. Check for mistakes.
3 changes: 2 additions & 1 deletion gbasis/integrals/libcint.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

from gbasis.utils import factorial2


__all__ = [
"LIBCINT",
"CBasis",
Expand Down Expand Up @@ -193,6 +192,7 @@ def from_param(cls, obj):

class PairData(Structure):
r"""``libcint`` ``PairData`` class."""

_fields_ = [
("rij", c_double * 3),
("eij", c_double),
Expand All @@ -202,6 +202,7 @@ class PairData(Structure):

class CINTOpt(Structure):
r"""``libcint`` ``CINTOpt`` class."""

_fields_ = [
("index_xyz_array", POINTER(POINTER(c_int))),
("non0ctr", POINTER(POINTER(c_int))),
Expand Down
1 change: 1 addition & 0 deletions gbasis/integrals/nuclear_electron_attraction.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module for computing the nuclear electron attraction."""

from gbasis.integrals.point_charge import point_charge_integral
import numpy as np

Expand Down
Loading
Loading