How to convolve a vector with itself n times - r

Suppose I have a vector x which I want to convolve with itself n times. What is the good way to do this in R?
Suppose that we already have a function conv(u,v) that convolves two vectors.
I can do this:
autoconv<-function(x,n){
r<-1;
for(i in 1:n){
r<-conv(r,x);
}
return(r);
}
is there a more efficient way?

Take the Fast Fourier Transform (fft) of x, raise it to the kth power and take the inverse fft. Then compare that to performing convolutions of k copies of x. No packages are used.
# set up test data
set.seed(123)
k <- 3 # no of vectors to convolve
n <- 32 # length of x
x <- rnorm(n)
# method 1 using fft and inverse fft
yy <- Re(fft(fft(x)^k, inverse = TRUE) / n)
# method 2 using repeated convolutions
y <- x
if (k >= 2) for(i in 2:k) y <- convolve(x, y, FALSE)
# check that the two methods give the same result
all.equal(y, yy)
## TRUE

autoconv <- function(x, n){
if(n == 0){
return(1)
} else if(n == 1){
return(x)
} else {
i <- 2
xi <- conv(x,x)
while(n %% i != 0){
i <- i + 1
xi <- conv(xi,x)
}
return(autoconv(xi,n/i))
}
}
This will call conv() once for each prime factor of n, rather than n times.

Related

For loop in r using summation

I have this,
sum(x^i)
with i being greater than or equal to 1.
How can I create a for loop in R for this summation?
In other words, how do I format this summation in R?
If both x and i are vectors you may use for loop as -
x <- 1:10
i <- 1:10
result <- 0
for(e in i) {
result <- result + sum(x^e)
}
result
If any of x or i goes to infinity, then the result would always be infinity.
For a fixed x and infinite n,
x <- 0.1 # You may change x
s <- 0
n <- 0
while(n < 100) { #If you want inf, let n >=0 then R will freeze recommend large number...
s <- s + x^(n)
n<-n+1
}
s

Simulating given probability density function in R

The following p.d.f is given:
f(x)=2x/k^2, where 0 <= x <= k
Let k=10, I'm trying to simulate 100 times for this p.d.f, then print the first 5 results and find the mean for all 100 times results.
If you want to simulate with a uniform distribution between 0 and k, then you can pass runif(n, min, max) into your pdf.
f <- function(x, k) {
return(2*x/k^2)
}
k <- 10
res <- f(runif(100, 0, k), k)
print(res[1:5])
print(mean(res))
Per MrFlick's comments, if you were instead wanting to do inverse transform sampling, this should suffice.
pdf <- function(x, k) {
return(2*x/k^2)
}
cdf <- function(x, k){
return(x^2/k^2)
}
icdf <- function(y, k){
return(sqrt(k^2*y))
}
k <- 10
res <- icdf(runif(100,0,1), k)
print(res[1:5])
print(mean(res))

R: populating an array from lists

