quadlib 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. quadlib/__init__.py +39 -0
  2. quadlib/basis/__init__.py +60 -0
  3. quadlib/basis/boson.py +61 -0
  4. quadlib/basis/discrete.py +71 -0
  5. quadlib/basis/expdvr.py +80 -0
  6. quadlib/basis/hodvr.py +51 -0
  7. quadlib/basis/jbasis.py +87 -0
  8. quadlib/basis/sindvr.py +97 -0
  9. quadlib/basis/spin.py +64 -0
  10. quadlib/cli/__init__.py +0 -0
  11. quadlib/cli/qlb_offset_oper_dof.py +34 -0
  12. quadlib/experimental/__init__.py +17 -0
  13. quadlib/experimental/cpd_eom.py +95 -0
  14. quadlib/experimental/mctdh.py +32 -0
  15. quadlib/experimental/node.py +259 -0
  16. quadlib/experimental/pdof.py +9 -0
  17. quadlib/experimental/tree.py +138 -0
  18. quadlib/hdmctdh/__init__.py +0 -0
  19. quadlib/hdmctdh/rundirectory.py +74 -0
  20. quadlib/legacy/__init__.py +14 -0
  21. quadlib/legacy/math.py +1337 -0
  22. quadlib/operator/sop.py +250 -0
  23. quadlib/propagation/__init__.py +17 -0
  24. quadlib/propagation/cpd.py +35 -0
  25. quadlib/propagation/exact.py +139 -0
  26. quadlib/propagation/integrators.py +108 -0
  27. quadlib/tools/__init__.py +0 -0
  28. quadlib/tools/bath.py +84 -0
  29. quadlib/tools/constants.py +289 -0
  30. quadlib/tools/iterators.py +276 -0
  31. quadlib/tools/linalg.py +215 -0
  32. quadlib/tools/pulses.py +187 -0
  33. quadlib/tools/spectra.py +179 -0
  34. quadlib/tools/tensor.py +227 -0
  35. quadlib/wavefunction/__init__.py +0 -0
  36. quadlib/wavefunction/wfn_cpd.py +266 -0
  37. quadlib/wavefunction/wfn_exact.py +147 -0
  38. quadlib-0.1.0.dist-info/METADATA +135 -0
  39. quadlib-0.1.0.dist-info/RECORD +43 -0
  40. quadlib-0.1.0.dist-info/WHEEL +5 -0
  41. quadlib-0.1.0.dist-info/entry_points.txt +2 -0
  42. quadlib-0.1.0.dist-info/licenses/LICENSE +19 -0
  43. quadlib-0.1.0.dist-info/top_level.txt +1 -0
