in src/envs/ode.py [0:0]
def gen_control_t(self):
"""
Generate systems of functions, data for controlability
"""
while True:
degree = self.rng.randint(self.min_degree, self.max_degree + 1)
p = self.rng.randint(1, degree // 2 + 1)
nb_ops = self.rng.randint(degree + p, 2 * (degree + p) + 3, size=(degree,))
ev_point = OrderedDict(
{self.variables[f"x{i}"]: self.eval_value for i in range(degree + p)}
)
system = []
i = 0
A = sp.Matrix()
B = sp.Matrix()
ngen = 0
while i < degree:
# generate expression
# si tau>0 doit on garantir l'existence de t (x{degree + p}) ?
expr = self.generate_tree(nb_ops[i], degree + p + 1)
ngen += 1
# sympy zone
try:
expr_sp = sp.S(expr, locals=self.local_dict)
# skip constant or invalid expressions
if len(expr_sp.free_symbols) == 0 or has_inf_nan(expr_sp):
continue
# evaluate gradient in point
valA, valB = self.compute_gradient_control_t(
expr_sp, ev_point, degree, p
)
# print('valA', valA)
# print('valB', valB)
if any(has_inf_nan(a) for a in valA) or any(
has_inf_nan(a) for a in valB
):
continue
if self.skip_zero_gradient and all(a == 0 for a in valA):
continue
except TimeoutError:
continue
except (ValueError, TypeError):
continue
except Exception as e:
logger.error(
"An unknown exception of type {0} occurred in line {1} "
'for expression "{2}". '
"Arguments:{3!r}.".format(
type(e).__name__,
sys.exc_info()[-1].tb_lineno,
expr_sp,
e.args,
)
)
continue
system.append(expr)
v1 = sp.Matrix(1, degree, valA)
v2 = sp.Matrix(1, p, valB)
A = A.col_join(v1)
B = B.col_join(v2)
i += 1
if self.skip_zero_gradient:
if any(all(A[j, i] == 0 for j in range(degree)) for i in range(degree)):
continue
if any(all(B[j, i] == 0 for j in range(degree)) for i in range(p)):
continue
try:
d = self.compute_rank(A, B, degree, p, 2)
except TimeoutError:
continue
# except FloatingPointError:
# continue
except Exception as e:
logger.error(
"An unknown exception of type {0} occurred in line {1} "
'for expression "{2}". '
"Arguments:{3!r}.".format(
type(e).__name__, sys.exc_info()[-1].tb_lineno, expr_sp, e.args
)
)
continue
break
# # debug
# logger.info(str(cspeed))
# logger.info(str(cspeed) + "\t" + " ||||| ".join(str(s) for s in system[:3]))
# print(degree, str(ngen) + " : " + str((ngen - degree) / ngen * 100.0))
# print(', '.join(f"{s} {t:.3f}" for s, t in times))
# encode input
x = self.write_int(degree)
for s in system:
x.append(self.func_separator)
x.extend(self.encode_expr(s))
# encode output: dimension of control subspace and optionally the Gramian matrix
controlable = 1 if d == 0 else 0
y = self.write_int(controlable)
if self.max_len > 0 and (len(x) >= self.max_len or len(y) >= self.max_len):
return None
return x, y