I have a function f(x, y) that returns a list of 8 logical vectors, where x and y are integers. I want to populate a three-dimensional array M so that M[x, y, z] is the number of TRUEs in the zth element of f(x, y). I can do this with nested for loops, but I know those are frowned upon in R. I think there's a more elegant way, using either outer or rbind and sapply but I can't figure it out. Here's my code with the nested for loops:
M <- array(dim=c(150, 200, 8))
for(j in 1:150) {
for(k in 1:200) {
rsu <- f(j, k)
for(z in 1:8) {
M[j, k, z] <- sum(rsu[[z]])
}}}
What is a more efficient/elegant way of populating this array that gives the same result?
Edited to add: For purposes of this question, treat f as a black box. In reality it involves various calculations and lookups about eight different satellites, but here's a dummy function that will generate some data for this example:
is.prime <- function(n) n == 2L || all(n %% 2L:ceiling(sqrt(n)) != 0)
#source for is.prime function:
# https://stackoverflow.com/questions/19767408/prime-number-function-in-r
f <- function(x,y) {
retlist <- list()
retlist[[1]] <- c(FALSE, FALSE, rep(TRUE, x))
retlist[[2]] <- c(TRUE, TRUE, rep(FALSE, y), rep(TRUE, y))
retlist[[3]] <- c(is.prime(x), is.prime(y), is.prime(x+y), is.prime(x+y+3), sapply(x:(2*(x+y)), is.prime))
retlist[[4]] <- c(x+y %% 5 == 0, x*y %% 6 ==0)
retlist[[5]] <- retlist[[(x+y) %% 4 + 1]]
retlist[[6]] <- retlist[[y %% 4 + 1]]
retlist[[7]] <- retlist[[x %% 6 + 1]]
retlist[[8]] <- sapply(abs(x-y):(7L*x+y+1), is.prime)
return(retlist)
}
Here's how to the populate the array, giving the same results, using nested functions and sapply instead of for:
f2 <- function(x,y) {
rsu <- f(x,y)
values <- vapply(1:8, FUN=function(z) sum(rsu[[z]]), FUN.VALUE=1L)
}
f3 <- function(x) array(data=t(sapply(1:200, FUN=function(w) f2(x,w))), dim=c(1,200,8))
M2 <- array(data=t(sapply(1:150, FUN=f3)), dim=c(150,200,8))
Here's how to do it with outer. But it's unintuitive; the matrix data are assigned within the function. I don't understand why I need to invoke Vectorize(f2) here instead of simply f2.
M2 <- array(dim=c(150, 200, 8))
f2 <- function(x, y) {
rsu <- f(x, y)
M2[x, y, ] <<- vapply(1:8, FUN=function(z) sum(rsu[[z]]), FUN.VALUE=1L)
return(0L)
}
ABC <- outer(1:150, 1:200, Vectorize(f2))

General code for a summation in R

I'm writing some code in R and I came across following problem:
Basically, I want to calculate a variable X[k], where X takes on values for each k, like this:
where A is a known variable which takes on different values for each index.
For the moment, I have something like this:
k <- NULL
X <- NULL
z<- 1: n
for (k in seq(along =z)){
for (j in seq (along = 1:k)){
X[k] = 1/k*sum(A[n-k]/A[n-j+1])
}
}
which can't be right. Any idea on how to fix this one?
As always, any help would be dearly appreciated.
Try this
# define A
A <- c(1,2,3,4)
n <- length(A)
z <- 1:n
#predefine X (don't worry, all values will be overwritten, but it will have the same length as A
X <- A
for(k in z){
for(j in 1:k){
X[k] = 1/k*sum(A[n-k]/A[n-j+1])
}
}
You don't need to define z, it is only used inside the for. In this case, do for(k in 1:n){
As
You can do the following
set.seed(42)
A <- rnorm(10)
k <- sample(length(A), 4)
calc_x <- function(A, k){
n <- length(A)
c_sum <- cumsum(1/rev(A)[1:max(k)])
A[n-k]/k * c_sum[k]
}
calc_x(A,k)
what returns:
[1] 0.07775603 2.35789999 -0.45393983 0.13323284

Function that returns itself in R?

In Lambda calculus, Y -combinator returns itself like this Y a = a Y a, specifially here. Suppose some trivial function such as y(x)=2*x+1 (suppose Church numbers for the sake of simplicity) and I want to do it Y y to which I want some sort of break-out -function. I want to do something like this
calculate y(1) --->3
calculate y(3) --->7
calculate y(7) ...
...
terminate on the n-th case
How can I do this in R using the functional way of thinking? Is there something built-in?
I don't really understand the notation of the lambda calculus, so can't know for sure what the Y-combinator is, but I wonder if the R function Recall() (help page here) wouldn't help you build what you're after. Here is an example of its use to calculate a factorial:
# Calculate 4!
(function(n) {if (n<=1) 1 else n*Recall(n-1)})(4)
And here it is applied to the example you described:
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=1)
# [1] 1
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=2)
# [1] 3
(function(x, n) {if (n<=1) x else Recall(2*x+1, n-1)})(x=1, n=3)
# [1] 7
Try this:
myfun = function(x) { 2*x+1 }
N = 10; seed = 3; i = 1
for(i in 1:N){
seed = Y = myfun(seed)
print(Y)
}
If you just want a function, g, that transforms a function f
into function(x) f(f(f(f(...f(x))))) (n times, with n not known in advance),
the following should do.
compose_with_itself_n_times <- function(f,n) {
function(x) {
for(i in seq_len(n)) {
x <- f(x)
}
x
}
}
f <- function(x) 2*x+1
g <- compose_with_itself_n_times(f,10)
g(1)

Resources