quadlib/__init__.py ADDED
@@ -0,0 +1,39 @@
1
+ # QuaDLib: QUAntum Dynamics LIBrary for research and methods development
2
+ # Copyright (C) 2018-2026, The Theoretical Chemistry Group, Heidelberg University
3
+ #
4
+ # This software is licensed under the MIT License (https://spdx.org/licenses/MIT.html)
5
+
6
+ import os.path
7
+
8
+ # -------------------------------------------------------------
9
+ # Make classes available in quadlib's namespace
10
+ from quadlib.wavefunction.wfn_exact import WfnExact
11
+ from quadlib.wavefunction.wfn_cpd import WfnCPD
12
+
13
+ from quadlib.basis.boson import Boson
14
+ from quadlib.basis.discrete import Discrete
15
+ from quadlib.basis.expdvr import Expdvr
16
+ from quadlib.basis.hodvr import HOdvr
17
+ from quadlib.basis.sindvr import Sindvr
18
+ from quadlib.basis.spin import Spin
19
+ from quadlib.basis.jbasis import Jbasis
20
+
21
+ from quadlib.operator.sop import SumOfProducts
22
+ from quadlib.operator.sop import SumOfProducts as SOP
23
+ from quadlib.operator.sop import OpType
24
+
25
+ from quadlib.hdmctdh.rundirectory import Rundirectory
26
+ #from quadlib.hdmctdh.mctdh_runner import MctdhRunner
27
+
28
+ # -------------------------------------------------------------
29
+ # Make submodules available
30
+ import quadlib.tools.constants as cons
31
+ import quadlib.tools.linalg as linalg
32
+ import quadlib.tools.spectra as spectra
33
+ import quadlib.tools.bath as bath
34
+ import quadlib.tools.tensor as tensor
35
+ import quadlib.wavefunction.wfn_exact as exactwfn
36
+
37
+ import quadlib.propagation as propagation
38
+
39
+ QDLPATH = os.path.dirname(__file__)
@@ -0,0 +1,60 @@
1
+ # QuaDLib: QUAntum Dynamics LIBrary for research and methods development
2
+ # Copyright (C) 2018-2026, The Theoretical Chemistry Group, Heidelberg University
3
+ #
4
+ # This software is licensed under the MIT License (https://spdx.org/licenses/MIT.html)
5
+
6
+ """
7
+ Primitive basis classes.
8
+
9
+ Every basis class in this subpackage exposes at minimum the attribute `n`
10
+ (the dimension of the single-DOF Hilbert space it represents).
11
+
12
+ DVR (position-space) bases additionally expose `x`, `w`, `xmat`, `dq1`,
13
+ `dq2`, `u`; see the :class:`DVRBasis` Protocol below.
14
+
15
+ Algebraic bases (Boson, Spin, Jbasis, Discrete) expose the operators
16
+ relevant to their physics with conventional capitalised names
17
+ (``PauliX``, ``Jz``, ``Nop``, ``C``, ``A``, …). The dimension is always
18
+ the lowercase `n`.
19
+ """
20
+
21
+ from typing import Protocol, runtime_checkable
22
+
23
+ import numpy as np
24
+
25
+
26
+ @runtime_checkable
27
+ class Basis(Protocol):
28
+ """Minimum interface every basis class provides."""
29
+
30
+ n: int # dimension of the single-DOF Hilbert space
31
+
32
+
33
+ @runtime_checkable
34
+ class DVRBasis(Basis, Protocol):
35
+ """Position-space (DVR) basis.
36
+
37
+ All array attributes are real unless otherwise noted.
38
+
39
+ Attributes
40
+ ----------
41
+ x : ndarray of shape (n,)
42
+ DVR grid points.
43
+ w : ndarray of shape (n,)
44
+ DVR quadrature weights.
45
+ xmat : ndarray of shape (n, n)
46
+ Position operator in the DVR basis, equal to ``np.diag(x)``.
47
+ dq1 : ndarray of shape (n, n)
48
+ First-derivative matrix in the DVR basis.
49
+ dq2 : ndarray of shape (n, n)
50
+ Second-derivative matrix in the DVR basis.
51
+ u : ndarray of shape (n, n)
52
+ FBR → DVR transformation matrix.
53
+ """
54
+
55
+ x: np.ndarray
56
+ w: np.ndarray
57
+ xmat: np.ndarray
58
+ dq1: np.ndarray
59
+ dq2: np.ndarray
60
+ u: np.ndarray
quadlib/basis/boson.py ADDED
@@ -0,0 +1,61 @@
1
+ import numpy as np
2
+
3
+
4
+ class Boson:
5
+ """
6
+ Boson (harmonic oscillator in SQ) basis.
7
+
8
+ N -- integer: number of states, counting |0>.
9
+
10
+ Notes: the maximum number of particles for a given N is N-1
11
+
12
+ """
13
+
14
+ def __init__(self, N):
15
+ """
16
+ Initialize a boson (harmonic oscillator SQ) basis object
17
+
18
+ """
19
+ if not isinstance(N, (int, np.integer)):
20
+ raise ValueError('N needs to be an integer\n')
21
+ self.n = N
22
+ self.ONE = _ONE(N) # unit operator as a matrix
23
+ self.ONE_d = _ONE(N, diag=True) # unit operator as a diagonal oper.
24
+ self.Nop = _Bnum(N) # number operator
25
+ self.Nop_d = _Bnum(N, diag=True) # number operator as a diagonal oper.
26
+ self.C = _Bc(N) # creation operator
27
+ self.A = _Ba(N) # annihilation operator
28
+ self.H = np.diag(np.ones(N)*0.5) + self.Nop # Hamiltonian in au.
29
+
30
+
31
+ def _ONE(n, diag=False):
32
+ if diag:
33
+ return np.ones(n, float)
34
+ else:
35
+ return np.diag(np.ones(n, float))
36
+
37
+
38
+ def _Bnum(n, diag=False):
39
+ ln = np.asarray(list(range(0, n)), float)
40
+ if diag:
41
+ return ln
42
+ else:
43
+ return np.diag(ln)
44
+
45
+
46
+ def _Bc(n):
47
+ bc = np.zeros((n, n), float)
48
+ for i in list(range(1, n)):
49
+ bc[i, i-1] = np.sqrt(i)
50
+ return bc
51
+
52
+
53
+ def _Ba(n):
54
+ ba = np.zeros((n, n), float)
55
+ for i in list(range(1, n)):
56
+ ba[i-1, i] = np.sqrt(i)
57
+ return ba
58
+
59
+
60
+
61
+
@@ -0,0 +1,71 @@
1
+ import numpy as np
2
+
3
+
4
+ class Discrete:
5
+ """
6
+ Discrete basis (e.g. to represent electronic-state degrees of freedom).
7
+
8
+ N -- integer: number of states, counting |0>.
9
+
10
+ Notes: the maximum number of particles for a given N is N-1
11
+
12
+ """
13
+ def __init__(self, N):
14
+ """
15
+ Initialize a discrete basis object
16
+
17
+ """
18
+ if not isinstance(N, (int, np.integer)):
19
+ raise ValueError('N needs to be an integer\n')
20
+ self.n = N
21
+ self.ONE = _ONE(N) # unit operator as a matrix
22
+ self.ONE_d = _ONE(N, diag=True) # unit operator as a diagonal oper.
23
+
24
+
25
+ def P(self, n, diag=False):
26
+ """
27
+ Projector |n><n|
28
+
29
+ n -- state number, n <= self.n
30
+
31
+ """
32
+ p = np.zeros((self.n), float)
33
+ p[n] = 1.0
34
+ if diag:
35
+ return p
36
+ else:
37
+ return np.diag(p)
38
+
39
+
40
+ def S(self, n, m):
41
+ """
42
+ Symmetric operator |n><m| + |m><n|
43
+
44
+ n, m -- state number, n, m <= self.n
45
+
46
+ """
47
+ p = np.zeros((self.n, self.n), float)
48
+ p[n, m] = 1.0
49
+ p[m, n] = 1.0
50
+ return p
51
+
52
+
53
+ def Z(self, n, m):
54
+ """
55
+ Off-diagonal operator |n><m|
56
+
57
+ n, m -- state number, n, m <= self.n
58
+
59
+ """
60
+ p = np.zeros((self.n, self.n), float)
61
+ p[n, m] = 1.0
62
+ return p
63
+
64
+
65
+ def _ONE(n, diag=False):
66
+ if diag:
67
+ return np.ones(n, float)
68
+ else:
69
+ return np.diag(np.ones(n, float))
70
+
71
+
@@ -0,0 +1,80 @@
1
+ import numpy as np
2
+
3
+
4
+ class Expdvr:
5
+ """
6
+ Exp DVR (plane wave) basis.
7
+
8
+ """
9
+
10
+ def __init__(self, N, x0=0, L=2*np.pi):
11
+ """
12
+ Initialize a exp DVR basis object
13
+ """
14
+ if not isinstance(N, (int, np.integer)):
15
+ raise ValueError('N needs to be an odd integer\n')
16
+ if N%2 == 0:
17
+ raise ValueError('N needs to be an odd integer\n')
18
+ x0 = float(x0)
19
+ L = float(L)
20
+ self.n = N
21
+ self.x0 = x0
22
+ self.dX = L/N
23
+ self.xf = x0 + L - L/N # Last grid point
24
+ self.L = L
25
+ self.x, self.w, self.dq1, self.dq2, self.u = expdvr(N, x0, L)
26
+ self.xmat = np.diag(self.x)
27
+
28
+
29
+ def expdvr(N, x0, L):
30
+ weights = np.ones(N, float)*L/N
31
+ x, umat = _calcumat(N, x0, L)
32
+ d1dvr = _calcd1dvr(N, x0, L)
33
+ d2dvr = _calcd2dvr(N, x0, L)
34
+ return x, weights, d1dvr, d2dvr, umat
35
+
36
+
37
+ def _dx(N, L):
38
+ return L/N
39
+
40
+
41
+ def _calcumat(N, x0, L):
42
+ U = np.zeros((N, N), float)
43
+ X = np.zeros(N, float)
44
+ dx = L/N
45
+ N1 = N + 1
46
+ fac = np.sqrt(2.0/(N + 1))
47
+ for j in range(N):
48
+ X[j] = x0 + j*dx
49
+ for a in range(N):
50
+ U[j, a] = fac*np.sin(j*a*np.pi/N1)
51
+ return X, U
52
+
53
+
54
+ def _calcd1dvr(N, x0, L):
55
+ D1 = np.zeros((N, N), float)
56
+ fac = np.pi/L
57
+ for a in range(N):
58
+ for b in range(N):
59
+ if a==b:
60
+ continue
61
+ pref = fac*(-1)**(a - b)
62
+ D1[a, b] = pref/np.sin(np.pi*(a - b)/N)
63
+ return D1
64
+
65
+
66
+ def _calcd2dvr(N, x0, L):
67
+ D2 = np.zeros((N, N), float)
68
+ fac1 = -np.pi**2/(3*L**2)*(N**2 - 1)
69
+ fac2 = -2*np.pi**2/(L**2)
70
+ for a in range(N):
71
+ for b in range(N):
72
+ if a==b:
73
+ D2[a, b] = fac1
74
+ else:
75
+ pref = fac2*(-1)**(a - b)
76
+ c = np.cos(np.pi*(a - b)/N)
77
+ s2 = np.sin(np.pi*(a - b)/N)**2
78
+ D2[a, b] = pref*c/s2
79
+ return D2
80
+
quadlib/basis/hodvr.py ADDED
@@ -0,0 +1,51 @@
1
+ import numpy as np
2
+
3
+ import quadlib.basis.boson as boson
4
+
5
+
6
+ class HOdvr:
7
+ """
8
+ Harmonic oscillator DVR basis.
9
+
10
+ """
11
+
12
+ def __init__(self, N, m=1.0, w=1.0, x0=0.0):
13
+ """
14
+ Initialize a HO DVR basis object
15
+ """
16
+ if not isinstance(N, (int, np.integer)):
17
+ raise ValueError('N needs to be an integer\n')
18
+ m = float(m)
19
+ w = float(w)
20
+ mw = m*w
21
+ mw4 = (mw/np.pi)**-0.25
22
+ B = boson.Boson(N)
23
+ H = (B.Nop + np.diag(np.ones(N))*0.5)*w
24
+ x_fbr = (B.C + B.A)/np.sqrt(2*mw) + np.diag(np.ones(N))*x0
25
+ p_fbr = 1.0j*(B.C - B.A)*np.sqrt(mw/2)
26
+ x2_fbr = x_fbr @ x_fbr
27
+ v_fbr = 0.5*m*w**2 * x2_fbr
28
+ dq2_fbr = -2.0*m*(H - v_fbr)
29
+ # Line above is the correct way to obtain the second derivative matrix.
30
+ # It prevents the fbr basis truncation error
31
+
32
+ X, U = np.linalg.eigh(x_fbr)
33
+ for j, u0j in enumerate(U[0,:]):
34
+ if u0j < 0.0: U[:,j] = -1.0*U[:,j]
35
+
36
+ P_dvr = U.T @ p_fbr @ U
37
+ self.dq1 = -1.0j*P_dvr
38
+ self.P = P_dvr
39
+
40
+ self.dq2 = U.T @ dq2_fbr @ U
41
+ self.T = -0.5*self.dq2/m
42
+
43
+ self.n = N
44
+ self.u = U
45
+ self.x = X
46
+ self.xmat = np.diag(X)
47
+ self.x0 = self.x[0]
48
+ self.xf = self.x[-1]
49
+ w12 = mw4*np.exp(0.5*mw*X**2)*np.abs(U[0])
50
+ self.w = w12**2
51
+
@@ -0,0 +1,87 @@
1
+ import numpy as np
2
+
3
+
4
+ class Jbasis:
5
+ """
6
+ General angular momentum basis.
7
+
8
+ """
9
+
10
+ def __init__(self, M):
11
+ """
12
+ Initialize a general angular momentum basis
13
+
14
+ M -- spin multiplicity, M = 2S + 1 (S is the total spin)
15
+
16
+ Notes:
17
+ - See e.g. Griffiths, Introduction to Quantum Mechanics
18
+ - |0> has the highest angular momentum projection along z.
19
+ """
20
+ self.n = M
21
+ self.ONE = np.diag(np.ones(M, float))
22
+ self.Jz = _Jz(M)
23
+ self.Jx = _Jx(M)
24
+ self.Jy = _Jy(M)
25
+ self.Jp = _Jp(M)
26
+ self.Jm = _Jm(M)
27
+ self.J2 = _J2(M)
28
+
29
+
30
+ def _bj(j, s):
31
+ t = (s + j)*(s + 1 - j)
32
+ return np.sqrt(t)
33
+
34
+
35
+ def _Jx(M):
36
+ jx = np.zeros((M, M), float)
37
+ s = (M - 1.0)/2.0
38
+ for i in list(range(0, M - 1)):
39
+ j = s - i
40
+ bj = _bj(j, s)
41
+ jx[i + 1, i] = bj
42
+ jx[i, i + 1] = bj
43
+ jx = 0.5*jx
44
+ return jx
45
+
46
+
47
+ def _Jy(M):
48
+ jy = np.zeros((M, M), complex)
49
+ s = (M - 1.0)/2.0
50
+ for i in list(range(0, M - 1)):
51
+ j = s - i
52
+ bj = _bj(j, s)
53
+ jy[i + 1, i] = 1.0j*bj
54
+ jy[i, i + 1] = -1.0j*bj
55
+ jy = 0.5*jy
56
+ return jy
57
+
58
+
59
+ def _Jz(M):
60
+ jz = np.zeros((M, M), float)
61
+ s = (M - 1.0)/2.0
62
+ for i in list(range(0, M)):
63
+ j = s - i
64
+ jz[i, i] = j
65
+ return jz
66
+
67
+
68
+ def _Jp(M):
69
+ jx = _Jx(M)
70
+ jy = _Jy(M)
71
+ return np.real(jx + 1.0j*jy)
72
+
73
+
74
+ def _Jm(M):
75
+ jx = _Jx(M)
76
+ jy = _Jy(M)
77
+ return np.real(jx - 1.0j*jy)
78
+
79
+
80
+ def _J2(M):
81
+ jx = _Jx(M)
82
+ jy = _Jy(M)
83
+ jz = _Jz(M)
84
+ j2 = np.dot(jx, jx) + np.dot(jy, jy) + np.dot(jz, jz)
85
+ return np.real(j2)
86
+
87
+
@@ -0,0 +1,97 @@
1
+ import math
2
+
3
+ import numpy as np
4
+
5
+
6
+ class Sindvr:
7
+ """
8
+ Sin DVR (particle in a box) basis.
9
+
10
+ """
11
+
12
+ def __init__(self, N, x0=-0.5, xf=0.5):
13
+ """
14
+ Initialize a sin DVR basis object
15
+ """
16
+ if not isinstance(N, (int, np.integer)):
17
+ raise ValueError('N needs to be an integer\n')
18
+ x0 = float(x0)
19
+ xf = float(xf)
20
+ self.n = N
21
+ self.x0 = x0
22
+ self.xf = xf
23
+ self.x, self.w, self.dq1, self.dq2, self.u = sindvr(N, x0, xf)
24
+ self.xmat = np.diag(self.x)
25
+ self.dX = _dx(N, x0, xf)
26
+ self.L = _L(N, x0, xf)
27
+
28
+
29
+ def sindvr(N, x0, xf):
30
+ weights = np.ones(N, float)*_dx(N, x0, xf)
31
+ x, umat = _calcumat(N, x0, xf)
32
+ d1dvr = _calcd1dvr(N, x0, xf, umat)
33
+ d2dvr = _calcd2dvr(N, x0, xf, umat)
34
+ return x, weights, d1dvr, d2dvr, umat
35
+
36
+
37
+ def _dx(N, x0, xf):
38
+ return (xf-x0) / (N-1)
39
+
40
+
41
+ def _L(N, x0, xf):
42
+ return (xf-x0) * (N+1.0) / (N-1.0) # physical length of box
43
+
44
+
45
+ def _calcumat(N, x0, xf):
46
+ dx = _dx(N, x0, xf)
47
+ L = _L(N, x0, xf)
48
+ dkron = np.identity(N+1,int)
49
+ # Generate the matrix Q(z), where z=cos(pi(x-xo)/L)
50
+ Qz = np.zeros((N, N), float)
51
+ for i in range(N):
52
+ for j in range(N):
53
+ Qz[i, j] = 0.5 * float( dkron[i, j+1] + dkron[i, j-1] )
54
+ evals, evecs = np.linalg.eigh(Qz)
55
+ # Reverse order of eigevalues and eigenvectors for ascending grid points
56
+ idx = list(range(0, N))
57
+ idx.reverse()
58
+ evals = evals[idx]
59
+ evecs = evecs[:,idx]
60
+ evals[:] = (L/math.pi) * np.arccos(evals)
61
+ umat = evecs
62
+ # change sign of eigenvectors to ensure positive weights
63
+ for i in range(N):
64
+ if umat[0, i] < 0.0:
65
+ umat[:, i] = -1.0*umat[:, i]
66
+ x = evals + x0 - dx
67
+ return x, umat
68
+
69
+
70
+ def _calcd1dvr(N, x0, xf, umat):
71
+ d1vbr = np.zeros((N, N), float)
72
+ umatT = np.transpose(umat)
73
+ L = _L(N, x0, xf)
74
+ for j in range(N):
75
+ j1=j+1
76
+ for k in range(N):
77
+ k1=k+1
78
+ if j != k:
79
+ d1vbr[j,k] = float((j1-k1)%2) * \
80
+ (4.0/L) * j1*k1/(j1**2 - k1**2)
81
+ d1dvr = np.dot(umatT, np.dot(d1vbr, umat))
82
+ return d1dvr
83
+
84
+
85
+ def _calcd2dvr(N, x0, xf, umat):
86
+ d2vbr = np.zeros((N, N), float)
87
+ umatT = np.transpose(umat)
88
+ dkron = np.identity(N+1,int)
89
+ L = _L(N, x0, xf)
90
+ for j in range(N):
91
+ j1=j+1
92
+ for k in range(N):
93
+ k1=k+1
94
+ d2vbr[j,k] = -dkron[j1,k1] * (j1*math.pi/L)**2
95
+ d2dvr = np.dot(umatT, np.dot(d2vbr, umat))
96
+ return d2dvr
97
+
quadlib/basis/spin.py ADDED
@@ -0,0 +1,64 @@
1
+ import numpy as np
2
+
3
+
4
+ class Spin:
5
+ """
6
+ Spin (two-level system) basis.
7
+
8
+ """
9
+
10
+ def __init__(self):
11
+ """
12
+ Initialize a spin basis object
13
+
14
+ Notes: we are using the convention
15
+ (1, 0)T --> |0>, spin-up
16
+ (0, 1)T --> |1>, spin-down.
17
+ This convention agrees with the definition of the general jbasis.
18
+ """
19
+ self.n = 2
20
+ self.ONE = np.diag(np.ones(2, float))
21
+ self.PauliZ = _PauliZ()
22
+ self.PauliX = _PauliX()
23
+ self.PauliY = _PauliY()
24
+ self.Sz = 0.5*self.PauliZ
25
+ self.Sx = 0.5*self.PauliX
26
+ self.Sy = 0.5*self.PauliY
27
+ self.Sp = _Sp()
28
+ self.Sm = _Sm()
29
+ self.S2 = 0.75*self.ONE
30
+
31
+
32
+ def _PauliX():
33
+ sx = np.zeros((2,2), float)
34
+ sx[0, 1] = 1.0
35
+ sx[1, 0] = 1.0
36
+ return sx
37
+
38
+
39
+ def _PauliY():
40
+ sy = np.zeros((2, 2), complex)
41
+ sy[0, 1] = -1.0j
42
+ sy[1, 0] = 1.0j
43
+ return sy
44
+
45
+
46
+ def _PauliZ():
47
+ sz = np.diag(np.ones(2, float))
48
+ sz[1, 1] = -1.0
49
+ return sz
50
+
51
+
52
+ def _Sp():
53
+ sp = np.zeros((2,2), float)
54
+ sp[0, 1] = 1.0
55
+ return sp
56
+
57
+
58
+ def _Sm():
59
+ sm = np.zeros((2,2), float)
60
+ sm[1, 0] = 1.0
61
+ return sm
62
+
63
+
64
+
File without changes
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python
2
+ # QuaDLib: QUAntum Dynamics LIBrary for research and methods development
3
+ # Copyright (C) 2018-2026, The Theoretical Chemistry Group, Heidelberg University
4
+ #
5
+ # This software is licensed under the MIT License (https://spdx.org/licenses/MIT.html)
6
+
7
+ """
8
+ Add an offset to the mode numbers (|n) of an MCTDH operator.
9
+
10
+ Reads the operator from stdin, writes it to stdout:
11
+ qlb-offset-oper-dof -o 3 < in.op > out.op
12
+ """
13
+
14
+ import argparse
15
+ import re
16
+ import sys
17
+
18
+
19
+ def offset_line(line, offset):
20
+ """Return line with every '|<n>' replaced by '|<n + offset>'."""
21
+ return re.sub(r'\|[0-9]+', lambda m: '|' + str(int(m[0][1:]) + offset), line)
22
+
23
+
24
+ def main(argv=None):
25
+ parser = argparse.ArgumentParser(description=__doc__.strip().splitlines()[0])
26
+ parser.add_argument('-o', '--offset', type=int, default=0,
27
+ help='Offset added to the modenumbers of an MCTDH operator')
28
+ opts = parser.parse_args(argv)
29
+ for line in sys.stdin:
30
+ print(offset_line(line.rstrip('\n'), opts.offset), file=sys.stdout)
31
+
32
+
33
+ if __name__ == '__main__':
34
+ main()
@@ -0,0 +1,17 @@
1
+ # QuaDLib: QUAntum Dynamics LIBrary for research and methods development
2
+ # Copyright (C) 2018-2026, The Theoretical Chemistry Group, Heidelberg University
3
+ #
4
+ # This software is licensed under the MIT License (https://spdx.org/licenses/MIT.html)
5
+
6
+ """
7
+ Unfinished or known-incorrect code kept for ongoing method development.
8
+
9
+ Nothing here is imported by ``quadlib/__init__.py``; import the
10
+ submodules explicitly, e.g. ``import quadlib.experimental.cpd_eom``.
11
+ Nothing here is covered by the stability or correctness expectations of
12
+ the rest of the library.
13
+
14
+ node, tree, pdof - tree-tensor-network scaffolding (Node, Tree, Pdof)
15
+ mctdh - placeholders for the (ML-)MCTDH equations of motion
16
+ cpd_eom - coupled CPD equations (known incorrect)
17
+ """