2

With PARI/GP, if I have a vector with unique entries:

a = [9, 7, 3, 5, 2, 8, 1, 0, 11]

how do I get the position (index) of an entry in the vector a?

like:

i = vectorsearch(a, 8);
a[i]

%1 = 8

Converting into a set and using setsearch doesn't work!

Piotr Semenov
  • 1,761
  • 16
  • 24
Ystar
  • 351
  • 1
  • 3
  • 8

3 Answers3

3

Just do select((x) -> x == 8, a, 1) where flag 1 means the "index mode". In general, your function is as shown below.

position = (elt, array) -> select((x) -> x == elt, array, 1);

Please note, despite the fact that this stuff does a lambda call per each element of the array, that is very efficient. This lead to nice run-time for small/big arrays.

To prove the efficiency, we do the simple performance tests to evaluate the position and its DIY-competitor looking just for the position of first occurrence.

position1 = (elt, array) -> for(i = 1, #array, if(array[i] == el, return(i)));

a = vector(100, i, random(200));
{ gettime(); for(i = 1, 10^4, position(8, a)); gettime() }
{ gettime(); for(i = 1, 10^4, position1(8, a)); gettime() }

This gives 87ms and 198ms correspondingly for PARI/GP 2.7.2 running at Windows 8 64bit, Intel i7-4702MQ CPU @ 2.20GHz

Piotr Semenov
  • 1,761
  • 16
  • 24
0

you may try:

position = select(x->x==8,a,1)[1];
ej8000
  • 141
  • 1
  • 6
0

If you need many calls to this function, pre-sorting the vector is the best option:

    a = [9, 7, 3, 5, 2, 8, 1, 0, 11];
    p = vecsort(a,, 1);    \\ permutation sorting a
    A = vecextract(a, p); \\ A = vecsort(a)
    position2(n) = p[vecsearch(A,n)];

    ? position2(8)
    %1 = 6

For simplicity, I used global variables and I didn't cater for missing entries (need to check whether vecsearch returns 0). And I also assume the inputs are real numbers (if not, use the universal vecsort(a, cmp, 1) instead of the default comparison function).

Using Piotr's benchmark:

position = (elt, array) -> select((x) -> x == elt, array, 1);
position1 = (elt, array) -> for(i = 1, #array, if(array[i] == el, return(i)));
a = vector(100, i, random(200));
position2(n) = p[vecsearch(A,n)];

? for(i = 1, 10^5, position(8, a));
time = 586 ms.
? for(i = 1, 10^5, position1(8, a));  
time = 1,644 ms.
? for(i = 1, 10^5, position2(8)); 
time = 29 ms.
K.B.
  • 861
  • 5
  • 14