sparse-ir 1.1.6__py3-none-any.whl → 2.0.0a2__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.
sparse_ir/basis.py CHANGED
@@ -1,16 +1,16 @@
1
- # Copyright (C) 2020-2022 Markus Wallerberger, Hiroshi Shinaoka, and others
2
- # SPDX-License-Identifier: MIT
3
- from typing import Tuple
1
+ """
2
+ High-level Python classes for FiniteTempBasis
3
+ """
4
+ from typing import Optional
4
5
  import numpy as np
5
- from warnings import warn
6
-
7
- from . import abstract
8
- from . import kernel as _kernel
9
- from . import poly
10
- from . import sve
11
-
12
-
13
- class FiniteTempBasis(abstract.AbstractBasis):
6
+ from pylibsparseir.core import basis_new, basis_get_size, basis_get_svals, basis_get_u, basis_get_v, basis_get_uhat, basis_get_default_tau_sampling_points, basis_get_default_omega_sampling_points, basis_get_default_matsubara_sampling_points
7
+ from pylibsparseir.constants import SPIR_STATISTICS_FERMIONIC, SPIR_STATISTICS_BOSONIC
8
+ from .kernel import LogisticKernel
9
+ from .abstract import AbstractBasis
10
+ from .sve import SVEResult
11
+ from .poly import PiecewiseLegendrePolyVector, PiecewiseLegendrePolyFTVector, FunctionSet, FunctionSetFT
12
+
13
+ class FiniteTempBasis(AbstractBasis):
14
14
  r"""Intermediate representation (IR) basis for given temperature.
15
15
 
16
16
  For a continuation kernel from real frequencies, `ω` ∈ [-ωmax, ωmax], to
@@ -40,103 +40,89 @@ class FiniteTempBasis(abstract.AbstractBasis):
40
40
  gl = basis.s * basis.v(2.5)
41
41
  giw = gl @ basis.uhat([1, 3, 5, 7])
42
42
  """
43
- def __init__(self, statistics, beta, wmax, eps=None, *,
44
- max_size=None, kernel=None, sve_result=None):
45
- if not (beta > 0):
46
- raise ValueError("inverse temperature beta must be positive")
47
- if not (wmax >= 0):
48
- raise ValueError("frequency cutoff must be non-negative")
49
-
50
- if eps is None and sve_result is None and not sve.HAVE_XPREC:
51
- warn("xprec package is not available:\n"
52
- "expect single precision (1.5e-8) only as both cutoff and\n"
53
- "accuracy of the basis functions")
54
-
55
- # Calculate basis functions from truncated singular value expansion
56
- self._kernel = _get_kernel(statistics, beta * wmax, kernel)
57
- if sve_result is None:
58
- sve_result = sve.compute(self._kernel, eps)
59
- else:
60
- # Sanity check of provided sve_result
61
- # TODO: check for the kernel type/name or eps?
62
- new_kernel_lambda = self._kernel.lambda_
63
- sve_kernel_lambda = sve_result.K.lambda_
64
- if not np.allclose(new_kernel_lambda, sve_kernel_lambda,
65
- atol=1e-12, rtol=4e-16):
66
- raise ValueError("Kernel mismatch:\n"
67
- "provided SVE result is incompatible with "
68
- "kernel parameters (lambda_ == beta*wmax)")
69
-
70
- self._sve_result = sve_result
43
+
44
+ def __init__(self, statistics: str, beta: float, wmax: float, eps: float, sve_result: Optional[SVEResult] = None, max_size: int =-1):
45
+ """
46
+ Initialize finite temperature basis.
47
+
48
+ Parameters:
49
+ -----------
50
+ statistics : str
51
+ 'F' for fermions, 'B' for bosons
52
+ beta : float
53
+ Inverse temperature
54
+ wmax : float
55
+ Frequency cutoff
56
+ eps : float
57
+ Accuracy threshold
58
+ """
71
59
  self._statistics = statistics
72
60
  self._beta = beta
73
61
  self._wmax = wmax
62
+ self._lambda = beta * wmax
74
63
 
