1
1
"""
2
2
finite size scaling tools
3
3
"""
4
- from typing import List , Tuple
4
+ from typing import List , Tuple , Optional
5
5
6
6
import numpy as np
7
7
@@ -14,6 +14,8 @@ def data_collapse(
14
14
nu : float ,
15
15
beta : float = 0 ,
16
16
obs_type : int = 1 ,
17
+ fit_type : int = 0 ,
18
+ dobs : Optional [List [List [float ]]] = None ,
17
19
) -> Tuple [List [float ], List [List [float ]], List [List [float ]], float ]:
18
20
xL : List [List [float ]] = [] # x=(p-pc)L^(1/\nv)
19
21
yL : List [List [float ]] = [] # y=S(p,L)-S(pc,L) or S(p,L)
@@ -33,27 +35,61 @@ def data_collapse(
33
35
yL [n0 ].append (obs [n0 ][p0 ] * n [n0 ] ** beta )
34
36
# tripartite mutual information
35
37
pc_list .append (pc_L )
36
- xL_all = []
37
- for i in range (len (xL )):
38
- xL_all .extend (xL [i ])
39
- yL_ave = []
40
- loss = []
41
- for x0 in range (len (xL_all )):
42
- ybar_list = []
43
- for n0 in range (len (n )):
44
- if xL_all [x0 ] >= xL [n0 ][0 ] and xL_all [x0 ] <= xL [n0 ][- 1 ]:
45
- yinsert = pc_linear_interpolation (xL [n0 ], yL [n0 ], xL_all [x0 ])
46
- ybar_list .append (yinsert )
38
+ if fit_type == 0 :
39
+ xL_all = []
40
+ for i in range (len (xL )):
41
+ xL_all .extend (xL [i ])
42
+ yL_ave = []
43
+ loss = []
44
+ for x0 in range (len (xL_all )):
45
+ ybar_list = []
46
+ for n0 in range (len (n )):
47
+ if xL_all [x0 ] >= xL [n0 ][0 ] and xL_all [x0 ] <= xL [n0 ][- 1 ]:
48
+ yinsert = pc_linear_interpolation (xL [n0 ], yL [n0 ], xL_all [x0 ])
49
+ ybar_list .append (yinsert )
50
+
51
+ ybar = np .mean (ybar_list )
52
+ mean_squared = [(ybar_list [i ] - ybar ) ** 2 for i in range (len (ybar_list ))]
53
+ loss .append (np .sum (mean_squared ))
54
+ yL_ave .append (ybar )
55
+ loss = np .sum (loss )
47
56
48
- ybar = np .mean (ybar_list )
49
- mean_squared = [(ybar_list [i ] - ybar ) ** 2 for i in range (len (ybar_list ))]
50
- loss .append (np .sum (mean_squared ))
51
- yL_ave .append (ybar )
52
- loss = np .sum (loss )
57
+ return pc_list , xL , yL , loss # type: ignore
53
58
59
+ # fit_type == 1
60
+ if dobs is None :
61
+ raise ValueError ("uncertainty of each y has to be specified in `dobs`" )
62
+
63
+ datas = []
64
+ for n0 in range (len (n )):
65
+ for i in range (len (xL [n0 ])):
66
+ datas .append ([xL [n0 ][i ], yL [n0 ][i ], dobs [n0 ][i ]])
67
+ datas = sorted (datas , key = lambda x : x [0 ])
68
+ loss = _quality_objective_v2 (datas ) # type: ignore
54
69
return pc_list , xL , yL , loss # type: ignore
55
70
56
71
72
+ def _quality_objective_v2 (datas : List [List [float ]]) -> float :
73
+ # https://journals.aps.org/prb/supplemental/10.1103/PhysRevB.101.060301/Supplement.pdf
74
+ loss = []
75
+ for i in range (len (datas ) - 2 ):
76
+ # i, i+1, i+2
77
+ x , y , d = datas [i + 1 ]
78
+ x1 , y1 , d1 = datas [i ]
79
+ x2 , y2 , d2 = datas [i + 2 ]
80
+ if np .abs (x - x1 ) < 1e-4 or np .abs (x - x2 ) < 1e-4 :
81
+ continue
82
+ ybar = ((x2 - x ) * y1 - (x1 - x ) * y2 ) / (x2 - x1 )
83
+ delta = (
84
+ d ** 2
85
+ + d1 ** 2 * (x2 - x ) ** 2 / (x2 - x1 ) ** 2
86
+ + d2 ** 2 * (x1 - x ) ** 2 / (x2 - x1 ) ** 2
87
+ )
88
+ w = (y - ybar ) ** 2 / delta
89
+ loss .append (w )
90
+ return np .mean (loss ) # type: ignore
91
+
92
+
57
93
def pc_linear_interpolation (p : List [float ], SA : List [float ], pc_input : float ) -> float :
58
94
if pc_input in p :
59
95
pc_index = p .index (pc_input )
0 commit comments