RobinHankin / permutations

https://robinhankin.github.io/permutations/
5 stars 3 forks source link

sapply does not really work #9

Open stla opened 5 years ago

stla commented 5 years ago

Hello,

I find a bit annoying that does not work:

library(permutations)
perms <- allperms(4)
sapply(perms, function(perm) prod(sgn(perm)))

To get the desired result, I have to do: sapply(1:24, function(i) prod(sgn(perms[i])))

RobinHankin commented 5 years ago

hello, thanks for this. I'm not sure what you are desiring here. I would do

> sgn(allperms(4))
 [1]  1 -1 -1  1  1 -1 -1  1  1 -1 -1  1  1 -1 -1  1  1 -1 -1  1  1 -1 -1  1

which gives the same result as your second idiom.

stla commented 5 years ago

Ok, this works like this for this example. But imagine another function f <- function(perm) ........ Then the sapply(perms, f) will not work. This is a strange behavior, no ?

stla commented 5 years ago

Take for example:

x <- 1:4
sapply(1:24, function(i) x[perms[i]]) # correct
sapply(perms, function(perm) x[perm]) # wrong

I find this strange because perms = c(perms[1], ...., perms[24]). This should give the same result.

By the way, AFAIK there's no function to apply a permutation to a vector (something instead of doing x[perm]).

RobinHankin commented 5 years ago

Hello, I'm still thinking about your sapply() question, but as for the x[perm] thing, this is why I wrote the package in the first place! Check this out:

> P <- as.cycle("(139)(2456)")
> P
(139)(2456) 
(139)(2456) 
> letters[1:9][as.word(P)]
[1] "c" "d" "i" "e" "f" "b" "g" "h" "a"
> 
> 
> options(print_word_as_cycle = FALSE)
> as.word(P)
            {1} {2} {3} {4} {5} {6} {7} {8} {9}
(139)(2456) 3   4   9   5   6   2   .   .   1  
> 
RobinHankin commented 5 years ago

The package uses two distinct representations for permutations, cycle or word. The default print method obscures this (introduced at the request of a peer review, against my better judgment). Anyway, if you coerce an object p to word form then apply(p,1,f) should work. For example;

R> apply(allperms(4),1,function(x){sum(x[1:2])})
[1] 3 3 4 4 5 5 3 3 5 5 6 6 4 4 5 5 7 7 5 5 6 6 7 7

Cycle objects are a little trickier because these are lists of lists.

R> pp <- as.cycle(rperm(3,8)) 
R> class(pp) [1] "permutation" "cycle"  
R> sapply(pp,function(x){x}) 
[[1]] 
[[1]][[1]]
[1] 1 8 6 3 7 5 2

[[2]]
[[2]][[1]]
[1] 1 8 3 4 6 2 5 7 

[[3]]
[[3]][[1]]
[1] 2 4 8 6

[[3]][[2]]
[1] 3 5 7

Does this help?