Given some list of symmetric integer matrices, I want to remove all duplicates under the following equivalence relation:
Two k x k matrices M1
, M2
are equivalent if there is some permutation s
on {1,...,k}
such that for all i
and j
in {1,...,k}
we have M1_ij = M2_s(i)s(j)
, i.e. two matrices are "equal" if I can get one from the other by simultaneously permuting its rows and columns.
Unfortunately, my naive approach (while building the list, check if any of the permutations of the new matrix is already in the list) proves to be too slow.
Some probably faster alternative I could think of would be putting all matrices in the list, permute them to some "canonical permutation" and then remove the duplicates as described e.g. here. However, I am not sure how to achieve such a "canonical permutation" in code either.
To narrow this down some more: The matrices are relatively small (k <= 4
), the list will contain some 5 or 6 digit number of matrices and the dtype
of the matrices has to be some integer type (currently intc
, but I could change that).
The order of the final list does not matter, neither does which representative of each equivalence class survives. The entire process may take some small number of hours if needed, but not days.
Is there some reasonably efficient way to achieve this? Did I (yet again) miss some cool NumPy or SciPy facility that would help me with this?
As requested, some small examples to demonstrate how that equivalence relation works:
The matrices {{1,1,1},{1,2,0},{1,0,3}}
and {{1,1,1},{1,3,0},{1,0,2}}
are equivalent, as the permutation {1,2,3}->{1,3,2}
transforms one to the other.
The matrices {{1,1,1},{1,2,0},{1,0,3}}
and {{1,1,0},{1,2,1},{0,1,3}}
are not equivalent, you cannot change the position of the 1s without permuting the diagonal.