예제 #1
0
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
예제 #2
0
def _parse_declaration(solver: pywraplp.Solver, core_line: str, line_nr: int,
                       var_names: set):
    spl_whitespace = core_line.split(maxsplit=1)

    if spl_whitespace[0] != "int":
        raise ValueError("Declaration on line %d should start with \"int \"." %
                         line_nr)

    if len(spl_whitespace) != 2:
        raise ValueError("Declaration on line %d has no variables." % line_nr)

    spl_variables = spl_whitespace[1].split(",")
    for raw_var in spl_variables:
        clean_var = raw_var.strip()
        if not re.match(_REGEXP_SINGLE_VAR_NAME_ALL, clean_var):
            raise ValueError(
                "Non-permitted variable name (\"%s\") on line %d." %
                (clean_var, line_nr))
        if clean_var in var_names:
            raise ValueError("Variable \"%s\" declared again on line %d." %
                             (clean_var, line_nr))
        var_names.add(clean_var)
        solver.IntVar(-solver.infinity(), solver.infinity(), clean_var)