75
- u, s, v = sve_result.part(eps, max_size)
76
- if sve_result.s.size > s.size:
77
- self._accuracy = sve_result.s[s.size] / s[0]
64
+ # Create kernel
65
+ if statistics == 'F' or statistics == 'B':
66
+ self._kernel = LogisticKernel(self._lambda)
78
67
  else:
79
- self._accuracy = s[-1] / s[0]
80
-
81
- # The polynomials are scaled to the new variables by transforming the
82
- # knots according to: tau = beta/2 * (x + 1), w = wmax * y. Scaling
83
- # the data is not necessary as the normalization is inferred.
84
- self._u = u.__class__(u.data, beta/2 * (u.knots + 1), beta/2 * u.dx, u.symm)
85
- self._v = v.__class__(v.data, wmax * v.knots, wmax * v.dx, v.symm)
86
-
87
- # The singular values are scaled to match the change of variables, with
88
- # the additional complexity that the kernel may have an additional
89
- # power of w.
90
- self._s = np.sqrt(beta/2 * wmax) * (wmax**(-self.kernel.ypower)) * s
91
-
92
- # HACK: as we don't yet support Fourier transforms on anything but the
93
- # unit interval, we need to scale the underlying data.
94
- uhat_base_full = poly.PiecewiseLegendrePoly(
95
- np.sqrt(beta) * sve_result.u.data, sve_result.u,
96
- symm=sve_result.u.symm)
97
- conv_radius = 40 * self.kernel.lambda_
98
- even_odd = {'F': 'odd', 'B': 'even'}[statistics]
99
- self._uhat_full = poly.PiecewiseLegendreFT(uhat_base_full, even_odd,
100
- n_asymp=conv_radius)
101
- self._uhat = self._uhat_full[:s.size]
68
+ raise ValueError(f"Invalid statistics: {statistics} expected 'F' or 'B'")
102
69
 
103
- def __getitem__(self, index):
104
- return FiniteTempBasis(
105
- self._statistics, self._beta, self._wmax, None,
106
- max_size=_slice_to_size(index), kernel=self._kernel,
107
- sve_result=self._sve_result)
70
+ # Compute SVE
71
+ if sve_result is None:
72
+ self._sve = SVEResult(self._kernel, eps)
73
+ else:
74
+ self._sve = sve_result
108
75
 
109
- @property
110
- def statistics(self): return self._statistics
76
+ # Create basis
77
+ stats_int = SPIR_STATISTICS_FERMIONIC if statistics == 'F' else SPIR_STATISTICS_BOSONIC
78
+ self._ptr = basis_new(stats_int, self._beta, self._wmax, self._kernel._ptr, self._sve._ptr, max_size)
111
79
 
112
- @property
113
- def beta(self): return self._beta
80
+ u_funcs = FunctionSet(basis_get_u(self._ptr))
81
+ v_funcs = FunctionSet(basis_get_v(self._ptr))
82
+ uhat_funcs = FunctionSetFT(basis_get_uhat(self._ptr))
114
83
 
115
- @property
116
- def wmax(self): return self._wmax
84
+ self._s = basis_get_svals(self._ptr)
85
+ self._u = PiecewiseLegendrePolyVector(u_funcs, 0, self._beta)
86
+ self._v = PiecewiseLegendrePolyVector(v_funcs, -self._wmax, self._wmax)
87
+ self._uhat = PiecewiseLegendrePolyFTVector(uhat_funcs)
117
88
 
118
89
  @property
119
- def lambda_(self): return self._beta * self._wmax
90
+ def statistics(self):
91
+ """Quantum statistic ('F' for fermionic, 'B' for bosonic)"""
92
+ return self._statistics
120
93
 
121
94
  @property
122
- def shape(self): return self._s.shape
95
+ def beta(self):
96
+ """Inverse temperature"""
97
+ return self._beta
123
98
 
124
99
  @property
125
- def size(self): return self._s.size
100
+ def wmax(self):
101
+ """Real frequency cutoff"""
102
+ return self._wmax
126
103
 
127
104
  @property
