R - creating a function f(x) as a sum indexed by n - r

Is it possible in R to write a function f(x) like
f(x) = a_0 + a_1*sin(x) + ... + a_n*sin(n*x)
for some n, or any other f_i(x) in place of sin(i*x) just varying on i? I tried a recursion like
f <- function(x) a_0
for(n in 1:N)
f <- function(x) f(x) + a_n*x^n
It seemed to work but when I used f(x) to make some computations R said there was too much nesting. I eventually wrote by hand a_0 + a_1*x + ... etc.
Is there a proper way to do it in a compact way without using recursion?

If you have the following values of a and x
a <- 1:5
x <- 3
a[1] + a[2]*sin(x*1) + a[3]*sin(x*2) + a[4]*sin(x*3) + a[5]*sin(x*4)
# [1] -0.5903971
Then you can get the same value using
f <- function(x) {
a[1] + sum( a[-1] * sin((x * seq.int(length(a)-1) )))
}
f(x)
#[1] -0.5903971
Note that arrays in R use 1-based indexing

Related

Evaluating a multivariable function with constraints

I have a function f(x,y) where both the inputs are integers. Given a natural number K, I would like to evaluate f at all points in the set { (x,y) : 0 <= x <= K-1 , x < y <= K }. In other words, evaluating f at all feasible 0 <=x,y <= K which satisfy y>x.
I know this can be done with nested for loops but I am wondering if there is a more efficient way to do it through one of the apply functions perhaps.
Here is one way of doing what the question asks for. It's a simple double *apply loop with a function call in the inner most loop.
f <- function(x, y) {x + y + x*y}
K <- 10
sapply(0:(K - 1), function(x){
sapply((x + 1):K, function(y) f(x, y))
})
This is easily rewritten as a function of K and f.
fun <- function(K, FUN){
f <- match.fun(FUN)
lapply(0:(K - 1), function(x){
sapply((x + 1):K, function(y) f(x, y))
})
}
fun(10, f)

Finding derivate of function in R

I am using R and trying to make an function by giving 2 parameters which are function and x, try to look for the answer of the function. But I kept getting error. I do not want to use any packages just solely R base.
Heres the Code so far.
test2 <- function(x) {
func <- expression(x)
der<- D(eval(func), 'x')
return(der(x))
}
test2(function(x) return(x^2))
I kept getting this error: "expression must not be type 'closure'"
Is there any way that I can structure of the function?
Here's a slight adjustment to get the derivation function working:
test2 <- function(x) D(parse(text=x), "x")
test2("sin(cos(x + y^2))")
# -(cos(cos(x + y^2)) * sin(x + y^2))
test2("x^2")
# 2 * x
test2("x^3")
# 3 * x^2
Use substitute to pass the expression to D:
test2 <- function(e, d) D(substitute(e), deparse(substitute(d)))
test2(sin(cos(x + y^2)), x)
#-(cos(cos(x + y^2)) * sin(x + y^2))
You cannot pass a function to D since it's designed for creating derivatives symbolically, which means it needs expressions containing simple functions known to D.
The function f returns a character vector, and string_der gives the derivative. (I used string manipulation inside since it seems you want to pass an argument.)
string_der <- function(x) {
D(parse(text = x), "x")
}
library(stringr)
f <- function(x) {
str <- "sin(cos(z + y^2))"
str <- str_replace(str, "z", x)
return(str)
}
string_der(f(x = "x"))
# -(cos(cos(x + y^2)) * sin(x + y^2))
I guess following is pretty much Adam Queck has done. It uses quote and let's you pass an object wrapped in quote.
quote_der <- function(x) {
D(eval(x), 'x')
}
f <- function(x) {
qt <- substitute(expression(sin(cos(z + y^2))), list(z = x))
return(qt)
}
quote_der(f(x = quote(x)))
#-(cos(cos(x + y^2)) * sin(x + y^2))
Assuming that:
the function passed as the argument has a one-line body and
if x is not specified it defaults to the name of the first argument to the input function
then we can write
test3 <- function(fun, x = names(formals(fun))[1]) D(body(fun), x)
test3(function(x) x^2)
## 2 * x

non-numeric argument to binary operator, AR(1) model

