def find_transform(x, y, limit, threshold=1e-7): """ find a integer solution to ax + b - cxy - dy = 0 this will give us the mobius transform: T(x) = y :param x: numeric constant to check :param y: numeric manipulation of constant :param limit: range to look at :param threshold: optimal solution threshold. :return MobiusTransform in case of success or None. """ x1 = x x2 = dec(1.0) x3 = -x * y x4 = -y solver = Solver('mobius', Solver.CBC_MIXED_INTEGER_PROGRAMMING) a = solver.IntVar(-limit, limit, 'a') b = solver.IntVar(-limit, limit, 'b') c = solver.IntVar(-limit, limit, 'c') d = solver.IntVar(-limit, limit, 'd') f = solver.NumVar(0, 1, 'f') solver.Add(f == (a * x1 + b * x2 + c * x3 + d * x4)) solver.Add(a * x1 + b >= 1) # don't except trivial solutions and remove some redundancy solver.Minimize(f) status = solver.Solve() if status == Solver.OPTIMAL: if abs(solver.Objective().Value()) <= threshold: res_a, res_b, res_c, res_d = int(a.solution_value()), int(b.solution_value()),\ int(c.solution_value()), int(d.solution_value()) ret = MobiusTransform( np.array([[res_a, res_b], [res_c, res_d]], dtype=object)) ret.normalize() return ret else: return None
def _declare_constraint( solver: pywraplp.Solver, group: "Group", variables: typing.Tuple[typing.Tuple[pywraplp.Variable]], ) -> None: higher_groups = group.get_simultaneous_groups_of_higher_cycle() if higher_groups: # fixed duration of group summed_active_transitions_of_group = Group._sum_active_transitions_of_group( group, higher_groups) # fixed duration of higher groups summed_transitions_of_higher_groups = sum( Group._calculate_duration_of_n_phases(higher_group, higher_group.attack) for higher_group in higher_groups) summed_transitions_of_higher_groups += Group._calculate_duration_of_n_phases( higher_groups[-1], higher_groups[-1].release) difference_of_duration = (summed_active_transitions_of_group - summed_transitions_of_higher_groups) constraint = sum( Group._calculate_duration_of_n_phases(higher_group, var) for var, higher_group in zip(variables[1], higher_groups)) constraint = constraint - (Group._calculate_duration_of_n_phases( group, variables[0][0])) solver.Add(constraint == difference_of_duration)