def _design_controller(self, states, inputs, transitions, rng):
    logger = self._get_logger()
    (Anom, Bnom, _) = utils.solve_least_squares(states, inputs, transitions, reg=self._reg)
    eps_A = np.linalg.norm((Anom - self._A_star), ord=2)
    eps_B = np.linalg.norm((Bnom - self._B_star), ord=2)
    effective_eps_A = (self._actual_error_multiplier * eps_A)
    effective_eps_B = (self._actual_error_multiplier * eps_B)
    epoch_id = ((self._epoch_idx + 1) if self._has_primed else 0)
    logger.info('_design_controller(epoch={}): effective_eps_A={}, effective_eps_B={}'.format(epoch_id, effective_eps_A, effective_eps_B))
    if (self._use_gamma is None):
        logger.info('_design_controller(epoch={}): bisecting for gamma'.format(epoch_id))
        INF = 1000000000000.0

        def fn(gamma):
            (is_feasible, obj, _, _) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=gamma, alpha=0.5, logger=logger)
            if (not is_feasible):
                return INF
            else:
                return ((1 / (1 - gamma)) * obj)
        disp_lvl = (3 if logger.isEnabledFor(logging.DEBUG) else 0)
        (gamma_star, _, error_flag, _) = scipy.optimize.fminbound(fn, 0, (1 - 1e-05), xtol=0.01, maxfun=20, full_output=True, disp=disp_lvl)
        if error_flag:
            logger.warn('_design_controller(epoch={}): maxfun exceeded during bisection, gamma_star={}'.format(epoch_id, gamma_star))
        logger.info('_design_controller(epoch={}): using gamma_star={}'.format(epoch_id, gamma_star))
        (is_feasible, _, Phi_x, Phi_u) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=gamma_star, alpha=0.5, logger=logger)
    else:
        assert ((self._use_gamma > 0) and (self._use_gamma < 1))
        logger.info('_design_controller(epoch={}): using fixed gamma={}'.format(epoch_id, self._use_gamma))
        (is_feasible, _, Phi_x, Phi_u) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=self._use_gamma, alpha=0.5, logger=logger)
    if (not is_feasible):
        logger.info('_design_controller(epoch={}): SLS was not feasible...'.format(epoch_id))
        try:
            self._current_K
            assert (self._current_K is not None)
            logger.warn('_design_controller(epoch={}): SLS not feasible: keeping current controller'.format(epoch_id))
            self._midway_infeasible += 1
        except AttributeError:
            logger.warn('_design_controller(epoch={}): SLS not feasible: no existing controller to fallback on, effective_eps_A={}, effective_eps_B={}'.format(epoch_id, effective_eps_A, effective_eps_B))
            raise SLSInfeasibleException()
    else:
        logger.info('_design_controller(epoch={}): SLS was feasible. updating controller'.format(epoch_id))
        self._Phi_x = Phi_x
        self._Phi_u = Phi_u
        self._current_K = make_state_space_controller(Phi_x, Phi_u, self._n, self._p)
    Jnom = h2_squared_norm(self._A_star, self._B_star, self._Phi_x, self._Phi_u, self._Q, self._R, self._sigma_w)
    return (Anom, Bnom, Jnom)
def _design_controller(self, states, inputs, transitions, rng):
    logger = self._get_logger()
    (Anom, Bnom, _) = utils.solve_least_squares(states, inputs, transitions, reg=self._reg)
    eps_A = np.linalg.norm((Anom - self._A_star), ord=2)
    eps_B = np.linalg.norm((Bnom - self._B_star), ord=2)
    effective_eps_A = (self._actual_error_multiplier * eps_A)
    effective_eps_B = (self._actual_error_multiplier * eps_B)
    epoch_id = ((self._epoch_idx + 1) if self._has_primed else 0)
    logger.info('_design_controller(epoch={}): effective_eps_A={}, effective_eps_B={}'.format(epoch_id, effective_eps_A, effective_eps_B))
    if (self._use_gamma is None):
        logger.info('_design_controller(epoch={}): bisecting for gamma'.format(epoch_id))
        INF = 1000000000000.0

        def fn(gamma):
            (is_feasible, obj, _, _) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=gamma, alpha=0.5, logger=logger)
            if (not is_feasible):
                return INF
            else:
                return ((1 / (1 - gamma)) * obj)
        disp_lvl = (3 if logger.isEnabledFor(logging.DEBUG) else 0)
        (gamma_star, _, error_flag, _) = scipy.optimize.fminbound(fn, 0, (1 - 1e-05), xtol=0.01, maxfun=20, full_output=True, disp=disp_lvl)
        if error_flag:
            logger.warn('_design_controller(epoch={}): maxfun exceeded during bisection, gamma_star={}'.format(epoch_id, gamma_star))
        logger.info('_design_controller(epoch={}): using gamma_star={}'.format(epoch_id, gamma_star))
        (is_feasible, _, Phi_x, Phi_u) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=gamma_star, alpha=0.5, logger=logger)
    else:
        assert ((self._use_gamma > 0) and (self._use_gamma < 1))
        logger.info('_design_controller(epoch={}): using fixed gamma={}'.format(epoch_id, self._use_gamma))
        (is_feasible, _, Phi_x, Phi_u) = self._sls_impl.synth(self._Q, self._R, Anom, Bnom, effective_eps_A, effective_eps_B, self._truncation_length, gamma=self._use_gamma, alpha=0.5, logger=logger)
    if (not is_feasible):
        logger.info('_design_controller(epoch={}): SLS was not feasible...'.format(epoch_id))
        try:
            self._current_K
            assert (self._current_K is not None)
            logger.warn('_design_controller(epoch={}): SLS not feasible: keeping current controller'.format(epoch_id))
            self._midway_infeasible += 1
        except AttributeError:
            logger.warn('_design_controller(epoch={}): SLS not feasible: no existing controller to fallback on, effective_eps_A={}, effective_eps_B={}'.format(epoch_id, effective_eps_A, effective_eps_B))
            raise SLSInfeasibleException()
    else:
        logger.info('_design_controller(epoch={}): SLS was feasible. updating controller'.format(epoch_id))
        self._Phi_x = Phi_x
        self._Phi_u = Phi_u
        self._current_K = make_state_space_controller(Phi_x, Phi_u, self._n, self._p)
    Jnom = h2_squared_norm(self._A_star, self._B_star, self._Phi_x, self._Phi_u, self._Q, self._R, self._sigma_w)
    return (Anom, Bnom, Jnom)