Hi, I was looking at the proposal <https://github.com/sympy/sympy/wiki/Proposal-for-a-new-pattern-matching#proposals> for new pattern matching, here how to use WildNode and WildSequence?
Abdullah Javed Nesar On Wednesday, March 15, 2017 at 4:06:51 AM UTC+5:30, Francesco Bonazzi wrote: > > Concerning the pattern matching rules, it would be great if Mathics were > able to relicense the relevant part of the code under a BSD license. In > such a case, we would be able to re-use their code. > > Also, if anyone is experienced with LISP, one could also try to translate > the open source code by Richard Fateman into python, which essentially > provides Mathematica-like compatibility functions. > > Anyways, this is how I would proceed with the RUBI ruleset: > > > 1. Generate an enormous amount of reasonable simple matching rules. > This matching rules have to outnumber by far the rules in the RUBI set. > Ideally, they can be randomly derived by RUBI's ruleset. > 2. Given a large test set of integrand expressions, for each rules > count how many of these expressions are matched. > 3. Convert the number array of point 2 to a 2-state entropy > <https://en.wikipedia.org/wiki/Entropy_(information_theory)>. > 4. Take the rule with the highest entropy and use it as the base > if-clause. > 5. For each branch in the decision tree, select the rule that > maximizes the information gain > <https://en.wikipedia.org/wiki/Information_gain_in_decision_trees>. > 6. Repeat point 5 until all branches lead to a single rule. > > I think that scikit-learn <http://scikit-learn.org/> could be used in the > generating process, though I would try to do all these steps in Wolfram > Mathematica. > > On Tuesday, 14 March 2017 17:11:03 UTC-4, Aaron Meurer wrote: >> >> Also, I think the giant if-else chains in Ondrej's branch are very >> unmaintainable. We can definitely structure the rules in a way that >> makes the easier to read, document, and maintain. >> >> If we treat it as a compiled output from some script that converts >> rules from Rubi, then we can never modify it directly. But if we build >> a nice pattern matching integrator, I think we will eventually want to >> be able to add our own rules, beyond what Rubi has. We may also find >> bugs in it, which we will want to be able to fix without having to >> modify Rubi first. Since Rubi only has one maintainer and doesn't have >> a public source repo (correct me if I am wrong), this worries me quite >> a bit. >> >> Aaron Meurer >> >> On Tue, Mar 14, 2017 at 4:43 PM, Aaron Meurer <asme...@gmail.com> wrote: >> > The rules should definitely be structured in some way that we can pull >> > them all out for documentation and other purposes. Whether that means >> > functions or some other data structure I don't know. >> > >> > Aaron Meurer >> > >> > On Tue, Mar 14, 2017 at 4:40 PM, Arihant Parsoya >> > <parsoya...@gmail.com> wrote: >> >> Thanks Aaron. >> >> >> >> In manualintegrate, each rules is defined as seperate function whereas >> if we >> >> see Ondrej's PR #8036, the rules in decision tree are implemented >> directly. >> >> I am skeptical about which approach is better. I think, implementing >> rules >> >> as seperate functions can help us document the functions as well as. >> But on >> >> the other hand, it makes implementation lengthy. What do you think is >> the >> >> right way to go about it? >> >> >> >> Thanks >> >> >> >> On Wednesday, March 15, 2017 at 12:57:05 AM UTC+5:30, Aaron Meurer >> wrote: >> >>> >> >>> If we structure the rules properly, it shouldn't be necessary to >> parse >> >>> Python. >> >>> >> >>> Aaron Meurer >> >>> >> >>> On Tue, Mar 14, 2017 at 9:28 AM, Arihant Parsoya >> >>> <parsoya...@gmail.com> wrote: >> >>> > Hi Aaron, >> >>> > >> >>> > I think documentation of all the rules implemented is important(as >> >>> > mentioned >> >>> > by Ondrej). I was thinking to implement automatic documentation of >> rules >> >>> > in >> >>> > the decision tree using abstract syntax trees. AST automatically >> >>> > converts >> >>> > all `elif` and `else` conditions to `if`s. We can write a program >> which >> >>> > automatically generates documentation of rules with their >> conditions >> >>> > using >> >>> > AST. Is this a good idea? >> >>> > >> >>> > Thanks >> >>> > >> >>> > On Tuesday, March 14, 2017 at 12:39:31 AM UTC+5:30, Aaron Meurer >> wrote: >> >>> >> >> >>> >> Starting with Francesco's work is a good idea. He has thought >> about >> >>> >> pattern matching in SymPy more than anyone else. >> >>> >> >> >>> >> Aaron Meurer >> >>> >> >> >>> >> On Mon, Mar 13, 2017 at 2:48 PM, Abdullah Javed Nesar >> >>> >> <abdulja...@gmail.com> wrote: >> >>> >> > Hi, >> >>> >> > >> >>> >> > Thanks Aaron for your reply, that really helped. I think I've >> >>> >> > collected >> >>> >> > sufficient information about the project and I'll need your help >> to >> >>> >> > complete >> >>> >> > my proposal and organize tasks better. >> >>> >> > >> >>> >> > I think framing of rules is lengthy but quite straightforward. >> >>> >> > Pattern >> >>> >> > matching which needs to be implemented prior to it is where I >> need >> >>> >> > your >> >>> >> > help. I was looking at Francesco Bonazzi's proposal on new >> pattern >> >>> >> > matching >> >>> >> > and it seems fine to me. Do we need to add anything more to it >> or >> >>> >> > improve on >> >>> >> > anything? What do you think? >> >>> >> > >> >>> >> > Abdullah Javed Nesar >> >>> >> > >> >>> >> > On Saturday, March 11, 2017 at 2:46:19 AM UTC+5:30, 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 >> >>> >> >> <abdulja...@gmail.com> 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 >> >>> >> >> >> <abdulja...@gmail.com> >> >>> >> >> >> 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 >> >>> >> >> >>>>>> <parsoya...@gmail.com> >> >>> >> >> >>>>>> 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 >> >>> >> >> >>>>>>>>> <abdulja...@gmail.com> 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 >> & > > -- 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 sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. 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/9c98982c-fae3-44f2-ad71-be7771ae3737%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.