in src/envs/ode.py [0:0]
def gen_fourier_cond_init(self):
while True:
try:
dimension = self.rng.randint(self.min_degree, self.max_degree + 1)
nb_ops = self.rng.randint(dimension, 2 * dimension + 3)
# Generate differential operator
unariesd = ["id", "pow2", "pow4"]
expr = self.generate_polynomial(
nb_ops, 4, dimension, unariesd, True, False
)
# print(sp.S(expr))
# Fourier transform of the differential operator
PF = OrderedDict(
{
self.variables[f"x{i}"]: 2
* np.pi
* 1j
* self.variables[f"x{i}"]
for i in range(self.max_degree)
}
)
poly_fourier = sp.S(expr).subs(PF)
# print(poly_fourier)
# Generate initial condition
unariesexp = ["expi"]
unariesfk = ["1", "sinc", "delta0", "gauss"]
max_delay_op = 2 * dimension
expr_u0, bounds = self.generate_cond_init(
max_delay_op, dimension, unariesexp, unariesfk
)
# print(sp.S(expr_u0))
# print(bounds)
# Minimization of the Fourier transform of the differential operator
# on the frequency of the initial conditions
dum_point = np.zeros(dimension, dtype=float) + 0.5
max_f = opt.minimize(
expr_to_fun_real,
dum_point,
args=(poly_fourier, dimension),
method="TNC",
bounds=bounds,
options={"ftol": 1e-15, "gtol": 1e-15},
)
# print(max_f.fun)
if not max_f.success:
# logger.info(f'optimization error')
continue
if max_f.fun < -1e14:
reg = 0 # -1
stab = 0
elif max_f.fun < 0:
reg = 1 # 0
stab = 0
elif max_f.fun >= 0:
reg = 1
stab = 1
else:
# logger.info(f'optimization error in value')
continue
except Exception as e:
print(e)
continue
break
# encode input
x = self.write_int(dimension)
x.append(self.func_separator)
x.extend(self.encode_expr(expr, True))
x.append(self.func_separator)
x.extend(self.encode_expr(expr_u0, True))
# encode output
y = self.write_int(reg)
y.append(self.func_separator)
y.extend(self.write_int(stab))
if self.predict_bounds:
y.append(self.func_separator)
for i in range(len(bounds)):
if bounds[i][0] == np.inf:
y.append(self.pos_inf)
elif bounds[i][0] == -np.inf:
y.append(self.neg_inf)
else:
y.extend(self.write_float(bounds[i][0], 2))
y.append(self.list_separator)
if bounds[i][1] == np.inf:
y.append(self.pos_inf)
elif bounds[i][1] == -np.inf:
y.append(self.neg_inf)
else:
y.extend(self.write_float(bounds[i][1], 2))
y.append(self.line_separator)
return x, y