Skip to content

Commit

Permalink
Comment, and add binom_factor_direct to motivate the other cases
Browse files Browse the repository at this point in the history
  • Loading branch information
awf committed Oct 11, 2023
1 parent 0d64b26 commit 8c241d3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 21 deletions.
28 changes: 10 additions & 18 deletions notebooks/binom_factor_table.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,9 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
Expand Down Expand Up @@ -157,25 +150,24 @@
"\n",
"\n",
"def binom_factor(i: int, j: int, a: float, b: float, s: int):\n",
" out = 0\n",
" for t in range(max(s - i, 0), j + 1):\n",
" assert ((s - i) <= t) & (t <= j)\n",
" val = binom(i, s - t) * binom(j, t) * a ** (i - (s - t)) * b ** (j - t)\n",
" out += val\n",
" return out\n",
" return sum(\n",
" binom(i, s - t) * binom(j, t) * a ** (i - (s - t)) * b ** (j - t)\n",
" for t in range(max(s - i, 0), j + 1)\n",
" )\n",
"\n",
"\n",
"def binom_factor_sym(i: int, j: int, a: Symbol, b: Symbol, s: int):\n",
" return Poly(binom_factor(i, j, a, b, s), a, b)\n",
"\n",
"\n",
"a, b = symbols(\"a b\", real=True)\n",
"for i in range(0,7,3):\n",
" for j in range(0,7,2):\n",
" for s in range(0,7,2):\n",
"for i in range(0, 7, 3):\n",
" for j in range(0, 7, 2):\n",
" for s in range(0, 7, 2):\n",
" bf = binom_factor_sym(i, j, a, b, s)\n",
" print((i, j, s), bf)\n",
"\n",
"display(bf, bf.coeff_monomial(a**3*b**3))"
"display(bf, bf.coeff_monomial(a**3 * b**3))"
]
},
{
Expand Down
22 changes: 19 additions & 3 deletions pyscf_ipu/experimental/special.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def factorial2_lookup(n: IntN, nmax: int = 2 * LMAX) -> IntN:

factorial2 = factorial2_lookup

# Various binom implementations


def binom_beta(x: IntN, y: IntN) -> IntN:
approx = 1.0 / ((x + 1) * jnp.exp(betaln(x - y + 1, y + 1)))
Expand All @@ -78,6 +80,8 @@ def binom_lookup(x: IntN, y: IntN, nmax: int = LMAX) -> IntN:

binom = binom_lookup

# Various gammanu implementations


def gammanu_gamma(nu: IntN, t: FloatN, epsilon: float = 1e-10) -> FloatN:
"""
Expand Down Expand Up @@ -117,15 +121,26 @@ def gammanu_series(nu: IntN, t: FloatN, num_terms: int = 128) -> FloatN:
gammanu = gammanu_series


def binom_factor_segment_sum(
i: int, j: int, a: float, b: float, lmax: int = LMAX
) -> FloatN:
# Several binom_factor implementations


def binom_factor_direct(i: int, j: int, a: float, b: float, s: int):
"""
Eq. 15 from Augspurger JD, Dykstra CE. General quantum mechanical operators. An
open-ended approach for one-electron integrals with Gaussian bases. Journal of
computational chemistry. 1990 Jan;11(1):105-11.
<https://doi.org/10.1002/jcc.540110113>
"""
return sum(
binom_beta(i, s - t) * binom_beta(j, t) * a ** (i - (s - t)) * b ** (j - t)
for t in range(max(s - i, 0), j + 1)
)


def binom_factor_segment_sum(
i: int, j: int, a: float, b: float, lmax: int = LMAX
) -> FloatN:
# Vectorized version of above
s, t = jnp.tril_indices(lmax + 1)
out = binom(i, s - t) * binom(j, t) * a ** (i - (s - t)) * b ** (j - t)
mask = ((s - i) <= t) & (t <= j)
Expand All @@ -141,6 +156,7 @@ def binom_factor__via_segment_sum(i: int, j: int, a: float, b: float, s: int):


def binom_factor__via_lookup(i: int, j: int, a: float, b: float, s: int) -> FloatN:
# Lookup-table version of above -- see binom_factor_table.ipynb for the derivation
monomials = jnp.array(binom_factor_table.get_monomials(a, b))
coeffs = binom_factor_table_W[i, j, s]
return coeffs @ monomials
Expand Down

0 comments on commit 8c241d3

Please sign in to comment.