[GiNaC-list] Pattern matching versus non-commutative products (Was: Ordering and pattern matching)

Alexei Sheplyakov varg at metalica.kh.ua
Wed Aug 26 08:01:29 CEST 2009

```Hi Chris,

On Tue, Aug 25, 2009 at 03:02:04PM +0100, Chris Kelly wrote:

> I am new to GiNaC and am currently trying to get to grips with the clifford
> algebra classes. I am trying to perform the simple substitution:  A_mu
> gamma_mu B_nu gamma_nu = A_mu A_nu delta_mu,nu (Euclidean space).
>
> The problem i am having is that the pattern match is not consistent over
> repeated use of the executable: sometimes the pattern will match, at other
> times it will not.

The pattern matching operates on internal representation (in other words
the matching is `syntactic', not algebraic). It tries to be smart(er) and
handles sums and _commutative_ products in a special way (to account
commutativity and associativity), but these tricks are not applicable to
non-commutative products and/or tensors (a.k.a. indexed). Fortunately you
don't need pattern matching to solve your problem. Simply choose appropriate
basis (for 4-dimensional space with Minkowski metric that would be the set
{1, gamma_mu, i/2 [ gamma_mu, gamma_nu ], gamma_5, gamma_5 gamma_mu }),
and operate on (commutative) coefficients.

> #include<iostream>
> #include<vector>
> #include<sstream>
> #include<ginac/ginac.h>
> using namespace std;
> using namespace GiNaC;
>
> //Aim is to identify A_mu gamma_mu B_nu gamma_nu == A_mu B_nu delta_mu,nu
> int main(){
>
>   ex metric = unit_matrix(4);
>   idx i(symbol("i"),4) , j(symbol("j"),4);
>   // Use generalised clifford gamma matrices for euclidean space
>   ex al_i = clifford_unit(i,metric);
>   ex al_j = clifford_unit(j,metric);
>
>   //Create generic 'slashed' symbols with euclidean metric
>
>   ex s1 = indexed(symbol("A"),i)*al_i;
>   ex s2 = indexed(symbol("B"),j)*al_j;
>
>   //Form the product
>   ex prod = s1*s2;
>
>   cout << s1*s2 << endl;
>
>   //Attempt to match to patterns
>   idx w1(wild(1),4), w2(wild(2),4);
>   indexed in2_w1 = indexed(wild(2),w1);

Perhaps you mean wild(4) (not wild(2)) here.

>   indexed in3_w2 = indexed(wild(3),w2);
>   ex al_w1 = clifford_unit(w1,metric);
>   ex al_w2 = clifford_unit(w2,metric);
>
>   ex spat2_w1 = in2_w1*al_w1;
>   ex spat3_w2 = in3_w2*al_w2;
>
>   ex mpat = spat2_w1 * spat3_w2;
>   cout << "MATCHING TO PATTERN: " << mpat << endl;
>   cout << prod.match(mpat) << endl;
>
>   ex mpat2 = in2_w1 * in3_w2 * al_w1 * al_w2;

Shuffling terms like this doesn't make any sense: GiNaC will put them
into canonical order anyway. So either all mpat* will match prod, or
none of them will match.

[skipped]

> Strangely even if the pattern matches for a given run, the substitution code
>
> -------------------------------------------------
>   //Pattern sometimes matches, try a substitution for identity
>
>   ex ident = in2_w4 * in3_w5 * delta_tensor(w4,w5);
>
>   cout << "SUBSTITUTION RESULT:" << prod.subs(mpat4==ident) << endl;
>   cout << "SUBSTITUTION RESULT (ALGEBRAIC):" <<

Algebraic matching can not handle non-commutative products, so it won't
be any different from syntactic one.

> prod.subs(mpat4==ident,subs_options::algebraic) << endl;
> --------------------------------------------------
> always seems to fail (or is ignored?)

This looks like a bug. I'll try to find out what's going on.

Best regards,
Alexei

```