I have defined several symbolic function f[x],g[x,y],h[x,y,z] etc... And I have a list made of elements which are product of these functions with different arguments; for example,

list = { f[a]f[-a], f[a]g[c,d]h[-a,-c,-d],  f[c]f[-c] ,
       f[d]g[a,y]h[-d,-a,-y] , f[b]f[-a] , f[-c]f[c] ,
       f[d]g[a,y]h[-d,-a,-z] }

Actually, these functions are just symbolic. They do not return any value. You can think the functions' arguments as tensorial indexes.

I want to find an efficient function checkPattern[list_] which does the following

1) Take the first element f[a]f[-a] and find if there are others elements matching this pattern; so, for example, the third element of list is "equal" to the first one, in the sense that f[a]f[-a]~f[c]f[-c]~f[-c]f[c] irrespectively of the arguments. Note that the elements f[a]f[-a] and f[b]f[-a] are different.

2) Take the second element (which is more complicated) and does the same check as the step 1.

So the result would be

(* {{1,3,6},{2,4},{5},{7}}*)
  • $\begingroup$ Why not represent your products using TensorProduct/TensorContract? For example, both f[-c]f[c] and f[a] f[-a] could be TensorContract[TensorProduct[f, f], {{1,2}}] and f[a]g[c,d][h[-a,-c,-d] could be TensorContract[TensorProduct[f,g,h], {{1, 4}, {2,5}, {3, 6}}]. This eliminates the use of dummy indices. $\endgroup$
    – Carl Woll
    Apr 2, 2018 at 21:43
  • $\begingroup$ I know the TensorProduct function; but this would not allow me to do symbolic computation $\endgroup$
    – apt45
    Apr 2, 2018 at 21:44
  • $\begingroup$ Why would TensorProduct prevent you from doing symbolic computations? $\endgroup$
    – Carl Woll
    Apr 2, 2018 at 22:08

1 Answer 1


Here is your list:

list = {f[a] f[-a], f[a] g[c, d] h[-a, -c, -d], f[c] f[-c], 
   f[d] g[a, y] h[-d, -a, -y], f[b] f[-a], f[-c] f[c], 
   f[d] g[a, y] h[-d, -a, -z]};

Borrowing from here, we can find a list of all distinct patterns as follows:

patterns = Quiet[
     list /. 
      p : Alternatives[a | b | c | d | x | y | z] :> 
       Pattern[p, Blank[]],
     Internal`ComparePatterns[##] == "Identical" &
    MemberQ[{"Identical" , "Specific"}, Internal`ComparePatterns[##]] &]

Observe that I had to specify which symbols may be used as "indices".

A first approximation to the ultimate result could be

allpos = Map[Flatten@Position[list, #] &, patterns]

{{1, 3, 6}, {1, 3, 5, 6}, {2, 4}, {2, 4, 7}}

This can be cleaned up by utilizing that patterns is already ordered:

Table[Complement[allpos[[i]], Union @@ allpos[[1 ;; i - 1]]], {i, 1, Length[allpos]}]

{{1, 3, 6}, {5}, {2, 4}, {7}}

  • $\begingroup$ Thank you. I did not understand the last passage, when you clean allpos. Is this operation valid for any type of list like list or it is specific for the example I gave? $\endgroup$
    – apt45
    Apr 3, 2018 at 6:42
  • $\begingroup$ The cleaning just removes duplicated from allpos while preserving the first occurence (since patterns is ordered by "specificallity", the first occurence belongs to the most specific pattern). It is meant to work with all input lists list for which patterns can be set up correctly. I haven't performed any further tests, though. $\endgroup$ Apr 3, 2018 at 6:51
  • 1
    $\begingroup$ Ok thanks. I'll do some tests and let you know :) $\endgroup$
    – apt45
    Apr 3, 2018 at 6:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.