Dear all,<br><br>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). <br>
<br>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. It looks to me that this is related to the ordering of the expressions.<br>
<br>Here is some example code:<br><br>-----------------------------------------------------------------------------------------------------------------------------------<br>#include&lt;iostream&gt;<br>#include&lt;vector&gt;<br>
#include&lt;sstream&gt;<br>#include&lt;ginac/ginac.h&gt;<br>using namespace std;<br>using namespace GiNaC;<br><br>//Aim is to identify A_mu gamma_mu B_nu gamma_nu == A_mu B_nu delta_mu,nu<br>int main(){<br><br>  ex metric = unit_matrix(4);<br>
  idx i(symbol(&quot;i&quot;),4) , j(symbol(&quot;j&quot;),4);<br>  ex al_i = clifford_unit(i,metric); //Use generalised clifford gamma matrices for euclidean space<br>  ex al_j = clifford_unit(j,metric);<br><br>  //Create generic &#39;slashed&#39; symbols with euclidean metric<br>
  <br>  ex s1 = indexed(symbol(&quot;A&quot;),i)*al_i;<br>  ex s2 = indexed(symbol(&quot;B&quot;),j)*al_j;<br><br>  //Form the product<br>  ex prod = s1*s2;<br><br>  cout &lt;&lt; s1*s2 &lt;&lt; endl;<br><br>  //Attempt to match to patterns<br>
  idx w1(wild(1),4), w2(wild(2),4);<br>  indexed in2_w1 = indexed(wild(2),w1);<br>  indexed in3_w2 = indexed(wild(3),w2);<br>  ex al_w1 = clifford_unit(w1,metric);<br>  ex al_w2 = clifford_unit(w2,metric);<br><br>  ex spat2_w1 = in2_w1*al_w1;<br>
  ex spat3_w2 = in3_w2*al_w2;<br><br>  ex mpat = spat2_w1 * spat3_w2;<br>  cout &lt;&lt; &quot;MATCHING TO PATTERN: &quot; &lt;&lt; mpat &lt;&lt; endl;<br>  cout &lt;&lt; prod.match(mpat) &lt;&lt; endl;<br><br>  ex mpat2 = in2_w1 * in3_w2 * al_w1 * al_w2;<br>
  cout &lt;&lt; &quot;MATCHING TO PATTERN: &quot; &lt;&lt; mpat2 &lt;&lt; endl;<br>  cout &lt;&lt; prod.match(mpat2) &lt;&lt; endl;  <br><br>  ex mpat3 = in3_w2 * in2_w1 * al_w1 * al_w2;<br>  cout &lt;&lt; &quot;MATCHING TO PATTERN: &quot; &lt;&lt; mpat3 &lt;&lt; endl;<br>
  cout &lt;&lt; prod.match(mpat3) &lt;&lt; endl;   <br><br>  return 0;<br>}<br>-----------------------------------------------------------<br><br>The output of this example is as follows:<br><br>B.j*(e.i*e.j)*A.i    &lt;----- matching this against pattern<br>
MATCHING TO PATTERN: (e.($1)*e.($2))*$3.($2)*$2.($1)<br>0<br>MATCHING TO PATTERN: (e.($1)*e.($2))*$3.($2)*$2.($1)<br>0<br>MATCHING TO PATTERN: (e.($1)*e.($2))*$3.($2)*$2.($1)<br>0<br><br>So the expressions seem to all be reordered consistently, but in a different ordering to the object to which we wish to match.<br>
<br>If i then add more code, reproducing the above code for the first pattern but using different wildcard indices:<br><br>-----------------------------------------------------------<br>  //Create new indices, perhaps hash ordering will be correct for these?<br>
  <br>  idx w4(wild(4),4), w5(wild(5),4);<br>  indexed in2_w4 = indexed(wild(2),w4);<br>  indexed in3_w5 = indexed(wild(3),w5);<br>  ex al_w4 = clifford_unit(w4,metric);<br>  ex al_w5 = clifford_unit(w5,metric);<br><br>  ex spat2_w4 = in2_w4*al_w4;<br>
  ex spat3_w5 = in3_w5*al_w5;<br><br>  ex mpat4 = spat2_w4 * spat3_w5;<br>  cout &lt;&lt; &quot;MATCHING TO PATTERN: &quot; &lt;&lt; mpat4 &lt;&lt; endl;<br>  cout &lt;&lt; prod.match(mpat4) &lt;&lt; endl;<br><br>----------------------------------------------------------<br>
<br>The output sometimes (but not always) matches:<br><br>First run:  (object to match output as  B.j*(e.i*e.j)*A.i  )<br><br>MATCHING TO PATTERN: $2.($4)*(e.($4)*e.($5))*$3.($5)<br>
0<br><br>Second run: (object to match output as (e.i*e.j)*B.j*A.i )<br><br>MATCHING TO PATTERN: (e.($4)*e.($5))*$3.($5)*$2.($4)<br>1<br><br>Third run: (object to match output as B.j*(e.i*e.j)*A.i  )  &lt;---- notice this is the same as the first run<br>
<br>MATCHING TO PATTERN: (e.($4)*e.($5))*$3.($5)*$2.($4)<br>1<br><br>So for some reason the pattern matching is ordering dependent in a way that cannot be controlled. Strangely even if the pattern matches<br>for a given run, the substitution code<br>
<br>-------------------------------------------------<br>  //Pattern sometimes matches, try a substitution for identity<br>  <br>  ex ident = in2_w4 * in3_w5 * delta_tensor(w4,w5);<br><br>  cout &lt;&lt; &quot;SUBSTITUTION RESULT:&quot; &lt;&lt; prod.subs(mpat4==ident) &lt;&lt; endl;<br>
  cout &lt;&lt; &quot;SUBSTITUTION RESULT (ALGEBRAIC):&quot; &lt;&lt; prod.subs(mpat4==ident,subs_options::algebraic) &lt;&lt; endl;<br>--------------------------------------------------<br><br>always seems to fail (or is ignored?)<br>
<br>Second run: (object to match output as (e.i*e.j)*B.j*A.i )<br><br>SUBSTITUTION RESULT:(e.i*e.j)*B.j*A.i<br>SUBSTITUTION RESULT (ALGEBRAIC):(e.i*e.j)*B.j*A.i<br><br>Third run: (object to match output as B.j*(e.i*e.j)*A.i  )<br>
<br>SUBSTITUTION RESULT:B.j*(e.i*e.j)*A.i<br>SUBSTITUTION RESULT (ALGEBRAIC):B.j*(e.i*e.j)*A.i<br><br>Does anyone know how to solve these issues?<br><br>Thanks,<br>Chris K<br><br>