128
- def u(self) -> poly.PiecewiseLegendrePoly: return self._u
105
+ def lambda_(self):
106
+ """Basis cutoff parameter, Λ = β * wmax"""
107
+ return self._lambda
129
108
 
130
109
  @property
131
- def uhat(self) -> poly.PiecewiseLegendreFT: return self._uhat
110
+ def size(self):
111
+ return self._s.size
132
112
 
133
113
  @property
134
- def s(self) -> np.ndarray:
114
+ def s(self):
135
115
  """Vector of singular values of the continuation kernel"""
116
+ if self._s is None:
117
+ self._s = basis_get_svals(self._ptr)
136
118
  return self._s
137
119
 
138
120
  @property
139
- def v(self) -> poly.PiecewiseLegendrePoly:
121
+ def u(self):
122
+ return self._u
123
+
124
+ @property
125
+ def v(self):
140
126
  r"""Basis functions on the real frequency axis.
141
127
 
142
128
  Set of IR basis functions on the real frequency (omega) axis, where
@@ -162,49 +148,67 @@ class FiniteTempBasis(abstract.AbstractBasis):
162
148
  """
163
149
  return self._v
164
150
 
151
+ @property
152
+ def uhat(self):
153
+ return self._uhat
154
+
165
155
  @property
166
156
  def significance(self):
167
- return self._s / self._s[0]
157
+ """Relative significance of basis functions."""
158
+ return self.s / self.s[0]
168
159
 
169
160
  @property
170
161
  def accuracy(self):
171
- return self._accuracy
162
+ """Overall accuracy bound."""
163
+ return self.s[-1] / self.s[0]
172
164
 
173
165
  @property
174
- def kernel(self):
175
- """Kernel of which this is the singular value expansion"""
176
- return self._kernel
166
+ def shape(self):
167
+ """Shape of the basis function set"""
168
+ return self.s.shape
177
169
 
178
- @property
179
- def sve_result(self):
180
- return self._sve_result
181
-
182
- def default_tau_sampling_points(self, *, npoints=None):
183
- if npoints is None:
184
- npoints = self.size
185
- x = _default_sampling_points(self._sve_result.u, npoints)
186
- return self._beta/2 * (x + 1)
187
-
188
- def default_matsubara_sampling_points(self, *, npoints=None,
189
- positive_only=False):
190
- if npoints is None:
191
- npoints = self.size
192
- return _default_matsubara_sampling_points(self._uhat_full, npoints,
193
- positive_only=positive_only)
194
-
195
- def default_omega_sampling_points(self, *, npoints=None):
170
+ def default_tau_sampling_points(self, npoints=None):
171
+ """Get default tau sampling points."""
172
+ return basis_get_default_tau_sampling_points(self._ptr)
173
+
174
+ def default_omega_sampling_points(self, npoints=None):
196
175
  """Return default sampling points in imaginary time.
197
176
 
198
177
  Arguments:
199
178
  npoints (int):
200
179
  Minimum number of sampling points to return.
201
180
 
202
- .. versionadded: 1.1
181
+ .. versionadded:: 1.1
182
+ """
183
+ from pylibsparseir.core import basis_get_default_omega_sampling_points
184
+ return basis_get_default_omega_sampling_points(self._ptr)
185
+
186
+ def default_matsubara_sampling_points(self, npoints=None, positive_only=False):
187
+ """Get default Matsubara sampling points."""
188
+ return basis_get_default_matsubara_sampling_points(self._ptr, positive_only)
189
+
190
+ def __repr__(self):
191
+ return (f"FiniteTempBasis(statistics='{self.statistics}', "
192
+ f"beta={self.beta}, wmax={self.wmax}, size={self.size})")
193
+
194
+ def __getitem__(self, index):
195
+ """Return basis functions/singular values for given index/indices.
196
+
197
+ This can be used to truncate the basis to the n most significant
198
+ singular values: basis[:3].
203
199
  """
