You need to give arguments to the function.   Most things that I have  
tried in SymPy do not work with Functions unless they have arguments.   
If you don't want arguments, just use a Symbol.  I don't think implied  
arguments (e.g., everything a function of t) has been implemented,  
though it has been suggested.
 >>> from sympy import *
 >>> a = Wild('a', exclude=[pi])
 >>> b = Wild('b')
 >>> t = Symbol('t')
 >>> e = pi/S(2) + x(t)
 >>> e.match(a*pi + b)
{a: 1/2, b: x(t)}

If you run into something for which that doesn't work, one trick that  
I have used is to substitute the function for a dummy variable, do  
whatever you want to do, and then substitute it back.
use
y = Symbol('y', dummy=True) #dummy takes care of the possibility that  
the expression will have y in it already.
This also only works if you provide the arguments of the function,  
such as
expr = expr.subs(f(x), y)
<do something with expr>
expr = expr,subs(y, f(x))

I have personally found this useful if I want to substitute something  
for x but not for x in f(x), or if I want to take the partial with  
respect to x or y and y == y(x) in the expression (I am working on  
ODEs and dsolve).

Aaron Meurer

On May 26, 2009, at 2:46 PM, Luke wrote:

>
> 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