There is a version of Albert Rich's project that uses if-then-else rather than a rule set.
Writing a pattern matcher that mimicks Mathematica's pattern matcher would be irrelevant if you used that alternative. On the other hand, mimicking Mathematica might have other uses. There are at least 2 in the open source; one in Lisp, which I wrote, and another in the Mathics project, written in python (!) RJF On Friday, March 10, 2017 at 1:16:19 PM UTC-8, Aaron Meurer wrote: > > I recommend using the method I outlined above to figure out which > algorithm is actually handling this. Or just run integrate() through a > debugger. > > For the pattern matching integrator, there is a discussion in another > thread here on how to make patterns match expressions that are > mathematically equivalent, but don't match exactly. > > Aaron Meurer > > On Fri, Mar 10, 2017 at 9:05 AM, Abdullah Javed Nesar > <[email protected] <javascript:>> wrote: > > Aaron in case like this, > > > >>>> integrate(E**(n*log(a+b*x)), x) > > ⎧⎩⎨1blog(ab+x)abn+benlog(a+bx)+bxbn+benlog(a+bx)forn=−1otherwise > > E**(n*log(a+b*x))should better be simplified to (a+b*x)**n to proceed > > further, can you tell me how SymPy currently handles such cases? > > > > Abdullah Javed Nesar > > On Thursday, March 9, 2017 at 11:54:32 PM UTC+5:30, Aaron Meurer wrote: > >> > >> Can you clarify what you mean by this? > >> > >> Aaron Meurer > >> > >> On Thu, Mar 9, 2017 at 1:14 PM Abdullah Javed Nesar < > [email protected]> > >> wrote: > >>> > >>> Hi, > >>> > >>> I am not able to figure out how exactly we will use replacement > allowing > >>> technique in Rubi and when do we use it, can anyone explain this? > >>> > >>> Thanks. > >>> > >>> > >>> On Thursday, March 9, 2017 at 9:47:10 PM UTC+5:30, Abdullah Javed > Nesar > >>> wrote: > >>>> > >>>> Hi, > >>>> Arihant thanks for those suggestions, I guess if rule name contains > >>>> Algebraic then just > >>>> > >>>> >>> def rule_algebraic_integrand_1_1(expr, symbol) > >>>> > >>>> would suffice, no need for >>>def > rule_algebraic_integrand_1_1_1_1(expr, > >>>> symbol) (indicating algebraic integrand>linear product>(a + > b*x)**m). Yes, > >>>> this way the functions would be named in a systematic way, > necessarily > >>>> supported by a docstring which would explain those rules in details, > as > >>>> Aaron pointed. > >>>> > >>>> Pattern matching used in manualintegrate() is a simple one without a > >>>> decision tree and hence less efficient. The tree for (a + b*x)**m > would be > >>>> better represented as > >>>> Pow(Add(a, Mul(b, x)), m), well explained in #7748. > >>>> > >>>> > >>>> On Thursday, March 9, 2017 at 3:36:30 PM UTC+5:30, Arihant Parsoya > >>>> wrote: > >>>>> > >>>>> Thanks Aaron, > >>>>> > >>>>> I read the discussion to improve pattern matching algorithm. Can you > >>>>> give some information about which algorithm is currently being used > for > >>>>> pattern matching? > >>>>> > >>>>> I have been testing `match()` to check if it works properly for > complex > >>>>> expressions. It gives correct answer if we `exclude` the integration > >>>>> variable. However, there can be issues in matching expression when > brackets > >>>>> are automatically evaluated by SymPy: > >>>>> > >>>>> >>> x, y, z, F, fx = symbols('x, y, z, F, fx') > >>>>> > >>>>> >>> a = Wild('a', exclude=[x]) > >>>>> > >>>>> >>> b = Wild('b', exclude=[x]) > >>>>> > >>>>> >>> c = Wild('c', exclude=[x]) > >>>>> > >>>>> >>> d = Wild('d', exclude=[x]) > >>>>> > >>>>> >>> e = Wild('e', exclude=[x]) > >>>>> > >>>>> >>> f = Wild('f', exclude=[x]) > >>>>> > >>>>> >>> g = Wild('g', exclude=[x]) > >>>>> > >>>>> >>> p = Wild('p', exclude=[x]) > >>>>> > >>>>> >>> n = Wild('n', exclude=[x]) > >>>>> > >>>>> >>> m = Wild('m', exclude=[x]) > >>>>> > >>>>> >>> expr = ((1 + 2*x)**3) * ((F**(4*(5 + fx)))**6) * (6 + > 7*(F**(4*(5 + > >>>>> >>> fx))))**8 > >>>>> > >>>>> >>> pattern = ((c + d*x)**m) * ((F**(g*(e + fx)))**n) * (a + > >>>>> >>> b*(F**(g*(e + fx))))**p > >>>>> > >>>>> >>> pprint(pattern) > >>>>> > >>>>> p n > >>>>> > >>>>> ⎛ g⋅(fx + e) ⎞ m ⎛ g⋅(fx + e)⎞ > >>>>> > >>>>> ⎝F ⋅b + a⎠ ⋅(x⋅d + c) ⋅⎝F ⎠ > >>>>> > >>>>> >>> pprint(expr) > >>>>> > >>>>> 8 > >>>>> > >>>>> 24⋅fx + 120 ⎛ 4⋅fx + 20 ⎞ 3 > >>>>> > >>>>> F ⋅⎝7⋅F + 6⎠ ⋅(2⋅x + 1) > >>>>> > >>>>> >>> expr.match(pattern) > >>>>> > >>>>> {p_: 1, g_: 1, m_: 3, d_: 2, n_: 0, e_: 23*fx + 120, c_: 1, a_: 0, > b_: > >>>>> (7*F**(4*fx + 20) + 6)**8} > >>>>> > >>>>> > >>>>> We need to find a way to convert the expresison into known standard > >>>>> form so pattern matching can be done peoperly or implement such > >>>>> functionality in `.match()` itself. > >>>>> > >>>>> > >>>>> Thanks > >>>>> > >>>>> > >>>>> > >>>>> On Thursday, March 9, 2017 at 12:16:41 AM UTC+5:30, Aaron Meurer > wrote: > >>>>>> > >>>>>> That's sounds fine, though it should also include a docstring that > >>>>>> lists the rule so we don't have to depend on the Rubi site. This > will also > >>>>>> let us generate some documentation on what rules are supported. > >>>>>> > >>>>>> We will likely want to extend the rules beyond what Rubi has > >>>>>> eventually, so we should also consider that. > >>>>>> > >>>>>> Aaron Meurer > >>>>>> > >>>>>> On Wed, Mar 8, 2017 at 12:07 PM Arihant Parsoya < > [email protected]> > >>>>>> wrote: > >>>>>>> > >>>>>>> Hi, > >>>>>>> > >>>>>>> I observed that rules in manualintegrate() are countable in > number. > >>>>>>> While implementing ~7000 rules, naming each rule is also going to > be a big > >>>>>>> issue. I was thinking, names should be given based on the serial > number of > >>>>>>> the rule in Rubi website. For example algebric rules for linear > products > >>>>>>> should be named as: > >>>>>>> > >>>>>>> >>> def rule_algebric_integrand_1_1_1_1(expr, symbol): > >>>>>>> > >>>>>>> ... return log(expr) > >>>>>>> > >>>>>>> > >>>>>>> Using the above syntax for names of rules, we will be able to > >>>>>>> uniquely identify each rule. Is this desirable? > >>>>>>> > >>>>>>> Thanks, > >>>>>>> Arihant Parsoya > >>>>>>> > >>>>>>> On Monday, March 6, 2017 at 10:44:41 PM UTC+5:30, Abdullah Javed > >>>>>>> Nesar wrote: > >>>>>>>> > >>>>>>>> Hi, > >>>>>>>> > >>>>>>>> I was looking into sympy.integrals.manualintegrate.py it seems > that > >>>>>>>> the pattern matching (in manualintegrate) is quite different from > what is > >>>>>>>> expected in Rubi. As PR #7748 mentions we'll be using a better > approach > >>>>>>>> using decision tree, can you elaborate on what is expected? How > decision > >>>>>>>> tree concludes to a rule of integration then falls into function > integrate() > >>>>>>>> which contains rules like 1.1.1 (a + b*x)**m? > >>>>>>>> > >>>>>>>> Abdullah Javed Nesar > >>>>>>>> > >>>>>>>> On Monday, March 6, 2017 at 2:59:38 AM UTC+5:30, Aaron Meurer > wrote: > >>>>>>>>> > >>>>>>>>> integrate() uses several algorithms, and one or more algorithms > may > >>>>>>>>> apply to any specific integral. Some algorithms, if you know how > >>>>>>>>> they > >>>>>>>>> work, you can easily see if they won't apply to a specific > >>>>>>>>> integrand. > >>>>>>>>> The best way to tell how it works for a specific integral is to > >>>>>>>>> check > >>>>>>>>> the various algorithms. Another thing that I highly suggest is > to > >>>>>>>>> run > >>>>>>>>> the integrate() function through a debugger, so you can see how > it > >>>>>>>>> works (I like PuDB, but any debugger that you are comfortable > with > >>>>>>>>> will work). > >>>>>>>>> > >>>>>>>>> Here are the algorithms used by integrate() (I hope I didn't > forget > >>>>>>>>> any). You can import each algorithm from the specified module > to > >>>>>>>>> try > >>>>>>>>> it > >>>>>>>>> > >>>>>>>>> sympy.integrals.risch.risch_integrate() - Risch algorithm. > >>>>>>>>> Currently > >>>>>>>>> only works for transcendental equations with exp() and log(). > >>>>>>>>> > >>>>>>>>> sympy.integrals.manualintegrate.manualintegrate() - Manual > >>>>>>>>> integration. That means, integration akin to how you would do > >>>>>>>>> things > >>>>>>>>> by hand. This is very similar to Rubi in that it does pattern > >>>>>>>>> matching > >>>>>>>>> against some rules. Ideally any implementation of Rubi would > merge > >>>>>>>>> with manualintegrate() so we don't have two pattern matching > >>>>>>>>> integrators. > >>>>>>>>> > >>>>>>>>> sympy.integrals.trigonometry.trigintegrate() - Integrate trig > >>>>>>>>> functions. Also uses pattern matching. > >>>>>>>>> > >>>>>>>>> sympy.integrals.rationaltools.ratint() - Integrate rational > >>>>>>>>> functions. > >>>>>>>>> > >>>>>>>>> sympy.integrals.meijerint.meijerg_definite() and > >>>>>>>>> sympy.integrals.meijerint.meijerg_indefinite() - Integration > using > >>>>>>>>> the > >>>>>>>>> Meijer G algorithm (roughly, by translating the integral to a > >>>>>>>>> Meijer > >>>>>>>>> G-function, integrating, then translating back). > >>>>>>>>> > >>>>>>>>> sympy.integrals.heurisch.heurisch() - The heuristic Risch > >>>>>>>>> algorithm. > >>>>>>>>> This is tried last, because it can be very slow (sometimes > hanging > >>>>>>>>> the > >>>>>>>>> integrator), but there are cases where only it can produce an > >>>>>>>>> answer. > >>>>>>>>> > >>>>>>>>> You should be able to apply any of these functions directly on > an > >>>>>>>>> integrand to see if they can produce an answer. > >>>>>>>>> > >>>>>>>>> The algorithms are tried in order until one gives an answer. I > >>>>>>>>> don't > >>>>>>>>> remember exactly what order, but I think it's similar to the > above. > >>>>>>>>> I > >>>>>>>>> do know that heurisch() is last, because it's the worst. > >>>>>>>>> > >>>>>>>>> Aaron Meurer > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Sun, Mar 5, 2017 at 12:00 PM, Abdullah Javed Nesar > >>>>>>>>> <[email protected]> wrote: > >>>>>>>>> > Hi Aaron, > >>>>>>>>> > > >>>>>>>>> > Thanks for your explanation. > >>>>>>>>> > > >>>>>>>>> > How does SymPy evaluates integrals like, > >>>>>>>>> > > >>>>>>>>> >>>integrate((a + b*u)**m, x) when u = c + dx (i.e. Integration > by > >>>>>>>>> >>> substitution) > >>>>>>>>> > > >>>>>>>>> > I couldn't find such an example can give one? > >>>>>>>>> > > >>>>>>>>> > Abdullah Javed Nesar > >>>>>>>>> > > >>>>>>>>> > On Sunday, March 5, 2017 at 11:58:20 AM UTC+5:30, Aaron Meurer > >>>>>>>>> > wrote: > >>>>>>>>> >> > >>>>>>>>> >> The SymPy assumptions system lets you define x = Symbol('x', > >>>>>>>>> >> positive=True) (and query like x.is_positive). The pattern > >>>>>>>>> >> matcher > >>>>>>>>> >> will need to be able to set and define restrictions like > this. > >>>>>>>>> >> Also > >>>>>>>>> >> note that expand_log() and logcombine() already expand and > >>>>>>>>> >> combine > >>>>>>>>> >> logarithms and check the domain restrictions. > >>>>>>>>> >> > >>>>>>>>> >> Another thing is that the integrator should return a > Piecewise > >>>>>>>>> >> whenever possible. For example, the current integrator: > >>>>>>>>> >> > >>>>>>>>> >> In [6]: integrate(x**n, x) > >>>>>>>>> >> Out[6]: > >>>>>>>>> >> ⎧log(x) for n = -1 > >>>>>>>>> >> ⎪ > >>>>>>>>> >> ⎪ n + 1 > >>>>>>>>> >> ⎨x > >>>>>>>>> >> ⎪────── otherwise > >>>>>>>>> >> ⎪n + 1 > >>>>>>>>> >> ⎩ > >>>>>>>>> >> > >>>>>>>>> >> This way we get results that are mathematically correct, even > >>>>>>>>> >> when > >>>>>>>>> >> assumptions aren't set. > >>>>>>>>> >> > >>>>>>>>> >> Aaron Meurer > >>>>>>>>> >> > >>>>>>>>> >> On Thu, Mar 2, 2017 at 8:56 AM, Abdullah Javed Nesar > >>>>>>>>> >> <[email protected]> wrote: > >>>>>>>>> >> > Hi Ondřej, > >>>>>>>>> >> > > >>>>>>>>> >> > I am willing to work on Rubi Integrator this summer. I went > >>>>>>>>> >> > through the > >>>>>>>>> >> > issues you raised for this project and this idea really > sounds > >>>>>>>>> >> > cool. It > >>>>>>>>> >> > would be great to segregate the different methods of > >>>>>>>>> >> > integration into a > >>>>>>>>> >> > decision tree which would hence improve its performance. > >>>>>>>>> >> > > >>>>>>>>> >> > Before implementing Rule-based integrator we need to > implement > >>>>>>>>> >> > fast > >>>>>>>>> >> > pattern > >>>>>>>>> >> > matching/replacement for the set of 10,000 rules so we need > to > >>>>>>>>> >> > plan out > >>>>>>>>> >> > an > >>>>>>>>> >> > efficient decision tree for it. > >>>>>>>>> >> > > >>>>>>>>> >> > log(x*y) -> log(x) + log(y); x > 0, y > 0 > >>>>>>>>> >> > > >>>>>>>>> >> > > >>>>>>>>> >> > In the above example how do we exactly move on with domain > >>>>>>>>> >> > restrictions > >>>>>>>>> >> > (i.e. x, y). > >>>>>>>>> >> > > >>>>>>>>> >> > On Wednesday, March 1, 2017 at 8:39:41 PM UTC+5:30, Ondřej > >>>>>>>>> >> > Čertík wrote: > >>>>>>>>> >> >> > >>>>>>>>> >> >> Hi, > >>>>>>>>> >> >> > >>>>>>>>> >> >> Here is a project that I would love to see happen: > >>>>>>>>> >> >> > >>>>>>>>> >> >> https://github.com/sympy/sympy/issues/12233 > >>>>>>>>> >> >> > >>>>>>>>> >> >> I am available to mentor it, and I think quite a few > people > >>>>>>>>> >> >> are > >>>>>>>>> >> >> excited about it and such a system/framework (i.e. set of > >>>>>>>>> >> >> rules for > >>>>>>>>> >> >> patter matching + compiler to generate a fast if/then/else > >>>>>>>>> >> >> decision > >>>>>>>>> >> >> tree) would have applications beyond just integration, but > >>>>>>>>> >> >> integration > >>>>>>>>> >> >> would already be super useful. As you can browse on Rubi > web > >>>>>>>>> >> >> page, the > >>>>>>>>> >> >> integrator's capabilities are very impressive, i.e. the > rule > >>>>>>>>> >> >> based > >>>>>>>>> >> >> system Rubi 4.9 can do more integrals than Mathematica, > and > >>>>>>>>> >> >> is about > >>>>>>>>> >> >> as fast, due to the large number of rules, and the > >>>>>>>>> >> >> if/then/else > >>>>>>>>> >> >> decision tree Rubi 5 promises an order of magnitude (or > more) > >>>>>>>>> >> >> speedup, > >>>>>>>>> >> >> but it's still in development. > >>>>>>>>> >> >> > >>>>>>>>> >> >> The project is big in scope, so there could even be > multiple > >>>>>>>>> >> >> projects. > >>>>>>>>> >> >> If anybody is interested in this, please get in touch, and > >>>>>>>>> >> >> try to > >>>>>>>>> >> >> propose a good plan. > >>>>>>>>> >> >> > >>>>>>>>> >> >> Ondrej > >>>>>>>>> >> > > >>>>>>>>> >> > -- > >>>>>>>>> >> > You received this message because you are subscribed to the > >>>>>>>>> >> > Google > >>>>>>>>> >> > Groups > >>>>>>>>> >> > "sympy" group. > >>>>>>>>> >> > To unsubscribe from this group and stop receiving emails > from > >>>>>>>>> >> > it, send > >>>>>>>>> >> > an > >>>>>>>>> >> > email to [email protected]. > >>>>>>>>> >> > To post to this group, send email to [email protected]. > > >>>>>>>>> >> > Visit this group at https://groups.google.com/group/sympy. > >>>>>>>>> >> > To view this discussion on the web visit > >>>>>>>>> >> > > >>>>>>>>> >> > > >>>>>>>>> >> > > https://groups.google.com/d/msgid/sympy/05a4ee3e-7a0b-485b-9918-0a68bb4f3350%40googlegroups.com. > > > >>>>>>>>> >> > > >>>>>>>>> >> > For more options, visit https://groups.google.com/d/optout. > > >>>>>>>>> > > >>>>>>>>> > -- > >>>>>>>>> > You received this message because you are subscribed to the > >>>>>>>>> > Google Groups > >>>>>>>>> > "sympy" group. > >>>>>>>>> > To unsubscribe from this group and stop receiving emails from > it, > >>>>>>>>> > send an > >>>>>>>>> > email to [email protected]. > >>>>>>>>> > To post to this group, send email to [email protected]. > >>>>>>>>> > Visit this group at https://groups.google.com/group/sympy. > >>>>>>>>> > To view this discussion on the web visit > >>>>>>>>> > > >>>>>>>>> > > https://groups.google.com/d/msgid/sympy/0cc84418-0eac-4ab2-b975-c74eeec47d64%40googlegroups.com. > > > >>>>>>>>> > > >>>>>>>>> > For more options, visit https://groups.google.com/d/optout. > >>>>>>> > >>>>>>> -- > >>>>>>> You received this message because you are subscribed to the Google > >>>>>>> Groups "sympy" group. > >>>>>>> To unsubscribe from this group and stop receiving emails from it, > >>>>>>> send an email to [email protected]. > >>>>>>> To post to this group, send email to [email protected]. > >>>>>>> Visit this group at https://groups.google.com/group/sympy. > >>>>>>> To view this discussion on the web visit > >>>>>>> > https://groups.google.com/d/msgid/sympy/8efee19b-fedd-4188-b00f-e68ecf288eb5%40googlegroups.com. > > > >>>>>>> For more options, visit https://groups.google.com/d/optout. > >>> > >>> -- > >>> You received this message because you are subscribed to the Google > Groups > >>> "sympy" group. > >>> To unsubscribe from this group and stop receiving emails from it, send > an > >>> email to [email protected]. > >>> To post to this group, send email to [email protected]. > >>> Visit this group at https://groups.google.com/group/sympy. > >>> To view this discussion on the web visit > >>> > https://groups.google.com/d/msgid/sympy/6e64ae8e-2c19-49ca-9d74-fb873ac77112%40googlegroups.com. > > > >>> For more options, visit https://groups.google.com/d/optout. > > > > -- > > You received this message because you are subscribed to the Google > Groups > > "sympy" group. > > To unsubscribe from this group and stop receiving emails from it, send > an > > email to [email protected] <javascript:>. > > To post to this group, send email to [email protected] > <javascript:>. > > Visit this group at https://groups.google.com/group/sympy. > > To view this discussion on the web visit > > > https://groups.google.com/d/msgid/sympy/2d53f1c8-52b3-4a0a-89af-bf70d83d4df1%40googlegroups.com. > > > > > > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/sympy. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/65969745-6320-4861-b193-b7844e00c8f8%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
