-
Notifications
You must be signed in to change notification settings - Fork 0
/
fpe.py
144 lines (114 loc) · 4.01 KB
/
fpe.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from fpcross import EquationOUP
from fpcross import FPCross
import numpy as np
import os
import teneva
from time import perf_counter as tpc
class FpeOUP:
def __init__(self, d=3, seed=42):
self.seed = seed
if d == 3:
self.init_problem_3d()
elif d == 4:
self.init_problem_4d()
elif d == 5:
self.init_problem_5d()
else:
raise NotImplementedError()
self.with_y_list = False
def data_build(self, m, fpath=None, seed=None, tst=False):
if seed is None:
seed = self.seed
t = tpc()
if tst:
I = teneva.sample_rand([self.n]*self.d_opt, m, seed)
else:
I = teneva.sample_lhs([self.n]*self.d_opt, m, seed)
y = self.run_grid_many(I)
t = tpc() - t
if fpath:
np.savez_compressed(fpath, data={'I': I, 'y': y, 't': t})
return I, y, self.data_info(I, y, t, tst=tst, load=False)
def data_info(self, I, y, t, tst=False, load=False):
title1 = '\n------------> '
title2 = 'Loaded dataset ' if load else 'Generated dataset '
title3 = '(tst)\n' if tst else '(trn)\n'
text = title1 + title2 + title3
text += f'- Dimension : {I.shape[1]:-10d}\n'
text += f'- Samples : {I.shape[0]:-10.2e}\n'
text += f'- Time full : {t:-10.2e}\n'
text += f'- Time call : {t/len(I):-10.2e}\n'
text += f'- Value min : {np.min(y):-10.4e}\n'
text += f'- Value avg : {np.mean(y):-10.4e}\n'
text += f'- Value max : {np.max(y):-10.4e}\n'
text += '\n'
return text
def data_load(self, fpath, tst=False):
data = np.load(fpath, allow_pickle=True).get('data').item()
I, y, t = data['I'], data['y'], data['t']
return I, y, self.data_info(I, y, t, tst=tst, load=True)
def init_problem_3d(self):
self.d = 3
self.d_opt = self.d * self.d
self.n = 11
self.ind_to_poi = lambda i: i / 10
rand = np.random.default_rng(self.seed)
self.A_base = rand.random((self.d, self.d)) * 1.E-3
self.A_opt = np.array([
[0.8, 0.4, 0.1],
[0.5, 0.9, 0.2],
[0.3, 0.7, 0.6],
])
def init_problem_4d(self):
self.d = 4
self.d_opt = self.d * self.d
self.n = 11
self.ind_to_poi = lambda i: i / 10
rand = np.random.default_rng(self.seed)
self.A_base = rand.random((self.d, self.d)) * 1.E-3
self.A_opt = np.array([
[0.8, 0.4, 0.1, 0.2],
[0.5, 0.9, 0.2, 0.3],
[0.3, 0.7, 0.6, 0.5],
[0.4, 0.5, 0.4, 0.7],
])
def init_problem_5d(self):
self.d = 5
self.d_opt = self.d * self.d
self.n = 11
self.ind_to_poi = lambda i: i / 10
rand = np.random.default_rng(self.seed)
self.A_base = rand.random((self.d, self.d)) * 1.E-3
self.A_opt = np.array([
[0.8, 0.4, 0.1, 0.2, 0.1],
[0.5, 0.9, 0.2, 0.3, 0.2],
[0.3, 0.7, 0.6, 0.5, 0.4],
[0.4, 0.5, 0.4, 0.7, 0.3],
[0.2, 0.1, 0.3, 0.2, 0.9],
])
def loss(self, Y):
dY = teneva.sub(self.Y_opt, Y)
return teneva.norm(dY)
def prep(self):
self.Y_opt = self.run(self.A_opt)
def run(self, A, with_y_list=False):
eq = EquationOUP(d=self.d)
eq.set_cross_opts(nswp=3, dr_min=0)
eq.set_grid(n=15, a=-5., b=+5.)
eq.set_grid_time(m=10, t=0.5)
eq.set_coef_rhs(self.A_base + A)
eq.init()
eq.with_rs = False
eq.with_rt = False
fpc = FPCross(eq, with_hist=False, with_log=False,
with_y_list=self.with_y_list)
fpc.solve()
if self.with_y_list:
self.Y_list = fpc.Y_list
return fpc.Y
def run_grid(self, i):
A = self.ind_to_poi(i).reshape(self.d, self.d)
Y = self.run(A)
return self.loss(Y)
def run_grid_many(self, I):
return np.array([self.run_grid(i) for i in I])