def test_logaddexp2_opt(): x, y = map(Symbol, 'x y'.split()) expr1 = log(2**x + 2**y) / log(2) opt1 = optimize(expr1, [logaddexp2_opt]) assert logaddexp2(x, y) - opt1 == 0 assert logaddexp2(y, x) - opt1 == 0 assert opt1.rewrite(log) == expr1
def test_numpy_special_math(): if not numpy: skip("numpy not installed") funcs = [expm1, log1p, exp2, log2, log10, hypot, logaddexp, logaddexp2] for func in funcs: if 2 in func.nargs: expr = func(x, y) args = (x, y) num_args = (0.3, 0.4) elif 1 in func.nargs: expr = func(x) args = (x, ) num_args = (0.3, ) else: raise NotImplementedError( "Need to handle other than unary & binary functions in test") f = lambdify(args, expr) result = f(*num_args) reference = expr.subs(dict(zip(args, num_args))).evalf() assert numpy.allclose(result, float(reference)) lae2 = lambdify((x, y), logaddexp2(log2(x), log2(y))) assert abs(2.0**lae2(1e-50, 2.5e-50) - 3.5e-50) < 1e-62 # from NumPy's docstring
def test_logaddexp2(): lae2_xy = logaddexp2(x, y) ref2_xy = log(2**x + 2**y) / log(2) for wrt, deriv_order in product([x, y, z], range(0, 3)): assert (lae2_xy.diff(wrt, deriv_order) - ref2_xy.diff(wrt, deriv_order)).rewrite(log).simplify() == 0 def lb(x): return log(x) / log(2) two_thirds = S.One * 2 / 3 four_thirds = 2 * two_thirds lbTwoThirds = lb(two_thirds) lbFourThirds = lb(four_thirds) lae2_sum_to_2 = logaddexp2(lbTwoThirds, lbFourThirds) assert lae2_sum_to_2.rewrite(log) == 1 assert lae2_sum_to_2.simplify() == 1 assert logaddexp2(x, y).simplify() == logaddexp2( x, y) # cannot simplify with x, y
# Optimization procedures for turning A**(-1) * x into MatrixSolve(A, x) def _matinv_predicate(expr): # TODO: We should be able to support more than 2 elements if expr.is_MatMul and len(expr.args) == 2: left, right = expr.args if left.is_Inverse and right.shape[1] == 1: inv_arg = left.arg if isinstance(inv_arg, MatrixSymbol): return bool(ask(Q.fullrank(left.arg))) return False def _matinv_transform(expr): left, right = expr.args inv_arg = left.arg return MatrixSolve(inv_arg, right) matinv_opt = ReplaceOptim(_matinv_predicate, _matinv_transform) logaddexp_opt = ReplaceOptim(log(exp(_v)+exp(_w)), logaddexp(_v, _w)) logaddexp2_opt = ReplaceOptim(log(Pow(2, _v)+Pow(2, _w)), logaddexp2(_v, _w)*log(2)) # Collections of optimizations: optims_c99 = (expm1_opt, log1p_opt, exp2_opt, log2_opt, log2const_opt) optims_numpy = optims_c99 + (logaddexp_opt, logaddexp2_opt,) + sinc_opts optims_scipy = (cosm1_opt,)
left, right = expr.args if left.is_Inverse and right.shape[1] == 1: inv_arg = left.arg if isinstance(inv_arg, MatrixSymbol): return bool(ask(Q.fullrank(left.arg))) return False def _matinv_transform(expr): left, right = expr.args inv_arg = left.arg return MatrixSolve(inv_arg, right) matinv_opt = ReplaceOptim(_matinv_predicate, _matinv_transform) logaddexp_opt = ReplaceOptim(log(exp(_v) + exp(_w)), logaddexp(_v, _w)) logaddexp2_opt = ReplaceOptim(log(Pow(2, _v) + Pow(2, _w)), logaddexp2(_v, _w) * log(2)) # Collections of optimizations: optims_c99 = (expm1_opt, log1p_opt, exp2_opt, log2_opt, log2const_opt) optims_numpy = optims_c99 + ( logaddexp_opt, logaddexp2_opt, ) + sinc_opts optims_scipy = (cosm1_opt, )
def test_numpy_logaddexp(): lae = logaddexp(a, b) assert NumPyPrinter().doprint(lae) == 'numpy.logaddexp(a, b)' lae2 = logaddexp2(a, b) assert NumPyPrinter().doprint(lae2) == 'numpy.logaddexp2(a, b)'