From bee87a5126b51237a93814fc5c969c969cf2bbef Mon Sep 17 00:00:00 2001 From: Hugo Karas Date: Wed, 12 Jun 2024 18:29:00 +0200 Subject: [PATCH 1/3] Seperate Kinterpolator into its own function Interpolation in Scipy is very slow, currently the same interpolation is being rerun for every calculation of the dipolarkernal. This is now cached to speed it up. --- deerlab/dipolarkernel.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/deerlab/dipolarkernel.py b/deerlab/dipolarkernel.py index 33d815f1..efbe330b 100644 --- a/deerlab/dipolarkernel.py +++ b/deerlab/dipolarkernel.py @@ -367,7 +367,7 @@ def dipolarkernel(t, r, *, pathways=None, mod=None, bg=None, method='fresnel', e if tinterp is not None: # Construct interpolator, this way elementarykernel_twospin is executed only once independently of how many pathways there are - Kinterpolator = [interp1d(tinterp,elementarykernel_twospin(tinterp,r_q,method,excbandwidth,gridsize,g,orisel,complex),axis=0,kind='cubic') for r_q in r] + Kinterpolator = _elementarykernel_twospin_interp(tinterp,r,method,excbandwidth,gridsize,g,orisel,complex) withinInterpolation = lambda tdip: np.all((np.max(tinterp) >= np.max(tdip)) & (np.min(tinterp) <= np.min(tdip))) # Define kernel matrix auxiliary functions @@ -435,8 +435,14 @@ def K0_3spin(tdip): return K #============================================================================== - - +@cached(max_size=100) +def _elementarykernel_twospin_interp(tinterp,r,method,excbandwidth,gridsize,g,orisel,complex): + """ + Construct interpolator, this way elementarykernel_twospin is executed only once independently of how many pathways there are + Cached for performance reasons, interpolation is slow. + """ + Kinterpolator = [interp1d(tinterp,elementarykernel_twospin(tinterp,r_q,method,excbandwidth,gridsize,g,orisel,complex),axis=0,kind='cubic') for r_q in r] + return Kinterpolator #============================================================================== # TWO-SPIN ELEMENTARY DIPOLAR KERNEL From 9df5fb01733efaa8602310f3dcb5ae65aea072b5 Mon Sep 17 00:00:00 2001 From: Hugo Karas Date: Wed, 12 Jun 2024 18:30:47 +0200 Subject: [PATCH 2/3] Only run orientation selection on grid and integral based kernals This hunk of code is not needed when fresnel integrals are used so does not need to be evaluated --- deerlab/dipolarkernel.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/deerlab/dipolarkernel.py b/deerlab/dipolarkernel.py index efbe330b..8ee3d387 100644 --- a/deerlab/dipolarkernel.py +++ b/deerlab/dipolarkernel.py @@ -474,14 +474,15 @@ def elementarykernel_twospin(tdip,r,method,ωex,gridsize,g,Pθ,complex): ωr = (μ0/2)*μB**2*g[0]*g[1]/h*1e21/(r**3) # rad μs^-1 # Orientation selection - orientationselection = Pθ is not None - if orientationselection: - # Ensure zero-derivatives at [0,π/2] - θ = np.linspace(0,π/2,50) # rad - Pθ_ = make_interp_spline(θ, Pθ(θ),bc_type="clamped") - # Ensure normalization of probability density function (∫P(cosθ)dcosθ=1) - Pθnorm,_ = quad(lambda cosθ: Pθ_(np.arccos(cosθ)),0,1,limit=1000) - Pθ = lambda θ: Pθ_(θ)/Pθnorm + if method != 'fresnel': + orientationselection = Pθ is not None + if orientationselection: + # Ensure zero-derivatives at [0,π/2] + θ = np.linspace(0,π/2,50) # rad + Pθ_ = make_interp_spline(θ, Pθ(θ),bc_type="clamped") + # Ensure normalization of probability density function (∫P(cosθ)dcosθ=1) + Pθnorm,_ = quad(lambda cosθ: Pθ_(np.arccos(cosθ)),0,1,limit=1000) + Pθ = lambda θ: Pθ_(θ)/Pθnorm def elementarykernel_fresnel(tdip): #------------------------------------------------------------------------ From da244c221022ea0ad899f06c786b4b1432770d8d Mon Sep 17 00:00:00 2001 From: Hugo Karas Date: Wed, 12 Jun 2024 18:39:37 +0200 Subject: [PATCH 3/3] Update changelog --- docsrc/source/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docsrc/source/changelog.rst b/docsrc/source/changelog.rst index 252ef0fc..3aa92232 100644 --- a/docsrc/source/changelog.rst +++ b/docsrc/source/changelog.rst @@ -27,6 +27,7 @@ Release Notes Release ``v1.1.3`` - Ongoing ------------------------------------------ - |fix| : Removes unnecessary files from the docs +- |efficiency| : Improves the performance of the ``dipolarkernel`` function by 10-30% (:pr:`473`), by caching the interpolation of he effective dipolar evolution time vector. Release ``v1.1.2`` - November 2023 ------------------------------------------