asmeurer wrote: > I see that the gods do not want me to get this in. Apparently the > files did not make it to the last message. I am just going to do what > I know works: below is the text copied and pasted from the 4 patches. > If it is easier, you can still pull from my github repo with the > commit hashes in the original thread. Or, you could download the > patch files and convert them from Western (Mac OS Roman) to UTF-8. > > Below are the 4 patches in the order that they should be applied. > They all go together, so please do not test until you have applied all > 4. > > Aaron Meurer > > On May 25, 5:43 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote: > >> Those files had the wrong character encoding. These files should have >> the correct encoding. >> >> Aaron Meurer >> >> On May 23, 10:13 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote: >> > I tried sending these already through git, but they didn't seem to >> > show up in the list. Sorry if these are duplicates. See this >> thread:http://groups.google.com/group/sympy/browse_thread/thread/4622653ca05 >> ... >> > >> > I have no idea how to make git reformat these as one patch, so I am >> > just going to send them as one. They do need to be applied in order, >> > but they have the date and time stamps on them. Also, you can pull >> > the commits from their hashes from my github repo (right?). The link >> > is here:http://github.com/asmeurer/sympy/tree/odes >> > The hashes are 0d5698640a17365c024c688748552795e4d5ad38 >> > 7c50da0e55a315d5a104ac1a31027cbe6094367e >> > 0925083952426237794d7b3c67675f9977318b58 >> > 4ccdcd071075af238e522df0a1ef2adf86a59134. Hopefully that works. >> > Sorry if this is more work. I hope the files work this time. >> > >> > 0001-Made-logcombine-more-robust.patch >> > 7KViewDownload >> > >> > 0001-Added-function-logcombine.patch >> > 10KViewDownload >> > >> > 0001-Added-Equality-support-in-logcombine.patch >> > 3KViewDownload >> > >> > 0001-Added-an-XFAIL-test.patch >> > 3KViewDownload >> > > > > >From 4ccdcd071075af238e522df0a1ef2adf86a59134 Mon Sep 17 00:00:00 2001 > From: Aaron Meurer <asmeu...@gmail.com> > Date: Wed, 20 May 2009 13:53:44 -0600 > Subject: [PATCH 1/1] Added function logcombine. > This function takes expressions like 2*log(x)-log(y) and turns them > into > log(x**2/y), assuming that the arguments of the log are positive and > the coefficients are real. This also adds several tests for the > function. > > --- > sympy/simplify/__init__.py | 3 +- > sympy/simplify/simplify.py | 97 +++++++++++++++++++++++++ > +++++++- > sympy/simplify/tests/test_simplify.py | 21 +++++++- > 3 files changed, 117 insertions(+), 4 deletions(-) > > diff --git a/sympy/simplify/__init__.py b/sympy/simplify/__init__.py > index fa4d035..c883cbf 100644 > --- a/sympy/simplify/__init__.py > +++ b/sympy/simplify/__init__.py > @@ -5,7 +5,8 @@ > the expression (x+x)**2 will be converted into 4*x**2 > """ > from simplify import collect, separate, together, radsimp, ratsimp, > fraction, \ > - simplify, trigsimp, powsimp, combsimp, hypersimp, hypersimilar, > nsimplify > + simplify, trigsimp, powsimp, combsimp, hypersimp, hypersimilar, > nsimplify, \ > + logcombine > > from rewrite import cancel, trim, apart > > diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py > index 59a1d56..44558f1 100644 > --- a/sympy/simplify/simplify.py > +++ b/sympy/simplify/simplify.py > @@ -1,12 +1,12 @@ > from sympy import SYMPY_DEBUG > > from sympy.core import Basic, S, C, Add, Mul, Pow, Rational, Integer, > \ > - Derivative, Wild, Symbol, sympify > + Derivative, Wild, Symbol, sympify, expand > > from sympy.core.numbers import igcd > > from sympy.utilities import make_list, all > -from sympy.functions import gamma, exp, sqrt > +from sympy.functions import gamma, exp, sqrt, log > > from sympy.simplify.cse_main import cse > > @@ -1155,4 +1155,97 @@ def nsimplify_real(x): > > return re + im*S.ImaginaryUnit > > +def logcombine(expr, assumePosReal=False): > + """ > + Takes logarithms and combines them using the following rules: > + > + - log(x)+log(y) == log(x*y) > + - a*log(x) == log(x**a) > + > + These identities are only valid if x and y are positive and if a > is real, so > + the function will not combine the terms unless the arguments have > the proper > + assumptions on them. Use logcombine(func, assumePosReal=True) to > + automatically assume that the arguments of logs are positive and > that > + coefficents are real. Note that this will not change any > assumptions > + already in place, so if the coefficient is imaginary or the > argument > + negative, combine will still not combine the equations. Change > the > + assumptions on the variables to make them combine. > + > + Examples: > + >>> from sympy import * > + >>> a,x,y,z = symbols('axyz') > + >>> logcombine(a*log(x)+log(y)-log(z)) > + -log(z) + a*log(x) + log(y) > + >>> logcombine(a*log(x)+log(y)-log(z), assumePosReal=True) > + log(y*x**a/z) > + >>> x,y,z = symbols('xyz', positive=True) > + >>> a = Symbol('a', real=True) > + >>> logcombine(a*log(x)+log(y)-log(z)) > + log(y*x**a/z) > + """ > + # Try to make (a+bi)*log(x) == a*log(x)+bi*log(x). This needs to > be a > + # seperate function call to avoid infinite recursion. > + return _logcombine(expand(expr), assumePosReal=assumePosReal) > + > +def _logcombine(expr, assumePosReal=False): > + > + def _getlogargs(expr): > + """ > + Returns the arguments of the logarithm in an expression. > + Example: > + _getlogargs(a*log(x*y) -> x*y > + """ > + if expr.is_Function and expr.func == log: > + return expr.args[0] > + else: > + for i in expr.args: > + if i.has(log): > + return _getlogargs(i) > + return None > + > + if type(expr) in (int, float) or expr.is_Number or > expr.is_Rational or \ > + expr.is_NumberSymbol: > + return expr > + if expr.is_Add: > + argslist = 1 > + notlogs = 0 > + coeflogs = 0 > + for i in expr.args: > + if i.is_Function and i.func == log: > + if (i.args[0].is_positive or (assumePosReal and not \ > + i.args[0].is_nonpositive)): > + argslist *= _logcombine(i.args[0], > assumePosReal=assumePosReal) > + else: > + notlogs += i > + elif i.has(log): > + largs = _getlogargs(i) > + if largs.is_positive and i.extract_multiplicatively > (log(largs)).\ > + is_real or (assumePosReal and not > largs.is_nonpositive and not \ > + i.extract_multiplicatively(log > (largs)).is_real==False): > + coeflogs += _logcombine(i, > assumePosReal=assumePosReal) > + else: > + notlogs += i > + else: > + notlogs += i > + alllogs = _logcombine(log(argslist)+coeflogs, > assumePosReal=assumePosReal) > + return notlogs + alllogs > + > + if expr.is_Mul: > + a = Wild('a', exclude=[log]) > + x = Wild('x') > + coef = expr.match(a*log(x)) > + if coef and (coef[a].is_real or expr.is_Number or > expr.is_NumberSymbol \ > + or type(coef[a]) in (int, float) or (assumePosReal and not \ > + coef[a].is_imaginary)): > + return log(coef[x]**coef[a]) > + else: > + return expr > + if expr.is_Function: > + return expr.func(_logcombine(expr.args[0], > assumePosReal=assumePosReal)) > + if expr.is_Pow: > + return _logcombine(expr.args[0], assumePosReal=assumePosReal) > **\ > + _logcombine(expr.args[1], assumePosReal=assumePosReal) > + else: > + return expr > + > > diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/ > tests/test_simplify.py > index d3dc547..c601f40 100644 > --- a/sympy/simplify/tests/test_simplify.py > +++ b/sympy/simplify/tests/test_simplify.py > @@ -1,7 +1,8 @@ > from sympy import Symbol, symbols, together, hypersimp, factorial, > binomial, \ > collect, Function, powsimp, separate, sin, exp, Rational, > fraction, \ > simplify, trigsimp, cos, tan, cot, log, ratsimp, Matrix, pi, > integrate, \ > - solve, nsimplify, GoldenRatio, sqrt, E, I, sympify, atan, > Derivative, S, diff > + solve, nsimplify, GoldenRatio, sqrt, E, I, sympify, atan, > Derivative, \ > + S, diff, logcombine > > from sympy.utilities.pytest import XFAIL > > @@ -363,3 +364,21 @@ def test_diff(): > assert simplify(2*f(x)*f(x).diff(x)-diff(f(x)**2,x)) == 0 > assert simplify(diff(1/f(x),x)+f(x).diff(x)/f(x)**2) == 0 > assert simplify(f(x).diff(x,y)-f(x).diff(y,x)) == 0 > + > +def test_logcombine(): > + x, y = symbols("xy") > + a = Symbol("a") > + z, w = symbols("zw", positive=True) > + b = Symbol("b", real=True) > + assert logcombine(log(x)+2*log(y)) == log(x) + 2*log(y) > + assert logcombine(log(x)+2*log(y), assumePosReal=True) == log > (x*y**2) > + assert logcombine(a*log(w)+log(z)) == a*log(w) + log(z) > + assert logcombine(b*log(z)+b*log(x)) == log(z**b) + b*log(x) > + assert logcombine(b*log(z)-log(w)) == log(z**b/w) > + assert logcombine(cos(-2*log(z)+b*log(w))) == cos(log(w**b/z**2)) > + assert logcombine(log(log(x)-log(y))-log(z), assumePosReal=True) > == log(log((x/y)**(1/z))) > + assert logcombine((2+I)*log(x), assumePosReal=True) == I*log(x) > +log(x**2) > + assert logcombine((x**2+log(x)-log(y))/(x*y), assumePosReal=True) > == log(x**(1/(x*y))*y**(-1/(x*y)))+x/y > + assert logcombine(log(x)*2*log(y)+log(z), assumePosReal=True) == > log(z*y**log(x**2)) > + > + > -- > 1.6.2 > > > >From 0925083952426237794d7b3c67675f9977318b58 Mon Sep 17 00:00:00 2001 > From: Aaron Meurer <asmeu...@gmail.com> > Date: Wed, 20 May 2009 23:32:33 -0600 > Subject: [PATCH 1/1] Added an XFAIL test. > This is similar to Issue 1274; match fails because 2/3 is used > instead of Rational(2,3). Also made the match variables dummy, which > is tested by the passing version of the XFAIL test. > > --- > sympy/simplify/simplify.py | 4 ++-- > sympy/simplify/tests/test_simplify.py | 11 ++++++++++- > 2 files changed, 12 insertions(+), 3 deletions(-) > > diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py > index f95184d..861d858 100644 > --- a/sympy/simplify/simplify.py > +++ b/sympy/simplify/simplify.py > @@ -1231,8 +1231,8 @@ def _getlogargs(expr): > return notlogs + alllogs > > if expr.is_Mul: > - a = Wild('a', exclude=[log]) > - x = Wild('x') > + a = Wild('a', exclude=[log], dummy=True) > + x = Wild('x', dummy=True) > coef = expr.match(a*log(x)) > if coef and (coef[a].is_real or expr.is_Number or > expr.is_NumberSymbol \ > or type(coef[a]) in (int, float) or (assumePosReal and not \ > diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/ > tests/test_simplify.py > index c601f40..ba6a73a 100644 > --- a/sympy/simplify/tests/test_simplify.py > +++ b/sympy/simplify/tests/test_simplify.py > @@ -365,7 +365,7 @@ def test_diff(): > assert simplify(diff(1/f(x),x)+f(x).diff(x)/f(x)**2) == 0 > assert simplify(f(x).diff(x,y)-f(x).diff(y,x)) == 0 > > -def test_logcombine(): > +def test_logcombine_1(): > x, y = symbols("xy") > a = Symbol("a") > z, w = symbols("zw", positive=True) > @@ -380,5 +380,14 @@ def test_logcombine(): > assert logcombine((2+I)*log(x), assumePosReal=True) == I*log(x) > +log(x**2) > assert logcombine((x**2+log(x)-log(y))/(x*y), assumePosReal=True) > == log(x**(1/(x*y))*y**(-1/(x*y)))+x/y > assert logcombine(log(x)*2*log(y)+log(z), assumePosReal=True) == > log(z*y**log(x**2)) > + assert logcombine((x*y+sqrt(x**4+y**4)+log(x)-log(y))/ > (pi*x**Rational(2,3)*y**Rational(3,2)), assumePosReal=True) == log(x** > (1/(pi*x**Rational(2,3)*y**Rational(3,2)))*y**(-1/(pi*x**Rational(2,3) > *y**Rational(3,2)))) + (x**4 + y**4)**Rational(1,2)/(pi*x**Rational > (2,3)*y**Rational(3,2)) + x**Rational(1,3)/(pi*y**Rational(1,2)) > + > + > +...@xfail > +def test_logcombine_2(): > + # The same as one of the tests above, but with Rational(a,b) > replaced with a/b. > + # This fails because of a bug in matches. See issue 1274. > + x, y = symbols("xy") > + assert logcombine((x*y+sqrt(x**4+y**4)+log(x)-log(y))/(pi*x**(2/3) > *y**(3/2)), assumePosReal=True) == log(x**(1/(pi*x**(2/3)*y**(3/2))) > *y**(-1/(pi*x**(2/3)*y**(3/2)))) + (x**4 + y**4)**(1/2)/(pi*x**(2/3) > *y**(3/2)) + x**(1/3)/(pi*y**(1/2)) > > > -- > 1.6.2 > > > > >From 7c50da0e55a315d5a104ac1a31027cbe6094367e Mon Sep 17 00:00:00 2001 > From: Aaron Meurer <asmeu...@gmail.com> > Date: Fri, 22 May 2009 23:41:13 -0600 > Subject: [PATCH 1/1] Added Equality support in logcombine. > > --- > sympy/simplify/simplify.py | 5 +++++ > sympy/simplify/tests/test_simplify.py | 3 ++- > 2 files changed, 7 insertions(+), 1 deletions(-) > > diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py > index b3526f8..2fa8a6f 100644 > --- a/sympy/simplify/simplify.py > +++ b/sympy/simplify/simplify.py > @@ -4,6 +4,7 @@ > Derivative, Wild, Symbol, sympify, expand > > from sympy.core.numbers import igcd > +from sympy.core.relational import Equality > > from sympy.utilities import make_list, all > from sympy.functions import gamma, exp, sqrt, log > @@ -1207,6 +1208,10 @@ def _getlogargs(expr): > if type(expr) in (int, float) or expr.is_Number or > expr.is_Rational or \ > expr.is_NumberSymbol: > return expr > + > + if isinstance(expr, Equality): > + return Equality(_logcombine(expr.lhs-expr.rhs, > assumePosReal=assumePosReal), Integer(0)) > + > if expr.is_Add: > argslist = 1 > notlogs = 0 > diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/ > tests/test_simplify.py > index ba6a73a..3f3d981 100644 > --- a/sympy/simplify/tests/test_simplify.py > +++ b/sympy/simplify/tests/test_simplify.py > @@ -2,7 +2,7 @@ > collect, Function, powsimp, separate, sin, exp, Rational, > fraction, \ > simplify, trigsimp, cos, tan, cot, log, ratsimp, Matrix, pi, > integrate, \ > solve, nsimplify, GoldenRatio, sqrt, E, I, sympify, atan, > Derivative, \ > - S, diff, logcombine > + S, diff, logcombine, Eq, Integer > > from sympy.utilities.pytest import XFAIL > > @@ -381,6 +381,7 @@ def test_logcombine_1(): > assert logcombine((x**2+log(x)-log(y))/(x*y), assumePosReal=True) > == log(x**(1/(x*y))*y**(-1/(x*y)))+x/y > assert logcombine(log(x)*2*log(y)+log(z), assumePosReal=True) == > log(z*y**log(x**2)) > assert logcombine((x*y+sqrt(x**4+y**4)+log(x)-log(y))/ > (pi*x**Rational(2,3)*y**Rational(3,2)), assumePosReal=True) == log(x** > (1/(pi*x**Rational(2,3)*y**Rational(3,2)))*y**(-1/(pi*x**Rational(2,3) > *y**Rational(3,2)))) + (x**4 + y**4)**Rational(1,2)/(pi*x**Rational > (2,3)*y**Rational(3,2)) + x**Rational(1,3)/(pi*y**Rational(1,2)) > + assert logcombine(Eq(log(x), -2*log(y)), assumePosReal=True) == Eq > (log(x*y**2), Integer(0)) > > > @XFAIL > -- > 1.6.2 > > > > >From 0d5698640a17365c024c688748552795e4d5ad38 Mon Sep 17 00:00:00 2001 > From: Aaron Meurer <asmeu...@gmail.com> > Date: Sat, 23 May 2009 16:34:43 -0600 > Subject: [PATCH] Made logcombine more robust, > in particular, with equalities and logs inside of functions (like acos > (-log(x))). Also added tests for everything that I fixed. > > --- > sympy/simplify/simplify.py | 33 +++++++++++++++++++++++++ > +------- > sympy/simplify/tests/test_simplify.py | 7 ++++++- > 2 files changed, 32 insertions(+), 8 deletions(-) > > diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py > index 2fa8a6f..9ae5ec3 100644 > --- a/sympy/simplify/simplify.py > +++ b/sympy/simplify/simplify.py > @@ -1210,7 +1210,16 @@ def _getlogargs(expr): > return expr > > if isinstance(expr, Equality): > - return Equality(_logcombine(expr.lhs-expr.rhs, > assumePosReal=assumePosReal), Integer(0)) > + retval = Equality(_logcombine(expr.lhs-expr.rhs, > assumePosReal=\ > + assumePosReal), Integer(0)) > + # If logcombine couldn't do much with the equality, try to > make it like > + # it was. Hopefully extract_additively won't become smart > enought to > + # take logs apart :) > + right = retval.lhs.extract_additively(expr.lhs) > + if right: > + return Equality(expr.lhs, logcombine(-right)) > + else: > + return retval > > if expr.is_Add: > argslist = 1 > @@ -1220,20 +1229,26 @@ def _getlogargs(expr): > if i.is_Function and i.func == log: > if (i.args[0].is_positive or (assumePosReal and not \ > i.args[0].is_nonpositive)): > - argslist *= _logcombine(i.args[0], > assumePosReal=assumePosReal) > + argslist *= _logcombine(i.args[0], assumePosReal= > \ > + assumePosReal) > else: > notlogs += i > - elif i.has(log): > + elif i.is_Mul and any(map(lambda t: getattr(t,'func', > False)==log,\ > + i.args)): > largs = _getlogargs(i) > if largs.is_positive and i.extract_multiplicatively > (log(largs)).\ > is_real or (assumePosReal and not > largs.is_nonpositive and not \ > - i.extract_multiplicatively(log > (largs)).is_real==False): > + getattr(i.extract_multiplicatively(log > (largs)),'is_real',\ > + False)==False): > coeflogs += _logcombine(i, > assumePosReal=assumePosReal) > else: > notlogs += i > + elif i.has(log): > + notlogs += _logcombine(i, > assumePosReal=assumePosReal) > else: > notlogs += i > - alllogs = _logcombine(log(argslist)+coeflogs, > assumePosReal=assumePosReal) > + alllogs = _logcombine(log(argslist)+coeflogs, assumePosReal=\ > + assumePosReal) > return notlogs + alllogs > > if expr.is_Mul: > @@ -1245,9 +1260,13 @@ def _getlogargs(expr): > coef[a].is_imaginary)): > return log(coef[x]**coef[a]) > else: > - return expr > + return _logcombine(expr.args[0], > assumePosReal=assumePosReal)*\ > + reduce(lambda x, y: _logcombine(x, > assumePosReal=assumePosReal)*\ > + _logcombine(y, assumePosReal=assumePosReal), expr.args > [1:], 1) > + > if expr.is_Function: > - return expr.func(_logcombine(expr.args[0], > assumePosReal=assumePosReal)) > + return apply(expr.func,map(lambda t: _logcombine(t, > assumePosReal=\ > + assumePosReal), expr.args)) > if expr.is_Pow: > return _logcombine(expr.args[0], assumePosReal=assumePosReal) > **\ > _logcombine(expr.args[1], assumePosReal=assumePosReal) > diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/ > tests/test_simplify.py > index 3f3d981..89891d9 100644 > --- a/sympy/simplify/tests/test_simplify.py > +++ b/sympy/simplify/tests/test_simplify.py > @@ -2,7 +2,7 @@ > collect, Function, powsimp, separate, sin, exp, Rational, > fraction, \ > simplify, trigsimp, cos, tan, cot, log, ratsimp, Matrix, pi, > integrate, \ > solve, nsimplify, GoldenRatio, sqrt, E, I, sympify, atan, > Derivative, \ > - S, diff, logcombine, Eq, Integer > + S, diff, logcombine, Eq, Integer, gamma, acos > > from sympy.utilities.pytest import XFAIL > > @@ -382,6 +382,11 @@ def test_logcombine_1(): > assert logcombine(log(x)*2*log(y)+log(z), assumePosReal=True) == > log(z*y**log(x**2)) > assert logcombine((x*y+sqrt(x**4+y**4)+log(x)-log(y))/ > (pi*x**Rational(2,3)*y**Rational(3,2)), assumePosReal=True) == log(x** > (1/(pi*x**Rational(2,3)*y**Rational(3,2)))*y**(-1/(pi*x**Rational(2,3) > *y**Rational(3,2)))) + (x**4 + y**4)**Rational(1,2)/(pi*x**Rational > (2,3)*y**Rational(3,2)) + x**Rational(1,3)/(pi*y**Rational(1,2)) > assert logcombine(Eq(log(x), -2*log(y)), assumePosReal=True) == Eq > (log(x*y**2), Integer(0)) > + assert logcombine(Eq(y, x*acos(-log(x/y))), assumePosReal=True) > == Eq(y, x*acos(log(y/x))) > + assert logcombine(gamma(-log(x/y))*acos(-log(x/y)), > assumePosReal=True) == acos(log(y/x))*gamma(log(y/x)) > + assert logcombine((2+3*I)*log(x), assumePosReal=True) == log > (x**2)+3*I*log(x) > + assert logcombine(Eq(y, -log(x)), assumePosReal=True) == Eq(y, log > (1/x)) > + > > > @XFAIL > -- > 1.6.2 > > > > > What are you using for an email program?
--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy-patches" group. To post to this group, send email to sympy-patches@googlegroups.com To unsubscribe from this group, send email to sympy-patches+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy-patches?hl=en -~----------~----~----~----~------~----~------~--~---