204
- if npoints is None:
205
- npoints = self.size
206
- y = _default_sampling_points(self._sve_result.v, npoints)
207
- return self._wmax * y
200
+ # TODO: Implement basis truncation when C API supports it
201
+ raise NotImplementedError("Basis truncation not yet implemented in C API")
202
+
203
+ @property
204
+ def kernel(self):
205
+ """The kernel used to generate the basis."""
206
+ return self._kernel
207
+
208
+ @property
209
+ def sve_result(self):
210
+ """The singular value expansion result."""
211
+ return self._sve
208
212
 
209
213
  def rescale(self, new_beta):
210
214
  """Return a basis for different temperature.
@@ -213,137 +217,24 @@ class FiniteTempBasis(abstract.AbstractBasis):
213
217
  temperature. Note that this implies a different UV cutoff ``wmax``,
214
218
  since ``lambda_ == beta * wmax`` stays constant.
215
219
  """
216
- new_wmax = self._kernel.lambda_ / new_beta
217
- return FiniteTempBasis(self._statistics, new_beta, new_wmax, None,
218
- max_size=self.size, kernel=self._kernel,
219
- sve_result=self._sve_result)
220
+ # Calculate new beta and wmax that give the desired lambda
221
+ # We keep the ratio beta/wmax constant
222
+ ratio = self.beta / self.wmax
223
+ new_wmax = np.sqrt(new_lambda / ratio)
224
+ new_beta = new_lambda / new_wmax
225
+
226
+ # Get epsilon from the current basis accuracy
227
+ eps = self.accuracy
220
228
 
229
+ return FiniteTempBasis(self.statistics, new_beta, new_wmax, eps)
221
230
 
222
- def finite_temp_bases(
223
- beta: float, wmax: float, eps: float = None,
224
- sve_result: tuple = None
225
- )-> Tuple[FiniteTempBasis, FiniteTempBasis]:
231
+
232
+ def finite_temp_bases(beta, wmax, eps=None, sve_result=None):
226
233
  """Construct FiniteTempBasis objects for fermion and bosons
227
234
 
228
235
  Construct FiniteTempBasis objects for fermion and bosons using
229
236
  the same LogisticKernel instance.
230
237
  """
