Testing an expression

74 views
Skip to first unread message

Alex Lindsay

unread,
May 5, 2016, 10:01:41 AM5/5/16
to sy...@googlegroups.com
I am trying to build a rule for manual integration. I want to test
whether an expression matches the general form:

c (e + f x)**p

where c, f, and p can be non-zero expressions not containing x, whereas
e can be zero but again cannot contain x.

Moreover, if the expressions matches the above form, I would like to
parse it such that I know the values for c, e, f, and p.

Any suggestions on general strategies for achieving my goals? I have
been thinking about prolific use of func and args. I imagine that I
would consider various branches for my test since c = 1, e = 0, f = 1,
and p = 1 would all change the class type of the expression or
sub-expressions.

Aaron Meurer

unread,
May 5, 2016, 12:42:23 PM5/5/16
to sy...@googlegroups.com
Take a look at Wild and match
http://docs.sympy.org/latest/modules/core.html#sympy.core.symbol.Wild.

Aaron Meurer
> --
> 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+un...@googlegroups.com.
> To post to this group, send email to sy...@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/572B5241.4050301%40ncsu.edu.
> For more options, visit https://groups.google.com/d/optout.

Richard Fateman

unread,
Jun 8, 2016, 10:54:05 PM6/8/16
to sympy
I suggest you get rid of all factors not dependent on x by scanning through each term in a product, if you have a product.
then you need only find if the expression is R= (e+f*x)^p.
compute t A= taylor series expansion around 0 of R and B=taylor series of diff(R,x).

Some algebra should get you e,f,p, if you had some R  of that form.  check by substitution.

Just a suggestion.

RJF

Richard Fateman

unread,
Jun 9, 2016, 5:24:55 PM6/9/16
to sympy
This works:   if h = c*(e+f*x)^p
then  h/gcd(h,diff(h,x) )  should produce f*x+e.   Setting x to 0
gives you e.  subtracting e from f*x+e and setting x to 1 gives you f.

c is kind of arbitrary, since if c=q^p, you can put it inside the ()^p.

If c is 1, then
to find p, try log(h)/log(e+f*x).

This all works in Maxima; not sure how if it works in sympy.
RJF

Aaron Meurer

unread,
Jun 9, 2016, 8:17:08 PM6/9/16
to sy...@googlegroups.com
If p is an integer, you could just factor() the expression and pattern
match against it (or to guard against slow negatives, use sqf_list,
which is basically what your technique uses). Integration should work
for any p, though, non-integer or symbolic, so long as it doesn't
depend on x. So I would recommend:

- factor() the expression in case it is expanded
- pattern match with Wild() and match() (or whatever it is
manualintegrate already uses)

More general cases, say if p is a sum and the term is expanded, may
require further simplification functions like powsimp() to bring it
into canonical form.

Aaron Meurer
> --
> 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+un...@googlegroups.com.
> To post to this group, send email to sy...@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/c52fbb2c-a0fc-49f6-b17a-1942797e91fd%40googlegroups.com.

Richard Fateman

unread,
Jun 11, 2016, 12:16:42 PM6/11/16
to sympy
Actually the question is, in some sense, wrong.  What you should be doing
(I hope you will consider this as constructive) is look for integrands of the form
constant* f(u)^p*du.

That includes  3*(4+5*x)^6    but  also  7*(8+9*x^2)^p * x
and even (1+2*sin(x))^p*cos(x).

this is one part of a "derivative-divides" integration system.
You can look for a product where there is a power of a function of x, f(x)^p.
See if  diff(f(x),x) divides the rest of the product evenly [giving you the constant].
and then you know the integral is f(x)^(p+1)/(p+1) times the constant.
(special case for p=-1 is log...)

This is so much more powerful, and yet easy to explain, and probably
no harder to program, that you should be doing this instead.

If you want to see how to do this, in a half-page of code, and much much
more in 2 pages, see this..

and read the documentation, in a link on line 5 of that.


RJF
Reply all
Reply to author
Forward
0 new messages