Coverage for gpaw/utilities/extrapolate.py: 8%
53 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1import sys
2import numpy as np
3from ase.parallel import paropen
6def extrapolate(x, y, n=-1.5, plot=0, reg=0, txt=None):
7 """Extrapolation tool. Mainly intended for RPA correlation energies,
8 but could be useful for other purposes. Fits a straight line to an
9 expression of the form: y=b + alpha*x**n and extrapolates the result
10 to infinite x. reg=N gives linear regression using the last N points in
11 x. reg should be larger than 2"""
13 if txt is None:
14 f = sys.stdout
15 elif isinstance(txt, str):
16 f = paropen(txt, 'a')
17 else:
18 f = txt
19 assert len(x) == len(y)
20 ext = []
21 print('Two-point extrapolation:', file=f)
22 for i in range(len(x) - 1):
23 alpha = (y[i] - y[i + 1]) / (x[i]**n - x[i + 1]**n)
24 ext.append(y[i + 1] - alpha * x[i + 1]**n)
25 print(' ', x[i], '-', x[i + 1], ':', ext[-1], file=f)
26 print(file=f)
28 if plot:
29 import matplotlib.pyplot as plt
30 plt.plot(x**n, y, 'o-', label='Data')
31 plt.xticks(x**n, [int(e) for e in x])
32 plt.axis([0, None, None, None])
33 if reg > 2:
34 a = x[-reg:]**n
35 b = y[-reg:]
36 N = reg
37 delta = N * np.sum(a**2) - (np.sum(a))**2
38 A = (np.sum(a**2) * np.sum(b) - np.sum(a) * np.sum(a * b)) / delta
39 B = (N * np.sum(a * b) - np.sum(a) * np.sum(b)) / delta
40 sigma_y = (1 / (N - 2) * np.sum((b - A - B * a)**2))**0.5
41 sigma_A = sigma_y * (np.sum(a**2) / delta)**0.5
43 print('Linear regression using last %s points:' % N, file=f)
44 print(' Extrapolated result:', A, file=f)
45 print(' Uncertainty:', sigma_A, file=f)
46 print(file=f)
47 if plot:
48 print([a[0], 0], [A + B * a[0], A])
49 plt.plot([a[0], 0], [A + B * a[0], A], '--', label='Regression')
50 plt.legend(loc='upper left')
51 else:
52 A = 0
53 B = 0
54 sigma_A = 0
55 if plot:
56 plt.show()
57 plt.plot(x[1:], ext, 'o-', label='Two-point extrapolation')
58 if reg > 2:
59 plt.plot([x[-reg], x[-1]], [A, A], '--', label='Regression')
60 plt.errorbar(x[-2], A, yerr=sigma_A,
61 elinewidth=2.0, capsize=5, c='g')
63 plt.legend(loc='lower right')
64 plt.show()
65 if txt is not None:
66 f.close()
67 return ext, A, B, sigma_A