231
- if sve_result is None:
232
- sve_result = sve.compute(_kernel.LogisticKernel(beta*wmax), eps)
233
- basis_f = FiniteTempBasis("F", beta, wmax, eps, sve_result=sve_result)
234
- basis_b = FiniteTempBasis("B", beta, wmax, eps, sve_result=sve_result)
235
- return basis_f, basis_b
236
-
237
-
238
- def _default_sampling_points(u, L):
239
- if u.xmin != -1 or u.xmax != 1:
240
- raise ValueError("expecting unscaled functions here")
241
-
242
- if L < u.size:
243
- # For orthogonal polynomials (the high-T limit of IR), we know that the
244
- # ideal sampling points for a basis of size L are the roots of the L-th
245
- # polynomial. We empirically find that these stay good sampling points
246
- # for our kernels (probably because the kernels are totally positive).
247
- x0 = u[L].roots()
248
- else:
249
- # If we do not have enough polynomials in the basis, we approximate the
250
- # roots of the L'th polynomial by the extrema of the (L-1)'st basis
251
- # function, which is sensible due to the strong interleaving property
252
- # of these functions' roots.
253
- maxima = u[-1].deriv().roots()
254
-
255
- # Putting the sampling points right at [0, beta], which would be the
256
- # local extrema, is slightly worse conditioned than putting it in the
257
- # middel. This can be understood by the fact that the roots never
258
- # occur right at the border.
259
- left = .5 * (maxima[:1] + u.xmin)
260
- right = .5 * (maxima[-1:] + u.xmax)
261
- x0 = np.concatenate([left, maxima, right])
262
-
263
- if x0.size != L:
264
- warn(f"Requesting {L} sampling points for corresponding basis size,\n"
265
- f"but {x0.size} were returned. This may indiciate a problem "
266
- f"with precision.", UserWarning, 3)
267
- return x0
268
-
269
-
270
- def _default_matsubara_sampling_points(uhat, L, *, fence=False, positive_only=False):
271
- l_requested = L
272
-
273
- # The number of sign changes is always odd for bosonic basis (freq=='even')
274
- # and even for fermionic basis (freq='odd'). So in order to get at least
275
- # as many sign changes as basis functions.
276
- if uhat.freq == 'odd' and l_requested % 2 == 1:
277
- l_requested += 1
278
- elif uhat.freq == 'even' and l_requested % 2 == 0:
279
- l_requested += 1
280
-
281
- if l_requested < uhat.size:
282
- # As with the zeros, the sign changes provide excellent sampling points
283
- wn = uhat[l_requested].sign_changes(positive_only=positive_only)
284
- else:
285
- # As a fallback, use the (discrete) extrema of the corresponding
286
- # highest-order basis function in Matsubara. This turns out to be okay.
287
- polyhat = uhat[-1]
288
- wn = polyhat.extrema(positive_only=positive_only)
289
-
290
- # For bosonic bases, we must explicitly include the zero frequency,
291
- # otherwise the condition number blows up.
292
- if wn[0] % 2 == 0:
293
- wn = np.unique(np.hstack((0, wn)))
294
-
295
- expected_size = l_requested
296
- if positive_only:
297
- expected_size = (expected_size + 1) // 2
298
-
299
- if wn.size != expected_size:
300
- warn(f"Requesting {expected_size} {uhat.freq} sampling frequencies\n"
301
- f"for basis size L={L}, but {wn.size} were returned. This may\n"
302
- f"indiciate a problem with precision.", UserWarning, 3)
303
- if fence:
304
- wn = _fence_matsubara_sampling(wn, positive_only)
305
- return wn
306
-
307
-
308
- def _fence_matsubara_sampling(wn, positive_only):
309
- # While the condition number for sparse sampling in tau saturates at a
310
- # modest level, the conditioning in Matsubara steadily deteriorates due
311
- # to the fact that we are not free to set sampling points continuously.
312
- # At double precision, tau sampling is better conditioned than iwn
313
- # by a factor of ~4 (still OK). To battle this, we fence the largest
314
- # frequency with two carefully chosen oversampling points, which brings
315
- # the two sampling problems within a factor of 2.
316
- wn_outer = wn[-1:] if positive_only else wn[[0, -1]]
317
- wn_diff = 2 * np.round(0.025 * wn_outer).astype(int)
318
- if wn.size >= 20:
319
- wn = np.hstack([wn, wn_outer - np.sign(wn_outer) * wn_diff])
320
- if wn.size >= 42:
321
- wn = np.hstack([wn, wn_outer + np.sign(wn_outer) * wn_diff])
322
- return np.unique(wn)
323
-
324
-
325
- def _get_kernel(statistics, lambda_, kernel):
326
- if statistics not in 'BF':
327
- raise ValueError("statistics must either be 'B' (for bosonic basis) "
328
- "or 'F' (for fermionic basis)")
329
- if kernel is None:
330
- kernel = _kernel.LogisticKernel(lambda_)
331
- else:
332
- try:
333
- lambda_kernel = kernel.lambda_
334
- except AttributeError:
335
- pass
336
- else:
337
- if not np.allclose(lambda_kernel, lambda_, atol=0, rtol=4e-16):
338
- raise ValueError("lambda of kernel and basis mismatch")
339
- return kernel
340
-
341
-
342
- def _slice_to_size(index):
343
- if not isinstance(index, slice):
344
- raise ValueError("argument must be a slice (`n:m`)")
345
- if index.start is not None and index.start != 0:
346
- raise ValueError("slice must start at zero")
347
- if index.step is not None and index.step != 1:
348
- raise ValueError("slice must step in ones")
349
- return index.stop
238
+ fermion_basis = FiniteTempBasis('F', beta, wmax, eps, sve_result=sve_result)
239
+ boson_basis = FiniteTempBasis('B', beta, wmax, eps, sve_result=sve_result)
240
+ return fermion_basis, boson_basis
sparse_ir/basis_set.py CHANGED
@@ -1,101 +1,143 @@
1
- # Copyright (C) 2020-2022 Markus Wallerberger, Hiroshi Shinaoka, and others
2
- # SPDX-License-Identifier: MIT
3
- from . import basis
4
- from . import sampling
1
+ """
2
+ Basis set functionality for SparseIR.
5
3
 
4
+ This module provides a convenience class that holds both fermionic and bosonic
5
+ bases along with their associated sampling objects.
6
+ """
7
+
8
+ from .basis import FiniteTempBasis, finite_temp_bases
9
+ from .sampling import TauSampling, MatsubaraSampling
6
10
 
