Exemple #1
0
 def test_nested_relational(self):
     expr = Expression(
         sympy.And(
             sympy.Or(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Or(sympy.Eq(self.e, self.f), sympy.Lt(self.g, self.f))))
     self.assertEqual(expr.rhs_cstr,
                      '(a == b || c == d) && (e == f || g < f)')
Exemple #2
0
 def test_nested_relational(self):
     expr = Expression('((a == b) || (c == d)) && ((e == f) || (g < f))')
     self.assertEqual(
         expr.rhs,
         sympy.And(
             sympy.Or(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Or(sympy.Eq(self.e, self.f), sympy.Lt(self.g, self.f))))
Exemple #3
0
def border_conditions(direction, field, ghost_layers=1):
    abs_direction = tuple(-e if e < 0 else e for e in direction)
    assert sum(abs_direction) == 1
    idx = abs_direction.index(1)
    val = direction[idx]

    loop_ctrs = [
        LoopOverCoordinate.get_loop_counter_symbol(i)
        for i in range(len(direction))
    ]
    loop_ctr = loop_ctrs[idx]

    gl = ghost_layers
    border_condition = sp.Eq(loop_ctr,
                             gl if val < 0 else field.shape[idx] - gl - 1)

    if ghost_layers == 0:
        return type_all_numbers(border_condition, loop_ctr.dtype)
    else:
        other_min = [sp.Ge(c, gl) for c in loop_ctrs if c != loop_ctr]
        other_max = [
            sp.Lt(c, field.shape[i] - gl) for i, c in enumerate(loop_ctrs)
            if c != loop_ctr
        ]
        result = sp.And(border_condition, *other_min, *other_max)
        return type_all_numbers(result, loop_ctr.dtype)
Exemple #4
0
def quadratic_denom_rule(integral):
    integrand, symbol = integral
    a = sympy.Wild('a', exclude=[symbol])
    b = sympy.Wild('b', exclude=[symbol])
    c = sympy.Wild('c', exclude=[symbol])
    match = integrand.match(a / (b * symbol**2 + c))

    if not match:
        return

    a, b, c = match[a], match[b], match[c]
    return PiecewiseRule([
        (ArctanRule(a, b, c, integrand, symbol), sympy.Gt(c / b, 0)),
        (ArccothRule(a, b, c, integrand, symbol),
         sympy.And(sympy.Gt(symbol**2, -c / b), sympy.Lt(c / b, 0))),
        (ArctanhRule(a, b, c, integrand, symbol),
         sympy.And(sympy.Lt(symbol**2, -c / b), sympy.Lt(c / b, 0))),
    ], integrand, symbol)
Exemple #5
0
def test_pheno(parser):
    code = """$PK

IF(AMT.GT.0) BTIME=TIME
TAD=TIME-BTIME
      TVCL=THETA(1)*WGT
      TVV=THETA(2)*WGT
IF(APGR.LT.5) TVV=TVV*(1+THETA(3))
      CL=TVCL*EXP(ETA(1))
      V=TVV*EXP(ETA(2))
      S1=V
"""
    rec = parser.parse(code).records[0]
    assert len(rec.statements) == 8
    assert rec.statements[0].symbol == S('BTIME')
    assert rec.statements[1].symbol == S('TAD')
    assert rec.statements[2].symbol == S('TVCL')
    assert rec.statements[3].symbol == S('TVV')
    assert rec.statements[4].symbol == S('TVV')
    assert rec.statements[5].symbol == S('CL')
    assert rec.statements[6].symbol == S('V')
    assert rec.statements[7].symbol == S('S1')
    assert rec.statements[0].expression == sympy.Piecewise(
        (S('TIME'), sympy.Gt(S('AMT'), 0)), (0, True))
    assert rec.statements[1].expression == S('TIME') - S('BTIME')
    assert rec.statements[2].expression == S('THETA(1)') * S('WGT')
    assert rec.statements[3].expression == S('THETA(2)') * S('WGT')
    assert rec.statements[4].expression == sympy.Piecewise(
        (S('TVV') * (1 + S('THETA(3)')), sympy.Lt(S('APGR'), 5)),
        (S('TVV'), True))
    assert rec.statements[5].expression == S('TVCL') * sympy.exp(S('ETA(1)'))
    assert rec.statements[6].expression == S('TVV') * sympy.exp(S('ETA(2)'))
    assert rec.statements[7].expression == S('V')
    symbol_names = {s.name for s in rec.statements.free_symbols}
    assert symbol_names == {
        'AMT',
        'BTIME',
        'TIME',
        'TAD',
        'TVCL',
        'THETA(1)',
        'WGT',
        'TVV',
        'THETA(2)',
        'APGR',
        'THETA(3)',
        'CL',
        'ETA(1)',
        'V',
        'ETA(2)',
        'S1',
    }
Exemple #6
0
def extreme(fn, over, maximizing):
    """Maximizes [minimizes] the function fn for 'over'.  Returns the
    first extreme expression and a list of conditions for it to be a
    maximum [minimum].

    >>> sp.var('x p', positive=True)
    (x, p)
    >>> theta = sp.Symbol('theta', positive=True)
    >>> fn = p*x - theta*x*x
    >>> maximize(fn, x)
    (p/(2*theta), 0 < theta)
    >>> maximize(fn.subs(theta, 1), x)
    (p/2, 0 <= p)
    >>> maximize(fn.subs(theta, -1), x)
    (None, False)
    """
    first = sp.diff(fn, over)
    extremes_at = sp.solve(first, over)
    second = sp.diff(first, over)
    for m in extremes_at:
        positive = False
        try:
            ## We only want values of over that are positive.
            positive = sp.solve(sp.Ge(m, 0))
        except:
            ## Inequality solve only works with a single variable.
            ## Assume it is true.  We are missing a condition.
            positive = True

        ## Checking for inequality to False because an inequality will
        ## evaluate as False even if present in positive
        if positive is not False:
            conditions = []
            if positive is not True:
                conditions.append(positive)
            try:
                if maximizing:
                    max_min_cond = sp.solve(sp.Lt(second.subs(over, m), 0))
                else:
                    max_min_cond = sp.solve(sp.Gt(second.subs(over, m), 0))
            except:
                ## Not always works.  Assume it is true.  We are
                ## missing a condition.
                max_min_cond = True
            if max_min_cond:
                if max_min_cond is not True:
                    conditions.append(max_min_cond)
                return m, reduce(sp.And, [True] + conditions)
    return None, False
Exemple #7
0
 def supply(self):
     """
     >>> sp.var('p q', positive=True)
     (p, q)
     >>> f = Firm(q, p, q**2/1000., SFC=1000)
     >>> f.supply()
     Piecewise((0, p < 1000.0), (500.0*p, And(0 <= p, p >= 1000.0)))
     >>> f = Firm(q, p, 10*q, SFC=0, FC=0)
     >>> f.supply()
     p - 10 == 0
     """
     min_atc, min_atc_cond = self.min_atc_sfc()
     supply, supply_cond = tools.maximize(self.earnings(), over=self.q)
     if supply is None:
         return sp.Eq(sp.diff(self.earnings(), self.q), 0)
     return sp.Piecewise(
         (0, sp.Lt(self.p, min_atc)),
         (supply, sp.And(sp.Ge(self.p, min_atc), supply_cond,
                         min_atc_cond)))
Exemple #8
0
    def demand(self, rational=True):
        """Compute the demand as the maximization of the utility function.

        >>> sp.var('x p')
        (x, p)
        >>> cu = Consumer(x, p, benefit=tools.benefit_from_demand(x, p, 9/p - 1))
        >>> sp.simplify(cu.benefit() - 9*sp.log(x + 1))
        0
        >>> cu.demand()
        Piecewise((0, p < 0), ((-p + 9)/p, True))
        >>> tau = sp.Symbol('tau')
        >>> cu_rat = Consumer(x, p, benefit=2*sp.sqrt(x))
        >>> cu_del = Consumer(x, p, benefit=2*sp.sqrt(x),
        ...                   decision_benefit=20*sp.sqrt(x),
        ...                   other=-(1+tau)*p*x)
        >>> sp.solve(cu_del.demand(rational=False)-cu_rat.demand(), tau)
        [-11, 9]
        """
        maxima, condition = tools.maximize(self.utility(rational), over=self.x)
        if maxima is None:
            maxima = 0
        return sp.Piecewise((0, sp.Lt(self.p, 0)), (maxima, condition),
                            (0, True))
def _make_comparison_question(context, left, right):
    """Makes a question for comparing two values."""
    if random.choice([False, True]) and sympy.Ne(left.value, right.value):
        # Do question of form: "Which is bigger: a or b?".
        if random.choice([False, True]):
            answer = (left.handle
                      if sympy.Gt(left.value, right.value) else right.handle)
            template = random.choice([
                'Which is bigger: {left} or {right}?',
                'Which is greater: {left} or {right}?',
            ])
        else:
            answer = (left.handle
                      if sympy.Lt(left.value, right.value) else right.handle)
            template = random.choice([
                'Which is smaller: {left} or {right}?',
            ])
        return example.Problem(question=example.question(context,
                                                         template,
                                                         left=left,
                                                         right=right),
                               answer=answer)

    comparisons = {
        '<': sympy.Lt,
        '<=': sympy.Le,
        '>': sympy.Gt,
        '>=': sympy.Ge,
        '=': sympy.Eq,
        '!=': sympy.Ne,
    }

    templates = {
        '<': [
            'Is {left} ' + ops.LT_SYMBOL + ' {right}?',
            'Is {left} less than {right}?',
            'Is {left} smaller than {right}?',
        ],
        '<=': [
            'Is {left} ' + ops.LE_SYMBOL + ' {right}?',
            'Is {left} less than or equal to {right}?',
            'Is {left} at most {right}?',
            'Is {left} at most as big as {right}?',
        ],
        '>': [
            'Is {left} ' + ops.GT_SYMBOL + ' {right}?',
            'Is {left} greater than {right}?',
            'Is {left} bigger than {right}?',
        ],
        '>=': [
            'Is {left} ' + ops.GE_SYMBOL + ' {right}?',
            'Is {left} greater than or equal to {right}?',
            'Is {left} at least {right}?',
            'Is {left} at least as big as {right}?',
        ],
        '=': [
            'Does {left} ' + ops.EQ_SYMBOL + ' {right}?',
            'Are {left} and {right} equal?',
            'Is {left} equal to {right}?',
            'Do {left} and {right} have the same value?',
        ],
        '!=': [
            'Is {left} ' + ops.NE_SYMBOL + ' {right}?',
            'Is {left} not equal to {right}?',
            'Are {left} and {right} unequal?',
            'Are {left} and {right} nonequal?',
            'Are {left} and {right} non-equal?',
            'Do {left} and {right} have different values?',
        ],
    }

    comparison = random.choice(list(comparisons.keys()))
    template = random.choice(templates[comparison])
    question = example.question(context, template, left=left, right=right)
    answer = comparisons[comparison](left.value, right.value)

    return example.Problem(question=question, answer=answer)
Exemple #10
0
def sum_over_piecewise(expr: sympy.Piecewise,
                       sum_var: sympy.Symbol,
                       sum_start: typing.Union[sympy.Basic, int],
                       sum_end: sympy.Basic,
                       extra_condition: sympy.Basic = True) -> sympy.Expr:
    """
  :return: equivalent to Sum(expr, (sum_var, sum_start, sum_end)), but we try to remove the piecewise.
    We assume that the piecewise conditions also depend on sum_var.
  """
    assert sum_var.is_Integer or sum_var.assumptions0["integer"]
    assert isinstance(expr, sympy.Piecewise)
    res = sympy.sympify(0)
    cond_start = sympy.Ge(sum_var, sum_start)
    cond_end = sympy.Le(sum_var, sum_end)
    prev_ranges = [(None, sum_start - 1), (sum_end + 1, None)]

    def check(cond__):
        false_cond = simplify_and(sympy.And(sympy.Not(cond__),
                                            extra_condition))
        if false_cond == sympy.sympify(False):
            return True
        true_cond = simplify_and(sympy.And(cond__, extra_condition))
        if true_cond == sympy.sympify(False):
            return False
        return None

    for value, cond in expr.args:
        j = 0
        while j < len(prev_ranges) - 1:
            cond_r_start = sympy.Ge(sum_var, prev_ranges[j][1] + 1)
            cond_r_end = sympy.Le(sum_var, prev_ranges[j + 1][0] - 1)
            cond = sympy.And(cond, cond_start, cond_end, cond_r_start,
                             cond_r_end)
            cond_ = simplify_and(cond,
                                 sum_var,
                                 extra_conditions=extra_condition)
            # print(cond, "->", cond_)
            if cond_ == sympy.sympify(False):
                j += 1
                continue

            if isinstance(cond_, sympy.And):
                if any(
                    [sum_var not in part.free_symbols for part in cond_.args]):
                    new_extra_conditions = [
                        part for part in cond_.args
                        if sum_var not in part.free_symbols
                    ]
                    new_extra_condition = sympy.And(*new_extra_conditions)
                    if check(new_extra_condition) is False:
                        j += 1
                        continue
                    assert check(new_extra_condition)
                    cond_ = sympy.And(*[
                        part for part in cond_.args
                        if sum_var in part.free_symbols
                    ])

            r = range_from_relationals(cond_, sum_var)
            if r[0] is None:  # e.g. if cond_start == True because sum_var is >= 0 always
                r = (sum_start, r[1])
            if sympy.Eq(r[0], r[1]) == sympy.sympify(True):
                res += value.subs(sum_var, r[0])
            else:
                res += sympy.Sum(value, (sum_var, r[0], r[1])).doit()

            for i in range(1, len(prev_ranges) + 1):
                assert i < len(prev_ranges), "where to insert %r?" % (
                    r, )  # should not get past here
                assert check(sympy.Gt(r[0], prev_ranges[i - 1][1]))
                if check(sympy.Eq(r[0] - 1, prev_ranges[i - 1][1])):
                    prev_ranges[i - 1] = (prev_ranges[i - 1][0], r[1])
                    break
                if check(sympy.Lt(r[0], prev_ranges[i][0])) or check(
                        sympy.Lt(r[1], prev_ranges[i][0])):
                    if check(sympy.Eq(r[1] + 1, prev_ranges[i][0])):
                        prev_ranges[i] = (r[0], prev_ranges[i][1])
                    else:
                        prev_ranges.insert(i, r)
                    break

            # print("prev ranges:", prev_ranges)
            j = 0  # start over...

        if len(prev_ranges) == 2 and sympy.Eq(
                prev_ranges[0][1], prev_ranges[1][0]) == sympy.sympify(True):
            # We have the full range covered.
            break

    return res.simplify()
Exemple #11
0
def simplify_and(
        x: sympy.Basic,
        gen: typing.Optional[sympy.Symbol] = None,
        extra_conditions: typing.Optional[sympy.Basic] = True) -> sympy.Basic:
    """
  Some rules, because SymPy currently does not automatically simplify them...
  """
    assert isinstance(x, sympy.Basic), "type x: %r" % type(x)
    from sympy.solvers.inequalities import reduce_rational_inequalities
    from sympy.core.relational import Relational

    syms = []
    if gen is not None:
        syms.append(gen)

    w1 = sympy.Wild("w1")
    w2 = sympy.Wild("w2")
    for sub_expr in x.find(sympy.Eq(w1, w2)):
        m = sub_expr.match(sympy.Eq(w1, w2))
        ws_ = m[w1], m[w2]
        for w_ in ws_:
            if isinstance(w_, sympy.Symbol) and w_ not in syms:
                syms.append(w_)
    for w_ in x.free_symbols:
        if w_ not in syms:
            syms.append(w_)

    if len(syms) >= 1:
        _c = syms[0]
        if len(syms) >= 2:
            n = syms[1]
        else:
            n = sympy.Wild("n")
    else:
        return x

    x = x.replace(((_c - 2 * n >= -1) & (_c - 2 * n <= -1)),
                  sympy.Eq(_c, 2 * n - 1))  # probably not needed anymore...
    apply_rules = True
    while apply_rules:
        apply_rules = False
        for and_expr in x.find(sympy.And):
            assert isinstance(and_expr, sympy.And)

            and_expr_ = reduce_rational_inequalities([and_expr.args], _c)
            # print(and_expr, "->", and_expr_)
            if and_expr_ != and_expr:
                x = x.replace(and_expr, and_expr_)
                and_expr = and_expr_
                if and_expr == sympy.sympify(False):
                    continue
                if isinstance(and_expr, sympy.Rel):
                    continue
                assert isinstance(and_expr, sympy.And)

            and_expr_args = list(and_expr.args)
            # for i, part in enumerate(and_expr_args):
            #  and_expr_args[i] = part.simplify()
            if all([
                    isinstance(part, Relational) and _c in part.free_symbols
                    for part in and_expr_args
            ]):
                # No equality, as that should have been resolved above.
                rel_ops = ["==", ">=", "<="]
                if not (_c.is_Integer or _c.assumptions0["integer"]):
                    rel_ops.extend(["<", ">"])
                rhs_by_c = {op: [] for op in rel_ops}
                for part in and_expr_args:
                    assert isinstance(part, Relational)
                    part = _solve_inequality(part, _c)
                    assert isinstance(part, Relational)
                    assert part.lhs == _c
                    rel_op, rhs = part.rel_op, part.rhs
                    if _c.is_Integer or _c.assumptions0["integer"]:
                        if rel_op == "<":
                            rhs = rhs - 1
                            rel_op = "<="
                        elif rel_op == ">":
                            rhs = rhs + 1
                            rel_op = ">="
                    assert rel_op in rhs_by_c, "x: %r, _c: %r, and expr: %r, part %r" % (
                        x, _c, and_expr, part)
                    other_rhs = rhs_by_c[rel_op]
                    assert isinstance(other_rhs, list)
                    need_to_add = True
                    for rhs_ in other_rhs:
                        cmp = Relational.ValidRelationOperator[rel_op](rhs,
                                                                       rhs_)
                        if simplify_and(
                                sympy.And(sympy.Not(cmp),
                                          extra_conditions)) == sympy.sympify(
                                              False):  # checks True...
                            other_rhs.remove(rhs_)
                            break
                        elif simplify_and(sympy.And(
                                cmp,
                                extra_conditions)) == sympy.sympify(False):
                            need_to_add = False
                            break
                        # else:
                        #  raise NotImplementedError("cannot compare %r in %r; extra cond %r" % (cmp, and_expr, extra_conditions))
                    if need_to_add:
                        other_rhs.append(rhs)
                if rhs_by_c[">="] and rhs_by_c["<="]:
                    all_false = False
                    for lhs in rhs_by_c[">="]:
                        for rhs in rhs_by_c["<="]:
                            if sympy.Lt(lhs, rhs) == sympy.sympify(False):
                                all_false = True
                            if sympy.Eq(lhs, rhs) == sympy.sympify(True):
                                rhs_by_c["=="].append(lhs)
                    if all_false:
                        x = x.replace(and_expr, False)
                        continue
                if rhs_by_c["=="]:
                    all_false = False
                    while len(rhs_by_c["=="]) >= 2:
                        lhs, rhs = rhs_by_c["=="][:2]
                        if sympy.Eq(lhs, rhs) == sympy.sympify(False):
                            all_false = True
                            break
                        elif sympy.Eq(lhs, rhs) == sympy.sympify(True):
                            rhs_by_c["=="].pop(1)
                        else:
                            raise NotImplementedError(
                                "cannot cmp %r == %r. rhs_by_c %r" %
                                (lhs, rhs, rhs_by_c))
                    if all_false:
                        x = x.replace(and_expr, False)
                        continue
                    new_parts = [sympy.Eq(_c, rhs_by_c["=="][0])]
                    for op in rel_ops:
                        for part in rhs_by_c[op]:
                            new_parts.append(
                                Relational.ValidRelationOperator[op](
                                    rhs_by_c["=="][0], part).simplify())
                else:  # no "=="
                    new_parts = []
                    for op in rel_ops:
                        for part in rhs_by_c[op]:
                            new_parts.append(
                                Relational.ValidRelationOperator[op](_c, part))
                    assert new_parts
                and_expr_ = sympy.And(*new_parts)
                # print(and_expr, "--->", and_expr_)
                x = x.replace(and_expr, and_expr_)
                and_expr = and_expr_

            # Probably all the remaining hard-coded rules are not needed anymore with the more generic code above...
            if sympy.Eq(_c, 2 * n) in and_expr.args:
                if (_c - 2 * n <= -1) in and_expr.args:
                    x = x.replace(and_expr, False)
                    continue
                if sympy.Eq(_c - 2 * n, -1) in and_expr.args:
                    x = x.replace(and_expr, False)
                    continue
                if (_c - n <= -1) in and_expr.args:
                    x = x.replace(and_expr, False)
                    continue
            if (_c >= n) in and_expr.args and (_c - n <= -1) in and_expr.args:
                x = x.replace(and_expr, False)
                continue
            if sympy.Eq(_c - 2 * n, -1) in and_expr.args:  # assume n>=1
                if (_c >= n) in and_expr.args:
                    x = x.replace(
                        and_expr,
                        sympy.And(
                            *
                            [arg for arg in and_expr.args
                             if arg != (_c >= n)]))
                    apply_rules = True
                    break
                if (_c - n >= -1) in and_expr.args:
                    x = x.replace(
                        and_expr,
                        sympy.And(*[
                            arg for arg in and_expr.args
                            if arg != (_c - n >= -1)
                        ]))
                    apply_rules = True
                    break
            if (_c >= n) in and_expr.args:
                if (_c - n >= -1) in and_expr.args:
                    x = x.replace(
                        and_expr,
                        sympy.And(*[
                            arg for arg in and_expr.args
                            if arg != (_c - n >= -1)
                        ]))
                    apply_rules = True
                    break
            if (_c - n >= -1) in and_expr.args and (_c - n <=
                                                    -1) in and_expr.args:
                args = list(and_expr.args)
                args.remove((_c - n >= -1))
                args.remove((_c - n <= -1))
                args.append(sympy.Eq(_c - n, -1))
                if (_c - 2 * n <= -1) in args:
                    args.remove((_c - 2 * n <= -1))
                x = x.replace(and_expr, sympy.And(*args))
                apply_rules = True
                break
    return x
Exemple #12
0
        return bool(self.shape_env.evaluate_expr(self.expr))


# Methods that have a `__foo__` as well as `__rfoo__`
reflectable_magic_methods = {
    'add': lambda a, b: a + b,
    'sub': lambda a, b: a - b,
    'mul': lambda a, b: a * b,
    'mod': lambda a, b: a % b,
}

magic_methods = {
    **reflectable_magic_methods,
    'eq': lambda a, b: sympy.Eq(a, b),
    'gt': lambda a, b: sympy.Gt(a, b),
    'lt': lambda a, b: sympy.Lt(a, b),
    'le': lambda a, b: sympy.Le(a, b),
    'ge': lambda a, b: sympy.Ge(a, b),
}

for method, _func in magic_methods.items():
    method_name = f'{method}'

    def _create_magic_impl(func):
        def magic_impl(self, other):
            if isinstance(other, PySymInt):
                other = other.expr
            return PySymInt(func(self.expr, other), self.shape_env)

        return magic_impl
Exemple #13
0
 def gen_lessthan(self, ident, val):
     return sym.Lt(val.exp_a, val.exp_b)
Exemple #14
0
def _make_comparison_question(context, left, right):
    """Makes a question for comparing two values."""
    if random.choice([False, True]) and sympy.Ne(left.value, right.value):
        # Do question of form: "Which is bigger: a or b?".
        if random.choice([False, True]):
            answer = (left.handle
                      if sympy.Gt(left.value, right.value) else right.handle)
            template = random.choice([
                'Что больше: {left} или {right}?',
                'Какое из чисел больше: {left} или {right}?',
            ])
        else:
            answer = (left.handle
                      if sympy.Lt(left.value, right.value) else right.handle)
            template = random.choice([
                'Что меньше: {left} или {right}?',
                'Какое число меньше: {left} или {right}?'
            ])
        return example.Problem(question=example.question(context,
                                                         template,
                                                         left=left,
                                                         right=right),
                               answer=answer)

    comparisons = {
        '<': sympy.Lt,
        '<=': sympy.Le,
        '>': sympy.Gt,
        '>=': sympy.Ge,
        '=': sympy.Eq,
        '!=': sympy.Ne,
    }

    templates = {
        '<': [
            'Правда ли, что {left} ' + ops.LT_SYMBOL + ' {right}?',
            '{left} меньше, чем {right}?',
            'Число {left} меньше числа {right}?',
        ],
        '<=': [
            'Правда ли, что {left} ' + ops.LE_SYMBOL + ' {right}?',
            'Правда ли, что {left} меньше или равно {right}?',
            'Число {left} не больше {right}?',
            'Число {left} не превосходит {right}?',
        ],
        '>': [
            'Правда ли, что {left} ' + ops.GT_SYMBOL + ' {right}?',
            '{left} больше, чем {right}?',
            'Число {left} больше числа {right}?',
        ],
        '>=': [
            'Правда ли, что {left} ' + ops.GE_SYMBOL + ' {right}?',
            'Правда ли, что {left} больше или равно {right}?',
            'Число {left} не меньше {right}?',
        ],
        '=': [
            'Правда ли, что {left} ' + ops.EQ_SYMBOL + ' {right}?',
            'Равны ли {left} и {right}?',
            'Число {left} равно числу {right}?',
            'Одинаковы ли {left} и {right}?',
        ],
        '!=': [
            'Правда ли, что {left} ' + ops.NE_SYMBOL + ' {right}?',
            'Число {left} не равно {right}?',
            'Числа {left} и {right} не равны?',
            'Значения числа {left} и числа {right} отличаются?',
            '{left} и {right} не равны друг другу?',
        ],
    }

    comparison = random.choice(list(comparisons.keys()))
    template = random.choice(templates[comparison])
    question = example.question(context, template, left=left, right=right)
    answer = comparisons[comparison](left.value, right.value)

    return example.Problem(question=question, answer=answer)
 def _ex_less(self, e):
     return sp.Lt(self.ex(e[0]), self.ex(e[1]))
Exemple #16
0
  sympy.tan(S('X')) * sympy.exp(S('Y'))),
 ('$PRED K_ = ATAN(1) - ASIN(X)/ACOS(X)', S('K_'),
  sympy.atan(1) - sympy.asin(S('X')) / sympy.acos(S('X'))),
 ('$PRED CL = INT(-2.2)', S('CL'), -2),
 ('$PRED CL = INT(0.2)', S('CL'), 0),
 ('$PRED CL = MOD(1, 2)', S('CL'), sympy.Mod(1, 2)),
 ('$PRED CL = GAMLN(2 + X)   ;COMMENT', S('CL'),
  sympy.loggamma(S('X') + 2)),
 ('$PRED IF (X.EQ.2) CL=23', S('CL'),
  sympy.Piecewise((23, sympy.Eq(S('X'), 2)))),
 ('$PRED IF (X.NE.1.5) CL=THETA(1)', S('CL'),
  sympy.Piecewise((S('THETA(1)'), sympy.Ne(S('X'), 1.5)))),
 ('$PRED IF (X.EQ.2+1) CL=23', S('CL'),
  sympy.Piecewise((23, sympy.Eq(S('X'), 3)))),
 ('$PRED IF (X < ETA(1)) CL=23', S('CL'),
  sympy.Piecewise((23, sympy.Lt(S('X'), S('ETA(1)'))))),
 ('$PK IF(AMT.GT.0) BTIME=TIME', S('BTIME'),
  sympy.Piecewise((S('TIME'), sympy.Gt(S('AMT'), 0)))),
 ('$PRED IF (X.EQ.2.AND.Y.EQ.3) CL=23', S('CL'),
  sympy.Piecewise(
      (23, sympy.And(sympy.Eq(S('X'), 2), sympy.Eq(S('Y'), 3))))),
 ('$PRED IF (X.EQ.2.OR.Y.EQ.3) CL=23', S('CL'),
  sympy.Piecewise(
      (23, sympy.Or(sympy.Eq(S('X'), 2), sympy.Eq(S('Y'), 3))))),
 ('$PRED IF (.NOT.X.EQ.2) CL=25', S('CL'),
  sympy.Piecewise((25, sympy.Not(sympy.Eq(S('X'), 2))))),
 ('$PRED IF (Q.EQ.(R+C)/D) L=0', S('L'),
  sympy.Piecewise(
      (0, sympy.Eq(S('Q'), sympy.Mul(sympy.Add(S('R'), S('C')),
                                     1 / S('D')))))),
 ('$PRED IF (Q.EQ.R+C/D) L=0', S('L'),
Exemple #17
0
def _make_comparison_question(context, left, right):
    """Makes a question for comparing two values."""
    if random.choice([False, True]) and sympy.Ne(left.value, right.value):
        # Do question of form: "Which is bigger: a or b?".
        if random.choice([False, True]):
            answer = (left.handle
                      if sympy.Gt(left.value, right.value) else right.handle)
            template = random.choice([
                'Mana yang lebih besar: {left} atau {right}?',
            ])
        else:
            answer = (left.handle
                      if sympy.Lt(left.value, right.value) else right.handle)
            template = random.choice([
                'Mana yang lebih kecil: {left} atau {right}?',
            ])
        return example.Problem(question=example.question(context,
                                                         template,
                                                         left=left,
                                                         right=right),
                               answer=answer)

    comparisons = {
        '<': sympy.Lt,
        '<=': sympy.Le,
        '>': sympy.Gt,
        '>=': sympy.Ge,
        '=': sympy.Eq,
        '!=': sympy.Ne,
    }

    templates = {
        '<': [
            'Apakah {left} ' + ops.LT_SYMBOL + ' {right}?',
            'Apakah {left} kurang dari {right}?',
            'Apakah {left} lebih kecil dari {right}?',
        ],
        '<=': [
            'Apakah {left} ' + ops.LE_SYMBOL + ' {right}?',
            'Apakah {left} kurang dari atau sama dengan {right}?',
            'Apakah {left} lebih banyak {right}?',
            'Apakah {left} paling tidak sama dengan {right}?',
        ],
        '>': [
            'Apakah {left} ' + ops.GT_SYMBOL + ' {right}?',
            'Apakah {left} lebih dari {right}?',
            'Apakah {left} lebih besar dari {right}?',
        ],
        '>=': [
            'Apakah {left} ' + ops.GE_SYMBOL + ' {right}?',
            'Apakah {left} lebih dari atau sama dengan {right}?',
            'Apakah {left} setidaknya {right}?',
            'Apakah {left} setidaknya sama besar dengan {right}?',
        ],
        '=': [
            'Apakah {left} ' + ops.EQ_SYMBOL + ' {right}?',
            'Apakah {left} dan {right} sama?',
            'Apakah {left} sama dengan {right}?',
            'Apakah {left} dan {right} memiliki nilai yang sama?',
        ],
        '!=': [
            'Apakah {left} ' + ops.NE_SYMBOL + ' {right}?',
            'Apakah {left} tidak sama dengan {right}?',
            'Apakah {left} dan {right} berbeda?',
            'Apakah {left} dan {right} tidak sama?',
            'Apakah {left} dan {right} memiliki nilai yang berbeda?',
        ],
    }

    comparison = random.choice(list(comparisons.keys()))
    template = random.choice(templates[comparison])
    question = example.question(context, template, left=left, right=right)
    answer = comparisons[comparison](left.value, right.value)

    return example.Problem(question=question, answer=answer)
    def test_reader_writer(self):
        # Test using the proper reader/writer
        try:
            import sympy as sp
        except ImportError:
            print('Sympy not found, skipping test.')
            return

        # Create writer and reader
        w = mypy.SymPyExpressionWriter()
        r = mypy.SymPyExpressionReader(self._model)

        # Name
        a = self._a
        ca = sp.Symbol('c.a')
        self.assertEqual(w.ex(a), ca)
        self.assertEqual(r.ex(ca), a)

        # Number with unit
        b = myokit.Number('12', 'pF')
        cb = sp.Float(12)
        self.assertEqual(w.ex(b), cb)
        # Note: Units are lost in sympy im/ex-port!
        #self.assertEqual(r.ex(cb), b)

        # Number without unit
        b = myokit.Number('12')
        cb = sp.Float(12)
        self.assertEqual(w.ex(b), cb)
        self.assertEqual(r.ex(cb), b)

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(w.ex(x), cb)
        # Note: Sympy doesn't seem to have a prefix plus
        self.assertEqual(r.ex(cb), b)

        # Prefix minus
        # Note: SymPy treats -x as Mul(NegativeOne, x)
        # But for numbers just returns a number with a negative value
        x = myokit.PrefixMinus(b)
        self.assertEqual(w.ex(x), -cb)
        self.assertEqual(float(r.ex(-cb)), float(x))

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(w.ex(x), ca + cb)
        # Note: SymPy likes to re-order the operands...
        self.assertEqual(float(r.ex(ca + cb)), float(x))

        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(w.ex(x), ca - cb)
        self.assertEqual(float(r.ex(ca - cb)), float(x))

        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(w.ex(x), ca * cb)
        self.assertEqual(float(r.ex(ca * cb)), float(x))

        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(w.ex(x), ca / cb)
        self.assertEqual(float(r.ex(ca / cb)), float(x))

        # Quotient
        x = myokit.Quotient(a, b)
        self.assertEqual(w.ex(x), ca // cb)
        self.assertEqual(float(r.ex(ca // cb)), float(x))

        # Remainder
        x = myokit.Remainder(a, b)
        self.assertEqual(w.ex(x), ca % cb)
        self.assertEqual(float(r.ex(ca % cb)), float(x))

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(w.ex(x), ca**cb)
        self.assertEqual(float(r.ex(ca**cb)), float(x))

        # Sqrt
        x = myokit.Sqrt(a)
        cx = sp.sqrt(ca)
        self.assertEqual(w.ex(x), cx)
        # Note: SymPy converts sqrt to power
        self.assertEqual(float(r.ex(cx)), float(x))

        # Exp
        x = myokit.Exp(a)
        cx = sp.exp(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Log(a)
        x = myokit.Log(a)
        cx = sp.log(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Log(a, b)
        x = myokit.Log(a, b)
        cx = sp.log(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(float(r.ex(cx)), float(x))

        # Log10
        x = myokit.Log10(b)
        cx = sp.log(cb, 10)
        self.assertEqual(w.ex(x), cx)
        self.assertAlmostEqual(float(r.ex(cx)), float(x))

        # Sin
        x = myokit.Sin(a)
        cx = sp.sin(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Cos
        x = myokit.Cos(a)
        cx = sp.cos(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Tan
        x = myokit.Tan(a)
        cx = sp.tan(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # ASin
        x = myokit.ASin(a)
        cx = sp.asin(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # ACos
        x = myokit.ACos(a)
        cx = sp.acos(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # ATan
        x = myokit.ATan(a)
        cx = sp.atan(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Floor
        x = myokit.Floor(a)
        cx = sp.floor(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Ceil
        x = myokit.Ceil(a)
        cx = sp.ceiling(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Abs
        x = myokit.Abs(a)
        cx = sp.Abs(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Equal
        x = myokit.Equal(a, b)
        cx = sp.Eq(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # NotEqual
        x = myokit.NotEqual(a, b)
        cx = sp.Ne(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # More
        x = myokit.More(a, b)
        cx = sp.Gt(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Less
        x = myokit.Less(a, b)
        cx = sp.Lt(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # MoreEqual
        x = myokit.MoreEqual(a, b)
        cx = sp.Ge(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # LessEqual
        x = myokit.LessEqual(a, b)
        cx = sp.Le(ca, cb)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Not
        x = myokit.Not(a)
        cx = sp.Not(ca)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # And
        cond1 = myokit.More(a, b)
        cond2 = myokit.Less(a, b)
        c1 = sp.Gt(ca, cb)
        c2 = sp.Lt(ca, cb)

        x = myokit.And(cond1, cond2)
        cx = sp.And(c1, c2)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Or
        x = myokit.Or(cond1, cond2)
        cx = sp.Or(c1, c2)
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # If
        # Note: sympy only does piecewise, not if
        x = myokit.If(cond1, a, b)
        cx = sp.Piecewise((ca, c1), (cb, True))
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x.piecewise())

        # Piecewise
        c = myokit.Number(1)
        cc = sp.Float(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        cx = sp.Piecewise((ca, c1), (cb, c2), (cc, True))
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Myokit piecewise's (like CellML's) always have a final True
        # condition (i.e. an 'else'). SymPy doesn't require this, so test if
        # we can import this --> It will add an "else 0"
        x = myokit.Piecewise(cond1, a, myokit.Number(0))
        cx = sp.Piecewise((ca, c1))
        self.assertEqual(r.ex(cx), x)

        # SymPy function without Myokit equivalent --> Should raise exception
        cu = sp.principal_branch(cx, cc)
        self.assertRaisesRegex(ValueError, 'Unsupported type', r.ex, cu)

        # Derivative
        m = self._model.clone()
        avar = m.get('c.a')
        r = mypy.SymPyExpressionReader(self._model)
        avar.promote(4)
        x = myokit.Derivative(self._a)
        cx = sp.symbols('dot(c.a)')
        self.assertEqual(w.ex(x), cx)
        self.assertEqual(r.ex(cx), x)

        # Equation
        e = myokit.Equation(a, b)
        ce = sp.Eq(ca, cb)
        self.assertEqual(w.eq(e), ce)
        # There's no backwards equivalent for this!
        # The ereader can handle it, but it becomes and Equals expression.

        # Test sympy division
        del (m, avar, x, cx, e, ce)
        a = self._model.get('c.a')
        b = self._model.get('c').add_variable('bbb')
        b.set_rhs('1 / a')
        e = b.rhs()
        ce = w.ex(b.rhs())
        e = r.ex(ce)
        self.assertEqual(
            e,
            myokit.Multiply(myokit.Number(1),
                            myokit.Power(myokit.Name(a), myokit.Number(-1))))

        # Test sympy negative numbers
        a = self._model.get('c.a')
        e1 = myokit.PrefixMinus(myokit.Name(a))
        ce = w.ex(e1)
        e2 = r.ex(ce)
        self.assertEqual(e1, e2)