I have an exercise to do where I have to run the following AR(1) model:
xi =c+φxi−1+ηi (i=1,...,T)
I know that ni ~ N(0,1) ; x0 ~ N(c/(1-φ),1/(1-φˆ2)); c= 2 ; φ = 0.6
I am trying to do a for loop. My code is the following:
n <- rnorm(T, 0, 1)
c <- 2
phi <- 0.6
x_0 <- rnorm(1,c/(1-phi), 1/(1-phi**2))
v <- vector("numeric", 0)
#for (i in 2:T){
name <- paste("x", i, sep="_")
v <- c(v,name)
v[1] <- c + phi*x_0 + n[1]
v[i] <- c + phi*v[i-1] + n[i]
}
However, I keep getting this error:
Error in phi * v[i - 1] : non-numeric argument to binary operator
I understand what this error is, but I can't find any solutions to solve it. Could someone please enlighten me? How could I assign numeric values to the name vector?
Thank you!
You're defining v as a numeric vector, but then v <- c(v, name) turns v into a character vector since name is character. That's what's causing the error.
If I'm not mistaken, your intent is to assign names to the values in a numeric vector. That's fine, you just need a different approach.
n <- rnorm(t)
c <- 2
phi <- 0.6
x_0 <- rnorm(1, c/(1-phi), 1/(1-phi^2))
v <- c + phi*x_0 + n[1]
for (i in 2:t) {
v[i] <- c + phi*v[i-1] + n[i]
}
names(v) <- paste("x", 1:t, sep="_")
Vectors in R don't have a static size; they're dynamically resized as needed. So even though we're initializing v with a scalar value, it grows to fit each new value in the loop.
The final step is to give v a list of names. This can be accomplished using names(v) <-. Take a look at v now--it has names!
And as an aside, since T is a synonym for TRUE in R, it's best not to use T as a variable name. Thus I've used t here instead.
I guess you seem to need the following. It'll produces 11 elements including the initial x value. You may exclude it later.
set.seed(1237)
t <- 10
n <- rnorm(t, 0, 1)
c <- 2
phi <- 0.6
x0 <- rnorm(1, c/(1-phi), 1/(1-phi**2))
v <- c(x0, rep(0, t))
for(i in 2:length(v)) {
v[i] <- c + phi * v[i-1] + n[i-1]
}
v
[1] 4.967833 4.535847 2.748292 2.792992 5.389548 6.173001 4.526824 3.790483 4.307981 5.442913 4.958193

Integrating over a PCHIP Function

How can I integrate over a PCHIP (Piecewise Cubic Hermite Interpolation Polynomial) function in R? pchip {pracma} returns interpolated point data, and to integrate we of course need a function. I see under the help menu for pchip(), "TODO: A `pchipfun' should be provided," I don't know how hard this would be to generate manually? Any other suggestions? You could fit an nth degree polynomial regression to the interpolated points and integrate off that to get a rough approximation, but that gets messy pretty quick...
Here's the source code for pchip {pracma} which returns points and not a function, I suppose returning a function is more of a math question not an R question, but I'm open for any and all suggestions! Please!
function (xi, yi, x)
{
h <- diff(xi)
delta <- diff(yi)/h
d <- .pchipslopes(h, delta)
n <- length(xi)
a <- (3 * delta - 2 * d[1:(n - 1)] - d[2:n])/h
b <- (d[1:(n - 1)] - 2 * delta + d[2:n])/h^2
k <- rep(1, length(x))
for (j in 2:(n - 1)) {
k[xi[j] <= x] <- j
}
s <- x - xi[k]
v <- yi[k] + s * (d[k] + s * (a[k] + s * b[k]))
return(v)
}
Thanks!
What does not work for you? You have to define a function using pchipfun() like this:
> library(pracma)
> xs <- linspace(0, pi, 10)
> ys <- sin(xs)
> pchipfun <- function(xi, yi) function(x) pchip(xi, yi, x)
> f <- pchipfun(xs, ys)
> integrate(f, 0, pi)
2.000749 with absolute error < 0.00017
I have updated pracma 1.7.2 on R-Forge to include pchipfun()
and added some error checking to pchip().

Summing over a range of value in R (not using for loop)

How do you perform such summation in R?
sum_{i=1}^3 (x^2)
i=1 is lower bound
i=3 is upper bound
x^2 is the operation
So we will perform
1^2 + 2^2 + 3^2
Using standard loop:
tot <-0
for (x in 1:3) {
tot <- tot + x^2
}
First, I'll point out that to generate a vector containing the elements 1,2,3 you can do:
x <- 1:3
Secondly, R is a vectorised language - meaning if x is a vector and I do x + 5 it'll add 5 to each element of x for me without needing a for loop.
# Recalling that "x <- x + 5" is the same as
for ( i in 1:length(x) ) {
x[i] <- x[i] + 5
}
# try to do something that makes x squared, i.e. x == c(1,4,9).
Thirdly, look at ?sum, whereby sum(x) adds up all the elements in x.
the_answer <- sum( (1:3)^2 )
For-loops are so last century.

Resources