7
- class FiniteTempBasisSet:
8
- """Class for holding IR bases and sparse-sampling objects.
9
11
 
12
+ class FiniteTempBasisSet:
13
+ """
14
+ Class for holding IR bases and sparse-sampling objects.
15
+
10
16
  An object of this class holds IR bases for fermions and bosons
11
17
  and associated sparse-sampling objects.
12
-
13
- Attributes:
14
- basis_f (FiniteTempBasis):
15
- Fermion basis
16
- basis_b (FiniteTempBasis):
17
- Boson basis
18
- smpl_tau_f (TauSampling):
19
- Sparse sampling for tau & fermion
20
- smpl_tau_b (TauSampling):
21
- Sparse sampling for tau & boson
22
- smpl_wn_f (MatsubaraSampling):
23
- Sparse sampling for Matsubara frequency & fermion
24
- smpl_wn_b (MatsubaraSampling):
25
- Sparse sampling for Matsubara frequency & boson
18
+
19
+ Attributes
20
+ ----------
21
+ basis_f : FiniteTempBasis
22
+ Fermion basis
23
+ basis_b : FiniteTempBasis
24
+ Boson basis
25
+ smpl_tau_f : TauSampling
26
+ Sparse sampling for tau & fermion
27
+ smpl_tau_b : TauSampling
28
+ Sparse sampling for tau & boson
29
+ smpl_wn_f : MatsubaraSampling
30
+ Sparse sampling for Matsubara frequency & fermion
31
+ smpl_wn_b : MatsubaraSampling
32
+ Sparse sampling for Matsubara frequency & boson
26
33
  """
27
- def __init__(self, beta, wmax, eps=None, sve_result=None):
34
+
35
+ def __init__(self, beta, wmax, eps=None, sve_result=None, use_positive_taus=False):
28
36
  """
29
- Create basis sets for fermion and boson and
30
- associated sampling objects.
37
+ Create basis sets for fermion and boson and associated sampling objects.
38
+
31
39
  Fermion and bosonic bases are constructed by SVE of the logistic kernel.
