def _remove_subtractions(exp): a,b = core.wilds('a b') vals = {} if exp.match(stdops.Sub(a,b), vals): return vals['a'] + (-vals['b']) else: return exp
def _get_factors(exp): rv = {} a, b = core.wilds('a b') vals = {} if exp.match(a * b, vals): tmp = _get_factors(vals['a']) for i in tmp: if i in rv: rv[i] += tmp[i] else: rv[i] = tmp[i] tmp = _get_factors(vals['b']) for i in tmp: if i in rv: rv[i] += tmp[i] else: rv[i] = tmp[i] elif exp.match(a**b, vals): rv = _get_factors(vals['a']) for k in rv: rv[k] = rv[k] * vals['b'] else: rv[exp] = 1 return rv
def _remove_subtractions(exp): a, b = core.wilds('a b') vals = {} if exp.match(stdops.Sub(a, b), vals): return vals['a'] + (-vals['b']) else: return exp
def _diff_known_function(expression, variable): vals = WildResults() g,h = wilds('g h') if expression[0] not in _known_functions: raise DifferentiationError("d/d%s %s" % (variable,expression)) if expression.match(g + h, vals): return diff(vals.g, variable) + diff(vals.h, variable) elif expression.match(g - h, vals): return diff(vals.g, variable) - diff(vals.h, variable) elif expression.match(variable ** g, vals): return vals.g * (variable ** (vals.g - 1)) elif expression.match(g * h, vals): return vals.g * diff(vals.h, variable) + vals.h * diff(vals.g, variable) elif expression.match(g / h, vals): return (diff(vals.g, variable) * vals.h - vals.g * diff(vals.h, variable)) / (vals.h ** 2) elif expression.match(Exp(variable)): return expression elif expression.match(Sin(variable)): return Sin(variable) elif expression.match(Cos(variable)): return -1 * Sin(variable) raise DifferentiationError("d/d%s %s" % (variable,expression))
def _get_factors(exp): rv = {} a,b = core.wilds('a b') vals = {} if exp.match(a * b, vals): tmp = _get_factors(vals['a']) for i in tmp: if i in rv: rv[i] += tmp[i] else: rv[i] = tmp[i] tmp = _get_factors(vals['b']) for i in tmp: if i in rv: rv[i] += tmp[i] else: rv[i] = tmp[i] elif exp.match(a ** b, vals): rv = _get_factors(vals['a']) for k in rv: rv[k] = rv[k] * vals['b'] else: rv[exp] = 1 return rv
def _(exp): a, b, c = core.wilds('a b c') vals = {} if exp.match(op1(op2(a, b), c), vals): return op2(op1(vals['c'], vals['a']), op1(vals['c'], vals['b'])) elif exp.match(op1(a, op2(b, c)), vals): return op2(op1(vals['a'], vals['b']), op1(vals['a'], vals['c'])) else: return exp
def _(exp): a,b,c = core.wilds('a b c') vals = {} if exp.match(op1(op2(a, b), c), vals): return op2(op1(vals['c'], vals['a']), op1(vals['c'], vals['b'])) elif exp.match(op1(a, op2(b, c)), vals): return op2(op1(vals['a'], vals['b']), op1(vals['a'], vals['c'])) else: return exp
def _fold_additions(exp): a, b, c = core.wilds('a b c') vals = {} if exp.match(a + a, vals): return vals['a'] * 2 elif exp.match(a + (a * b), vals) or exp.match(a + (b * a), vals): return (vals['b'] + 1) * vals['a'] else: return exp
def _simplify_known_values(exp): a,b,c = core.wilds('a b c') vals = {} if exp.match(a(b,c), vals) \ and 'numeric' in vals['a'].kargs \ and isinstance(vals['b'], core._KnownValue) \ and isinstance(vals['c'], core._KnownValue): cast = vals['a'].kargs['cast'] if 'cast' in vals['a'].kargs else (lambda x: x) nfn = getattr(operator, vals['a'].kargs['numeric']) return core.symbolic(nfn(cast(vals['b'].value()), cast(vals['c'].value()))) else: return exp
def _fold_additions(exp): a,b,c = core.wilds('a b c') vals = {} if exp.match(a + a, vals): return vals['a'] * 2 elif exp.match(a + (a * b), vals) or exp.match(a + (b * a), vals): return (vals['b'] + 1) * vals['a'] else: return exp
def _simplify_known_values(exp): a, b, c = core.wilds('a b c') vals = {} if exp.match(a(b,c), vals) \ and 'numeric' in vals['a'].kargs \ and isinstance(vals['b'], core._KnownValue) \ and isinstance(vals['c'], core._KnownValue): cast = vals['a'].kargs['cast'] if 'cast' in vals['a'].kargs else ( lambda x: x) nfn = getattr(operator, vals['a'].kargs['numeric']) return core.symbolic( nfn(cast(vals['b'].value()), cast(vals['c'].value()))) else: return exp
def _simplify_bitops(exp): a,b = core.wilds('a b') vals = core.WildResults() if exp.match(a ^ a): return core.symbolic(0) elif exp.match(a | a, vals): return vals.a elif exp.match(a & a, vals): return vals.a elif exp.match((a << b) >> b, vals) or exp.match((a >> b) << b, vals): return vals.a else: return exp
def _convert_to_pow(exp): a,b,c = core.wilds('a b c') if not exp.match(a(b,c)): return exp fs = _get_factors(exp) rv = 1 for k in fs: if fs[k] == 1: rv = rv * k else: rv = rv * (k ** fs[k]) return rv
def _convert_to_pow(exp): a, b, c = core.wilds('a b c') if not exp.match(a(b, c)): return exp fs = _get_factors(exp) rv = 1 for k in fs: if fs[k] == 1: rv = rv * k else: rv = rv * (k**fs[k]) return rv
def _simplify_bitops(exp): a, b = core.wilds('a b') vals = core.WildResults() if exp.match(a ^ a): return core.symbolic(0) elif exp.match(a | a, vals): return vals.a elif exp.match(a & a, vals): return vals.a elif exp.match((a << b) >> b, vals) or exp.match((a >> b) << b, vals): return vals.a else: return exp
def _strip_identities_pass(exp): a,b,c = core.wilds('a b c') vals = {} if exp.match(a(b, c)): kargs = exp[0].kargs lidentity = kargs['lidentity'] if 'lidentity' in kargs else kargs['identity'] if 'identity' in kargs else None ridentity = kargs['ridentity'] if 'ridentity' in kargs else kargs['identity'] if 'identity' in kargs else None if lidentity != None and exp.match(a(lidentity, b), vals): return vals['b'].walk(_strip_identities) elif ridentity != None and exp.match(a(b, ridentity), vals): return vals['b'].walk(_strip_identities) return exp
def _simplify_mul_div(exp): a, b, c = core.wilds('a b c') vals = core.WildResults() if exp.match(c * (b / c), vals) or exp.match((b / c) * c, vals): return vals.b if exp.match(a * (b / c), vals) or exp.match((b / c) * a, vals): return (vals.a * vals.b) / vals.c elif exp.match(a / b, vals) and isinstance(vals.b, core.Number): return vals.a * (1.0 / vals.b.value()) elif exp.match(a / b, vals) and factor.is_factor(vals.b, vals.a): return factor.get_coefficient(vals.a, vals.b) return exp
def _simplify_mul_div(exp): a,b,c = core.wilds('a b c') vals = core.WildResults() if exp.match(c * (b / c), vals) or exp.match((b / c) * c, vals): return vals.b if exp.match(a * (b / c), vals) or exp.match((b / c) * a, vals): return (vals.a * vals.b) / vals.c elif exp.match(a / b, vals) and isinstance(vals.b, core.Number): return vals.a * (1.0 / vals.b.value()) elif exp.match(a / b, vals) and factor.is_factor(vals.b, vals.a): return factor.get_coefficient(vals.a, vals.b) return exp
def _strip_identities_pass(exp): a, b, c = core.wilds('a b c') vals = {} if exp.match(a(b, c)): kargs = exp[0].kargs lidentity = kargs['lidentity'] if 'lidentity' in kargs else kargs[ 'identity'] if 'identity' in kargs else None ridentity = kargs['ridentity'] if 'ridentity' in kargs else kargs[ 'identity'] if 'identity' in kargs else None if lidentity != None and exp.match(a(lidentity, b), vals): return vals['b'].walk(_strip_identities) elif ridentity != None and exp.match(a(b, ridentity), vals): return vals['b'].walk(_strip_identities) return exp
def _diff_known_function(expression, variable): vals = WildResults() g,h = wilds('g h') if expression[0] not in _known_functions: raise DifferentiationError("d/d%s %s" % (variable,expression)) if expression.match(g + h, vals): return diff(vals.g, variable) + diff(vals.h, variable) elif expression.match(g - h, vals): return diff(vals.g, variable) - diff(vals.h, variable) elif expression.match(variable ** g, vals): return vals.g * (variable ** (vals.g - 1)) elif expression.match(g * h, vals): return vals.g * diff(vals.h, variable) + vals.h * diff(vals.g, variable) elif expression.match(g / h, vals): return (diff(vals.g, variable) * vals.h - vals.g * diff(vals.h, variable)) / (vals.h ** 2) elif expression.match(Exp(variable)): return expression elif expression.match(Sin(variable)): return Sin(variable) elif expression.match(Cos(variable)): return -1 * Sin(variable) elif expression.match(Sum(g, h), vals): if(variable(vals.g) in vals.h): return Sum(vals.g, diff(vals.h, variable(vals.g))) else: return Sum(vals.g, diff(vals.h, variable)) elif expression.match(Log(variable), vals): return 1.0 / variable raise DifferentiationError("d/d%s %s" % (variable,expression))
def diff(expression, variable): vals = WildResults() f,a,b = wilds('f a b') expression = expression.simplify() if variable not in expression: return symbolic(0) elif expression.match(variable): return symbolic(1) elif expression.match(f(a,b), vals) and vals.f in _known_functions: return _diff_known_function(expression, variable) elif expression.match(f(a), vals) and vals.f in _known_functions: return _diff_known_function(vals.f(vals.a), vals.a) * diff(vals.a, variable) raise DifferentiationError("d/d%s %s" % (variable,expression))