Hi David (CCing the list),

Yes, I know - I need to remember to press"Reply List" rather than "Reply" in Thunderbird!


I haven't used Mathematica's pattern functionality myself so I'm
interested to hear how it compares.

Sure - to use your example:


In[2]:= Sin[a*x + b] /. Sin[x*p1_. + p2_.] -> Cos[x*p1 + p2]

Out[2]= Cos[b + a x]

p1_ matches anything and p1_. also matches nothing by default in the context of multiplication (i.e.  1). Since p2_. is used in the context of addition, it matches zero by default. On the RHS there are referred to as p1 and p2 (which implies some rather complicated scoping rules that only apply within the replacement operation.

Here I make use of both the defaults (p1=1 and p2=0)

In[5]:= Sin[x] /. Sin[x*p1_. + p2_.] -> Cos[x*p1 + p2]unwanted

Out[5]= Cos[x]

These replacements do not have to be at the top level:

In[6]:= Exp[Sin[a*x + b]] /. Sin[x*p1_ + p2_.] -> Cos[x*p1 + p2]

Out[6]= E^Cos[b + a x]

There is also a variant of ->, :> which suppressed certain possible evaluations, but My Mathematica is fairly rusty.

Of course every Mathematica operator - such as '->' and '/.' has a long form which avoids remembering all the various operator precedences.

The sheer compactness of these replacements makes replacement operations very popular for algebraic manipulations.


The patterns made with Wild are used to extract the components of the
expression that match the Wild symbols so that you can use them for
other things. Suppose that I want to test if an expression is of the
form sin(a*x + b) and if so identify a and b so that I can use them to
build another expression. Then I can do:

In [7]: a = Wild('a')

In [8]: b = Wild('b')

In [9]: x = Symbol('x')

In [10]: expr = sin(sqrt(2)*x - 1)

In [11]: pattern = sin(a*x + b)

In [12]: expr.match(pattern)
Out[12]: {a: √2, b: -1}

In [13]: m = expr.match(pattern)

In [14]: cos(m[a]*x + m[b])
Out[14]: cos(√2⋅x - 1)

Of course you might want to do something more complicated than just
replace sin with cos so it is useful to be able to extract the values
m[a] and m[b]. For example if m[a] was equal to 2 you could apply the
double angle formula or something like that.

You can also use the Wild symbols with replace like:

In [7]: expr.replace(sin(a*x + b), cos(a*x + b))
Out[7]: cos(√2⋅x - 1)

You can also use a Wild pattern with find to extract sub-expressions
matching a pattern:

In [7]: expr = Integral(1 + sin(2*x + 1) + sin(3*x), x)

In [8]: expr
Out[8]:
⌠
⎮ (sin(3⋅x) + sin(2⋅x + 1) + 1) dx
⌡

In [9]: expr.find(sin(a*x + b))
Out[9]: {sin(3⋅x), sin(2⋅x + 1)}

This basically calls match recursively on all subtrees of the
expression so it can be quite inefficient for larger expressions. If
the objective was just to find all examples of sin then atoms is more
efficient:

Because you do actually extract the values taken on by the patterns in those examples, I rather wonder if something more like Mathematica replacements could be constructed out of what is already available in SymPy?

David

--
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/2613c6fe-bbe2-fc33-cbf6-fc8f7215489b%40dbailey.co.uk.

Reply via email to