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)
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', }
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
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()
def gen_greaterthan(self, ident, val): return sym.Gt(val.exp_a, val.exp_b)
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]))
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'))))),
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)
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)
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 _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))