Exemple #1
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 #2
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 #3
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 #4
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 #5
0
 def gen_greaterthan(self, ident, val):
     return sym.Gt(val.exp_a, val.exp_b)
Exemple #6
0
    def __bool__(self):
        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
 def _ex_more(self, e):
     return sp.Gt(self.ex(e[0]), self.ex(e[1]))
Exemple #8
0
  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'),
  sympy.Piecewise((0, sympy.Eq(S('Q'),
                               S('R') + S('C') / S('D'))))),
Exemple #9
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)
Exemple #11
0
    def xml_to_sympy_expr(self, xml_node):
        if isTag(xml_node, '/MathML}cn'):
            return float(xml_node.text)
        elif isTag(xml_node, '/MathML}ci'):
            if xml_node.text not in self.symbol_table:
                self.symbol_table[xml_node.text] = sp.Symbol(xml_node.text)
                self.extra_assignments[self.symbol_table[xml_node.text]] = None
            return self.symbol_table[xml_node.text]

        elif not isTag(xml_node, '/MathML}apply'):
            raise ValueError("Do not know hot to parse node %s" % xml_node)

        try:
            func, *arg_children = filterTags(xml_node.getchildren())
        except ValueError:
            raise
        processed_args = []
        for child in arg_children:
            processed_args.append(self.xml_to_sympy_expr(child))

        if isTag(func, '/MathML}plus'):
            out_expr =  sp.Add(*processed_args)
        elif isTag(func, '/MathML}times'):
            out_expr =  sp.Mul(*processed_args)
        elif isTag(func, '/MathML}power'):
            if len(processed_args) != 2:
                raise ValueError("Power is a binary operation!")
            out_expr =  sp.Pow(*processed_args)
        elif isTag(func, '/MathML}divide'):
            if len(processed_args) != 2:
                raise ValueError("Division is a binary operation!")
            out_expr =  sp.Mul(processed_args[0], sp.Pow(processed_args[1], -1))
        elif isTag(func, '/MathML}minus'):
            if (len(processed_args) > 2) or (len(processed_args) == 0):
                raise ValueError("Subtraction is a unitary or binary operation!")
            elif len(processed_args) == 2:
                out_expr =  sp.Add(processed_args[0], sp.Mul(processed_args[1], -1))
            elif len(processed_args) == 1:
                out_expr =  sp.Mul(processed_args[0], -1)
        elif isTag(func, '/MathML}abs'):
            if len(processed_args) != 1:
                raise ValueError("Absolute value is a unitary operation!")
            out_expr = sp.Abs(processed_args[0])

        elif isTag(func, '/MathML}cos'):
            if len(processed_args) != 1:
                raise ValueError("cos is a unitary operation!")
            out_expr = sp.cos(processed_args[0])
        elif isTag(func, '/MathML}sin'):
            if len(processed_args) != 1:
                raise ValueError("sin is a unitary operation!")
            out_expr = sp.sin(processed_args[0])
        elif isTag(func, '/MathML}csymbol'):

            if func.text == 'atan2':
                if len(processed_args) != 2:
                    raise ValueError("atan2 is a binary operation!")
                out_expr =  sp.atan2(*processed_args)
            else:
                raise ValueError("Unknown csymbol %s" % func.text)

        elif isTag(func, '/MathML}piecewise'):
            *pieces, otherwise = func.getchildren()
            otherwise_children = filterTags(otherwise.getchildren())
            conditions = []
            values = []
            if len(otherwise_children) != 1:
                raise ValueError("Too many `otherwise` children")
            for piece in filterTags(pieces):
                value_child, condition_child = filterTags(piece.getchildren())
                values.append(self.xml_to_sympy_expr(value_child))
                conditions.append(self.xml_to_sympy_expr(condition_child))

            values.append(self.xml_to_sympy_expr(otherwise_children[0]))
            conditions.append(True)
            out_expr = sp.Piecewise(*[(value, condition) for value, condition in zip(values, conditions)])
        elif isTag(func, '/MathML}lt'):
            if len(processed_args) != 2:
                raise ValueError("Less than is a binary operation!")
            out_expr = sp.Le(*processed_args)
        elif isTag(func, '/MathML}gt'):
            if len(processed_args) != 2:
                raise ValueError("Greater than is a binary operation!")
            out_expr = sp.Gt(*processed_args)
        elif isTag(func, '/MathML}leq'):
            if len(processed_args) != 2:
                raise ValueError("Less than equal to is a binary operation!")
            out_expr = sp.Le(*processed_args)
        elif isTag(func, '/MathML}geq'):
            if len(processed_args) != 2:
                raise ValueError("Greater than equal to is a binary operation!")
            out_expr = sp.Ge(*processed_args)

        else:
            raise ValueError("Unknown func tag, %s" % func.tag)

        if out_expr is None:
            raise ValueError("Calculated None")
        else:
            return out_expr
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 #13
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)
Exemple #14
0
def _symcheck():
    # import sympy as sym
    # # Create the index for our indexable sequence objects
    # i = sym.symbols('i', cls=sym.Idx)

    # measured = list(map(sym.IndexedBase, ['A_m', 'B_m', 'C_m']))
    # smoothed = list(map(sym.IndexedBase, ['A_s', 'B_s', 'C_s']))

    # for S in smoothed:
    #     S[0] = 0

    # for M, S in zip(measured, smoothed):
    #     M[i]
    #     pass

    # for r in raw_values:
    #     z = r[i]
    #     .is_nonnegative = True
    #     r.is_real = True

    ###########
    # I'm not sure how to used index objects correctly, so lets hack it
    import sympy as sym
    kw = dict(is_nonnegative=True, is_real=True)

    measured = {'A_m': [], 'B_m': [], 'C_m': [], 'T_m': []}
    smoothed = {'A_s': [], 'B_s': [], 'C_s': [], 'T_s': []}

    for i in range(3):
        _syms = sym.symbols('A_m{i}, B_m{i}, C_m{i}, T_m{i}'.format(i=i), **kw)
        for _sym in _syms:
            prefix = _sym.name[0:-1]
            measured[prefix].append(_sym)

        _syms = sym.symbols('A_s{i}, B_s{i}, C_s{i}, T_s{i}'.format(i=i), **kw)
        for _sym in _syms:
            prefix = _sym.name[0:-1]
            smoothed[prefix].append(_sym)

    # alpha, beta = sym.symbols('α,  β', is_real=1, is_positive=True)
    # constraints.append(sym.Eq(beta, 1 - alpha))
    # constraints.append(sym.Le(alpha, 1))
    # constraints.append(sym.Ge(alpha, 0))

    constraints = []
    N = 2
    alpha = 0.6
    beta = 1 - 0.6

    for i in range(N):
        # Total measure constraints
        constr = sym.Eq(
            measured['T_m'][i],
            measured['A_m'][i] + measured['B_m'][i] + measured['C_m'][i])

        # EWMA constraints
        for s_key in smoothed.keys():
            m_key = s_key.replace('_s', '_m')
            S = smoothed[s_key]
            M = measured[m_key]
            if i == 0:
                constr = sym.Eq(S[i], M[i])
                constraints.append(constr)
            else:
                constr = sym.Eq(S[i], M[i] * alpha + beta * S[i - 1])
                constraints.append(constr)

        constr = sym.Eq(
            measured['T_m'][i],
            measured['A_m'][i] + measured['B_m'][i] + measured['C_m'][i])
        constraints.append(constr)

    from sympy.solvers.solveset import linear_eq_to_matrix
    from sympy.solvers.solveset import linsolve
    import itertools as it
    import ubelt as ub

    all_symbols = list(
        ub.flatten(it.chain(measured.values(), smoothed.values())))

    # WE WANT TO KNOW IF THIS IS POSSIBLE
    constraints.append(sym.Gt(measured['A_m'][-1], measured['T_m'][-1]), )

    A, b = linear_eq_to_matrix(constraints, all_symbols)
    linsolve((A, b))