Skip to content

Commit e1c48d9

Browse files
angular ket and radial ket cache matrix elements
1 parent 77416a0 commit e1c48d9

2 files changed

Lines changed: 34 additions & 7 deletions

File tree

src/rydstate/angular/angular_ket.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import logging
4+
import weakref
45
from abc import ABC
56
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal, TypeVar, overload
67

@@ -59,6 +60,7 @@ class AngularKetBase(ABC, Generic[GenericT_Unknown], metaclass=CachedABCMeta):
5960
"quantum_numbers",
6061
"_allow_unknown",
6162
"_initialized",
63+
"_reduced_matrix_element_cache",
6264
"__weakref__",
6365
)
6466

@@ -119,6 +121,10 @@ def __init__( # noqa: C901, PLR0912
119121
Atomic species, e.g. 'Rb87', will not be used for calculation,
120122
only for convenience to infer the core electron spin and nuclear spin quantum numbers.
121123
"""
124+
self._reduced_matrix_element_cache: weakref.WeakKeyDictionary[
125+
AngularKetBase[Any], dict[tuple[AngularOperatorType, int], float]
126+
] = weakref.WeakKeyDictionary()
127+
122128
if species is not None:
123129
from rydstate.species.element_properties import get_element_properties # noqa: PLC0415
124130

@@ -600,8 +606,8 @@ def calc_reduced_overlap(self, other: AngularKetBase[Any]) -> float:
600606

601607
raise NotImplementedError(f"This method is not yet implemented for {self!r} and {other!r}.")
602608

603-
def calc_reduced_matrix_element( # noqa: C901, PLR0912
604-
self: Self, other: AngularKetBase[Any], operator: AngularOperatorType, kappa: int
609+
def calc_reduced_matrix_element(
610+
self, other: AngularKetBase[Any], operator: AngularOperatorType, kappa: int
605611
) -> float:
606612
r"""Calculate the reduced angular matrix element.
607613
@@ -612,6 +618,15 @@ def calc_reduced_matrix_element( # noqa: C901, PLR0912
612618
\left\langle self || \hat{O}^{(\kappa)} || other \right\rangle
613619
614620
"""
621+
cache = self._reduced_matrix_element_cache.setdefault(other, {})
622+
cache_key = (operator, kappa)
623+
if cache_key not in cache:
624+
cache[cache_key] = self._calc_reduced_matrix_element(other, operator, kappa)
625+
return cache[cache_key]
626+
627+
def _calc_reduced_matrix_element( # noqa: C901, PLR0912
628+
self: Self, other: AngularKetBase[Any], operator: AngularOperatorType, kappa: int
629+
) -> float:
615630
if not is_angular_operator_type(operator):
616631
raise NotImplementedError(f"calc_reduced_matrix_element is not implemented for operator {operator}.")
617632

src/rydstate/radial/radial_ket.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import logging
44
import math
5+
import weakref
56
from typing import TYPE_CHECKING, Literal, overload
67

78
import numpy as np
@@ -71,6 +72,10 @@ def __init__(
7172
The "n_l_1" convention requires ``n_expected`` to be set.
7273
7374
"""
75+
self._matrix_element_cache: weakref.WeakKeyDictionary[RadialKet, dict[tuple[int, str], float]] = (
76+
weakref.WeakKeyDictionary()
77+
)
78+
7479
self.potential = potential
7580

7681
if not nu > 0:
@@ -515,7 +520,7 @@ def calc_overlap(self, other: RadialKet, *, integration_method: INTEGRATION_METH
515520

516521
@overload
517522
def calc_matrix_element(
518-
self, other: RadialKet, k_radial: int, *, integration_method: INTEGRATION_METHODS = "sum"
523+
self, other: RadialKet, k_radial: int, *, unit: None = None, integration_method: INTEGRATION_METHODS = "sum"
519524
) -> PintFloat: ...
520525

521526
@overload
@@ -554,10 +559,17 @@ def calc_matrix_element(
554559
The radial matrix element in the desired unit.
555560
556561
"""
557-
# Ensure wavefunctions are integrated before accessing the grid
558-
radial_matrix_element_au = calc_radial_matrix_element_from_w_z(
559-
self.z_list, self.w_list, other.z_list, other.w_list, k_radial, integration_method
560-
)
562+
if other not in self._matrix_element_cache and self in other._matrix_element_cache:
563+
return other.calc_matrix_element(self, k_radial=k_radial, unit=unit, integration_method=integration_method)
564+
565+
cache = self._matrix_element_cache.setdefault(other, {})
566+
cache_key = (k_radial, integration_method)
567+
if cache_key not in cache:
568+
cache[cache_key] = calc_radial_matrix_element_from_w_z(
569+
self.z_list, self.w_list, other.z_list, other.w_list, k_radial, integration_method
570+
)
571+
572+
radial_matrix_element_au = cache[cache_key]
561573

562574
if unit == "a.u.":
563575
return radial_matrix_element_au

0 commit comments

Comments
 (0)