40
+
41
+ Parameters
42
+ ----------
43
+ beta : float
44
+ Inverse temperature
45
+ wmax : float
46
+ Cut-off frequency
47
+ eps : float, optional
48
+ Tolerance parameter for the basis construction.
49
+ If not provided, a default value will be used.
50
+ sve_result : SVEResult, optional
51
+ Pre-computed SVE result to use for basis construction.
52
+ If not provided, SVE will be computed internally.
53
+ use_positive_taus : bool, optional
54
+ If `use_positive_taus=False`, the sampling points are within
55
+ the range [-β/2, β/2] and the distribution is symmetric.
56
+ If `use_positive_taus=True`, the sampling points are
57
+ folded to the positive tau domain [0, β), which is
58
+ the default behavior of sparseir 1.x.x.
32
59
  """
33
60
  if sve_result is None:
34
61
  # Create bases by sve of the logistic kernel
35
- self.basis_f, self.basis_b = basis.finite_temp_bases(beta, wmax, eps)
62
+ self.basis_f, self.basis_b = finite_temp_bases(beta, wmax, eps)
36
63
  else:
37
64
  # Create bases using the given sve results
38
- self.basis_f = basis.FiniteTempBasis(
39
- "F", beta, wmax, eps, sve_result=sve_result)
40
- self.basis_b = basis.FiniteTempBasis(
41
- "B", beta, wmax, eps, sve_result=sve_result)
42
-
65
+ self.basis_f = FiniteTempBasis(
66
+ "F", beta, wmax, eps, sve_result=sve_result
67
+ )
68
+ self.basis_b = FiniteTempBasis(
69
+ "B", beta, wmax, eps, sve_result=sve_result
70
+ )
71
+
43
72
  # Tau sampling
44
- self.smpl_tau_f = sampling.TauSampling(self.basis_f)
45
- self.smpl_tau_b = sampling.TauSampling(self.basis_b)
46
-
73
+ self.smpl_tau_f = TauSampling(self.basis_f, use_positive_taus=use_positive_taus)
74
+ self.smpl_tau_b = TauSampling(self.basis_b, use_positive_taus=use_positive_taus)
75
+
47
76
  # Matsubara sampling
48
- self.smpl_wn_f = sampling.MatsubaraSampling(self.basis_f)
49
- self.smpl_wn_b = sampling.MatsubaraSampling(self.basis_b)
50
-
77
+ self.smpl_wn_f = MatsubaraSampling(self.basis_f)
78
+ self.smpl_wn_b = MatsubaraSampling(self.basis_b)
79
+
51
80
  @property
52
81
  def lambda_(self):
53
- """Ultra-violet cutoff of the kernel"""
82
+ """Ultra-violet cutoff of the kernel."""
54
83
  return self.basis_f.lambda_
55
-
84
+
56
85
  @property
57
86
  def beta(self):
58
- """Inverse temperature"""
87
+ """Inverse temperature."""
59
88
  return self.basis_f.beta
60
-
89
+
61
90
  @property
62
91
  def wmax(self):
63
- """Cut-off frequency"""
92
+ """Cut-off frequency."""
64
93
  return self.basis_f.wmax
65
-
94
+
66
95
  @property
67
96
  def accuracy(self):
68
- """Accuracy of the bases"""
97
+ """Accuracy of the bases."""
69
98
  return self.basis_f.accuracy
70
-
99
+
71
100
  @property
72
101
  def sve_result(self):
73
- """Result of singular value expansion"""
102
+ """Result of singular value expansion."""
74
103
  return self.basis_f.sve_result
75
-
104
+
76
105
  @property
77
106
  def tau(self):
78
- """Sampling points in the imaginary-time domain"""
107
+ """Sampling points in the imaginary-time domain."""
79
108
  return self.smpl_tau_f.sampling_points
80
-
109
+
81
110
  @property
82
111
  def wn_f(self):
83
- """Sampling fermionic frequencies"""
112
+ """Sampling fermionic frequencies."""
84
113
  return self.smpl_wn_f.sampling_points
85
-
114
+
86
115
  @property
87
116
  def wn_b(self):
88
- """Sampling bosonic frequencies"""
117
+ """Sampling bosonic frequencies."""
89
118
  return self.smpl_wn_b.sampling_points
90
-
119
+
91
120
  def rescale(self, new_beta):
92
- """Return a basis set for a different temperature.
93
-
121
+ """
122
+ Return a basis set for a different temperature.
123
+
94
124
  Uses the same kernel with the same ``eps``, but a different
95
- temperature. Note that this implies a different UV cutoff ``wmax``,
125
+ temperature. Note that this implies a different UV cutoff ``wmax``,
96
126
  since ``lambda_ == beta * wmax`` stays constant.
127
+
128
+ Parameters
129
+ ----------
130
+ new_beta : float
131
+ New inverse temperature
132
+
133
+ Returns
134
+ -------
135
+ FiniteTempBasisSet
136
+ New basis set for the different temperature
97
137
  """
98
138
  new_wmax = self.basis_f.lambda_ / new_beta
99
- return FiniteTempBasisSet(new_beta, new_wmax,
100
- eps=self.basis_f.sve_result.eps,
101
- sve_result=self.basis_f.sve_result)
139
+ return FiniteTempBasisSet(
140
+ new_beta, new_wmax,
141
+ eps=self.basis_f.accuracy, # Use accuracy instead of eps
142
+ sve_result=self.basis_f.sve_result
143
+ )