0

I am looking at vectors [a,b,c], for a,b,c in [-1,0,1] along with a function, cycle, which shifts each entry of a vector one to the left: cycle( v ) = [v[3], v[1], v[2]].

I want to only consider vectors such that no two vectors are "cycle-equivalent"; ie: if I look at vectors x, y, I don't want y = cycle( x ).

What I tried was setting up a vector V which had all 27 of my possible vectors, and then defining the following:

removecycle( V, n ) = {
local( N );
N = setsearch( V, cycle( V[n] ) );
return( V[^N] );
}

This allows me to specify a specific vector, apply the function, and then return a new vector with the outcome, if there is one, removed. The issue of course is then I have to repeat this with the new vector, and repeat again and again, and opens myself up to human error.

How can I automate this? I imagine it is possible to set it up to have my vector of vectors V, test cycle( V[1] ), throw away the result, return a new vector W, then test cycle( W[2] ), etc etc until all possibilities have been tested. But I'm just not sure how to set it up!


Edit: MNWE, with numbers changed to above for convenience.

V=[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 3, 1], [1, 3, 2], [1, 3, 3], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 1], [2, 3, 2], [2, 3, 3], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 3, 1], [3, 3, 2], [3, 3, 3]];

vecsort(vecsort(V),are_cycles,8)
> [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 2], [1, 3, 3], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 1], [2, 3, 3], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 3, 1], [3, 3, 3]]
#vecsort(vecsort(V),are_cycles,8)
> 23

In my case, I would have cycle( [1, 1, 2] ) = [2, 1, 1], so I would want [2, 1, 1] removed as well, but this hasn't happened. As said, I guess the comparator needs improving, but I'm not sure how!

Mystery_Jay
  • 161
  • 5

1 Answers1

3

You can remove the duplicates with help of the custom comparator via vecsort(_, _, 8). See the MWE below:

all_cycles(v) = [[v[3], v[1], v[2]], [v[2], v[3], v[1]]];

contains(list, value) = {
    #select(n -> n == value, list) > 0
};

\\ your comparator here.
are_cycles(v1, v2) = {
    if(contains(all_cycles(v1), v2), 0, lex(v1, v2));
};


V = [];
vecsort(vecsort(V), are_cycles, 8)
> []

V = all_cycles([1, 2, 3]);
vecsort(vecsort(V), are_cycles, 8)
> [[2, 3, 1]]

V = concat([[1, 2, 3], [3, 2, 1]], all_cycles([1, 2, 3]));
vecsort(vecsort(V), are_cycles, 8)
> [[1, 2, 3], [3, 2, 1]]

V = concat(V, all_cycles([3, 2, 1]));
vecsort(vecsort(V), are_cycles, 8)
> [[1, 2, 3], [1, 3, 2]]

Edit: much easier approach is to substitute each element with the representative of equivalence class it belongs to. Now no custom comparator is required.

all_cycles(v) = [v, cycle(v), cycle(cycle(v))];
representative(v) = vecsort(all_cycles(v))[1];

V=[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 3, 1], [1, 3, 2], [1, 3, 3], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 1], [2, 3, 2], [2, 3, 3], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 3, 1], [3, 3, 2], [3, 3, 3]];

#vecsort(apply(representative, V),,8)
> 11
vecsort(apply(representative, V),,8)
> [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 2], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]
Piotr Semenov
  • 1,761
  • 16
  • 24
  • Thanks! I'm struggling a bit executing this for my specific example though. Under my construction, `cycle([1,0,1]) = [1,1,0]` for example, but I can't seem to remove these types of duplicates. I'd assume this comes down to defining the right sort of comparator, but I can't seem to get that right. How could I potentially go about that? – Mystery_Jay Mar 16 '20 at 14:43
  • Please, update kindly your question with MNWE. It is difficult to see the problem just from text comment. – Piotr Semenov Mar 16 '20 at 18:48
  • Apologises; this has now been added! – Mystery_Jay Mar 17 '20 at 08:01
  • 2
    Please, find my answer updated with solution to your MNWE. – Piotr Semenov Mar 17 '20 at 15:17
  • A more idiomatic construct than vecsort(,,8) would be Set(). – K.B. Aug 15 '21 at 13:22