Aaron,
  It seems like this only works for Symbol instances, not
FunctionClass instances, i.e:
>>> from sympy import *
>>> x = Function('x')
>>> a = Wild('a', exclude=[pi])
>>> b = Wild('b')
>>> e = pi/S(2) + x
>>> e.match(a*pi + b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/core/basic.py", line 1317, in match
    return pattern.matches(self, {})
  File "sympy/core/operations.py", line 111, in _matches_commutative
    if (not p in repl_dict) and (not p in expr):
  File "sympy/core/basic.py", line 1046, in __contains__
    if what in x:
TypeError: argument of type 'FunctionClass' is not iterable
>>> a = WildFunction('a', exclude=[pi])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/core/function.py", line 399, in __new__
    obj = Function.__new__(cls, name, **assumptions)
  File "sympy/core/multidimensional.py", line 127, in wrapper
    return f(*args, **kwargs)
  File "sympy/core/cache.py", line 82, in wrapper
    return func_cache_it_cache[k]
TypeError: unhashable type: 'list'
>>> a = WildFunction('a', exclude=pi)
>>> b = WildFunction('b')
>>> e.match(a*pi + b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/core/basic.py", line 1317, in match
    return pattern.matches(self, {})
  File "sympy/core/operations.py", line 111, in _matches_commutative
    if (not p in repl_dict) and (not p in expr):
  File "sympy/core/basic.py", line 1046, in __contains__
    if what in x:
TypeError: argument of type 'FunctionClass' is not iterable
>>> a = Wild('a', exclude=[pi])
>>> e.match(a*pi + b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/core/basic.py", line 1317, in match
    return pattern.matches(self, {})
  File "sympy/core/operations.py", line 111, in _matches_commutative
    if (not p in repl_dict) and (not p in expr):
  File "sympy/core/basic.py", line 1046, in __contains__
    if what in x:
TypeError: argument of type 'FunctionClass' is not iterable
>>>


The reason I see this being a problem is that people might not always
be using Symbol instances, they may instead want to use a Function
that is implicitly dependent upon one or more other variables (case in
point, generalized coordinates in classical mechanics).

Ondrej, I'm told you are the only one who understands .match(), can
you shed any light on this? Maybe we just need to extend .match() to
work with other things besides Symbol?

~Luke


On May 26, 9:33 am, Luke <hazelnu...@gmail.com> wrote:
> Thanks.
>
> On May 25, 9:02 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote:
>
> > You need to use the exclude option I was telling you about.  Do,
> >  >>> a = Wild('a', exclude=[pi])
> > and
> >  >>> b = Wild('a', exclude=[pi]).
> > and you get
> >  >>> e1.match(a*pi + b)
> > {a_: 1, b_: x}
> >  >>> b = Wild('b', exclude=[pi])
> >  >>> e2.match(a*pi + b)
> > {b_: -x, a_: 1}
> >  >>> e3.match(a*pi + b)
> > {b_: x, a_: -1}
> >  >>> e4.match(a*pi + b)
> > {b_: -x, a_: -1}
>
> > just as you expected.
>
> > Aaron Meurer
> > On May 25, 2009, at 7:46 PM, Luke wrote:
>
> > > Aaron,
> > > Thanks for the clarification.  I think I get the idea, but I'm
> > > having trouble matching expressions of the following form:
> > > a = Wild('a')
> > > b = Wild('b')
> > > x = Symbol('x')
> > > e1 = pi + x
> > > e2 = pi - x
> > > e3 = -pi + x
> > > e4 = -pi - x
>
> > > I would think that for e{1,2,3,4} that I could get the following
> > > behavior:
> > >>>> e1.match(a*pi + b)
> > > {a: 1, b: x}
> > >>>> e2.match(a*pi + b)
> > > {a: 1, b: -x}
> > >>>> e3.match(a*pi + b)
> > > {a: -1, b: x}
> > > e4.match(a*pi + b)
> > > {a: -1, b: -x}
>
> > > But instead, I get:
> > > In [61]: e1.match(a*pi + b)
> > > Out[61]:
> > > ⎧   x      ⎫
> > > ⎨a: ─, b: π⎬
> > > ⎩   π      ⎭
>
> > > In [65]: e2.match(a*pi+b)
> > > Out[65]: {a: 1, b: -x}
>
> > > In [66]: e3.match(a*pi+b)
> > > Out[66]:
> > > ⎧   x       ⎫
> > > ⎨a: ─, b: -π⎬
> > > ⎩   π       ⎭
>
> > > In [67]: e4.match(a*pi+b)
> > > Out[67]: {a: -1, b: -x}
>
> > > The results for e2 and e4 makes sense to me, but I don't understand
> > > the behavior for e1 and e3.  Is there another simpler approach, or am
> > > I missing something fundamental here?
>
> > > Thanks,
> > > ~Luke
>
> > > On May 25, 4:07 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote:
> > >> On May 25, 2009, at 11:56 AM, Luke wrote:
>
> > >>> Here is the link for the Maxima trigsimp() code.  It was written in
> > >>> 1981, according to the comments!!!
> > >>>http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/trigonom
> > >>> ...
>
> > >>> I emailed the authors of the Fu et al. paper to see if they would be
> > >>> willing to share their implementation of the algorithm -- maybe we  
> > >>> can
> > >>> save ourselves some work this way.
>
> > >>> I want to start coding for this, because much of the stuff I am  
> > >>> doing
> > >>> in PyDy is heavy on kinematics and the expressions become  
> > >>> excessively
> > >>> long unless intelligent trigsimplification is possible.  Many of my
> > >>> unittests simply will not work because some results I know to be  
> > >>> true
> > >>> cannot be achieved with the current state of trigsimp, so this has
> > >>> become a significant limitation for me.
>
> > >>> What should be the general framework for implementing the 'rules'  
> > >>> that
> > >>> are laid out in the Fu paper?  There are certainly other rules we
> > >>> could find, either on Wikipedia, Mathworld, or in a engineering/
> > >>> mathematics reference manual.
>
> > >>> I have read over how trigsimp() and trigsimp_nonrecursive() are
> > >>> currently implemented, and I think I get the gyst of what the  
> > >>> approach
> > >>> is.  Can somebody explain what this is doing exactly:
> > >>> for pattern, simp in matchers:
> > >>>       res = result.match(pattern)
> > >>>       ....
>
> > >>> I'm not 100% clear on the use of the .match() method, does somebody
> > >>> have a quick example of use?
>
> > >> This should be res = ret.match(pattern).
>
> > >> match() takes a wildcard expression and matches it into a dictionary.
> > >> In the code above, pattern is each of the items in the list
> > >> ((a*sin(b)**2, a - a*cos(b)**2),(a*tan(b)**2, a*(1/cos(b))**2 - a),
> > >> (a*cot(b)**2, a*(1/sin(b))**2 - a)) (it runs a for loop).  a, b and c
> > >> are wild cards, to it will try to take the expression result and find
> > >> what a, b, and c are equal to.
>
> > >> For example, consider the first one: a*sin(b)**2.  If your ret ==
> > >> 4*x*sin(x**2)**2, then running res = ret.match(a*sin(b)**2) will
> > >> return the dictionary {a: 4*x, b: x**2}.  You can then access a and b
> > >> from res[a] and res[b].
>
> > >> You should also probably be aware of the exclude option on Wild.  If
> > >> you do a = Wild('a', exclude=[sin(x)]), then a will not match  
> > >> anything
> > >> with sin(x) in it.  Do help(x.matches) for another example.
>
> > >>> It seems like the flow of trigsimp (in the case of recursive==False
> > >>> and deep==False):
> > >>> 1)  call trigsimp_nonrecursive(expr, deep==False), store the  
> > >>> result in
> > >>> 'result'
> > >>> 2)  do some final pattern matching on 'result', currently this will
> > >>> only simplify a*sin(b)**c/cos(b)**c --> a*tan(b)**c
>
> > >>> So, should all the rules in Fu et al. be implemented as a tuple of
> > >>> length 2 tuples, similar to the existing matchers tuple?
>
> > >>> I'm kind of thinking out loud right now and trying to figure out the
> > >>> next step to take....
>
> > >>> ~Luke
>
> > >>> On May 21, 7:42 am, Akshay Srinivasan <akshaysriniva...@gmail.com>
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com
To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to