Я написал фрагмент кода в R, который вычисляет двойную сумму так называемой статистики рангов.R: «векторизация» тройного цикла
Мне нужно повторить вычисление Q минимум 1000 раз, но с 3 петлями внутри, для этого требуется довольно много времени, чтобы сделать это только один раз.
Вот мой код:
#u, a - real numbers
l <- function(u, a) {
-sqrt((1-a)/a)*I(u>=0 & u<a) + sqrt(a/(1-a))*I(u>=a & u<=1)
}
# r,s - real number, R,S - vectors of real numbers (equal lengths)
L<-function(r, s, R, S) {
n<-length(R)
x<-0
for (i in 1:n) {
x<-x+l(R[i]/(n+1),r) * l(S[i]/(n+1),s)
}
1/sqrt(n)*x
}
# r, s, X, Y - vectors of real numbers; X and Y must be equally long
Q<-function(r,s,X,Y) {
n<-length(X)
R<-rank(X)
S<-rank(Y)
q<-0
for (j in 1:length(r)) {
for (k in 1:length(s)) {
q<-q+L(r[j],s[k],R,S)^2
}
}
q
}
я пытался превратить свои функции, используя sapply и применять, но тогда первая функция не удалась, поскольку размеры г и s не могут быть равны (и не должны длины r, s равно длине X (или Y)).
Есть ли способ создать функцию L, которая принимает 4 вектора и создает матрицу, чтобы я избавился от циклов?
Заранее благодарен!
// Edit:
Я написал альтернативную функцию с помощью mapply:
Q1<-function(r,s,X,Y) {
n<-length(X)
R<-rank(X)
S<-rank(Y)
rs <- expand.grid(r,s)
q<-do.call(mapply, c(function(r,s) L(r,s,R=R,S=S)^2, unname(rs)))
sum(q)
}
, но это, кажется, еще медленнее. (.)
Возможно быстрее использовать 'L (R [J], с [K], R, S)^2' вместо вызова функции L дважды, чтобы сделать:' L (г [J], S [ K], R, S) * L (г [J], с [K], R, S) '. Это также быстрее для векторов предпределения и назначения в местоположения, чем для конкатенации. –
Ну, действительно, использование^2 вместо умножения помогло, теперь оно идет почти в 2 раза быстрее, спасибо большое. Я также заменил конкатенацию суммарным суммированием в обеих функциях, он сохранил ок. 0,1 с. Все еще интересно, есть ли способ опустить петли (при условии, что это занимает меньше времени). – xpenguinx
Не уверен, что вы поняли предположение о предварительном измерении. Вы должны отредактировать свой код, чтобы показать, что вы сделали. –