def gen_control_t()

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