Return integrated function using R - r

Let's say i have a function defined as the following in R:
> f <- function(x) 0.5*sin(x)*(x>=0)*(x<=pi)
i can do this to integrate it between 0 and pi:
> Integrate <- function(f,a,b) integrate(Vectorize(f),a,b)$value
> F <- Integrate(f,0,pi)
But if i want to evaluate and return some values of F i get this error:
> F(c(-100,0,1,2,pi,100))
Error in F(c(-100, 0, 1, 2, pi, 100)) :
function "F" is not found
i can understand that this is due to the fact, that my integrate <- function(f,a,b) returns a constant value C which is the result of the integration of f between a and b, but how can i return F as a function to be able to evaluate it's values as a vector and plot it ?
like in this case F should give 0 for any value less than 0 and 1 for any value bigger than pi and be variable between them.
Thanks.
Edit: just to sum it up more clearly: how can i define a function f(x) in [a,b] that will give me f(x) if x is in [a,b], 0 if xb ?

Try wrapping your function call in an sapply and have Integrate return a function.
Integrate <- function(f, a, b) function(x) if (x < a) 0 else if (x > b) 1 else integrate(Vectorize(f), a, x)$value
F <- Integrate(f, 0, pi)
sapply(c(-100,0,1,2,pi,100), F)
gives
[1] 0.0000000 0.0000000 0.2298488 0.7080734 1.0000000 1.0000000

Related

Is there a R function to derive a "kink"

Suppose I have a function with a kink. I want to derive a kink point, which in this case is 0.314. I tried optim but it does not work.
Here is an example. In general, I want to derive c. Of course, I could use brute force, but it is slow.
# function with a kink
f <- function(x, c){
(x >= 0 & x < c) * 0 + (x >= c & x <=1) * (sin(3*(x-c))) +
(x < 0 | x > 1) * 100
}
# plot
x_vec <- seq(0, 1, .01)
plot(x_vec, f(x_vec, c = pi/10), "l")
# does not work
optim(.4, f, c = pi/10)
This function has no unique minimum.
Here, a trick is to transform this function a little bit, so that its kink becomes a unique minimum.
g <- function (x, c) f(x, c) - x
x_vec <- seq(0, 1, 0.01)
plot(x_vec, g(x_vec, c = pi/10), type = "l")
# now works
optim(0.4, g, c = pi/10, method = "BFGS")
#$par
#[1] 0.3140978
#
#$value
#[1] -0.3140978
#
#$counts
#function gradient
# 34 5
#
#$convergence
#[1] 0
#
#$message
#NULL
Note:
In mathematics, if we want to find something, we have to first define it precisely. So what is a "kink" exactly? In this example, you refer to the parameter c = pi / 10. But what is it in general? Without a clear definition, there is no algorithm/function to get it.

Iteration of a recurrence solution in R

I'm given a question in R language to find the 30th term of the recurrence relation x(n) = 2*x(n-1) - x(n-2), where x(1) = 0 and x(2) = 1. I know the answer is 29 from mathematical deduction. But as a newbie to R, I'm slightly confused by how to make things work here. The following is my code:
loop <- function(n){
a <- 0
b <- 1
for (i in 1:30){
a <- b
b <- 2*b - a
}
return(a)
}
loop(30)
I'm returned 1 as a result, which is way off.
In case you're wondering why this looks Python-ish, I've mostly only been exposed to Python programming thus far (I'm new to programming in general). I've tried to check out all the syntax in R, but I suppose my logic is quite fixed by Python. Can someone help me out in this case? In addition, does R have any resources like PythonTutor to help visualise the code execution logic?
Thank you!
I guess what you need might be something like below
loop <- function(n){
if (n<=2) return(n-1)
a <- 0
b <- 1
for (i in 3:n){
a_new <- b
b <- 2*b - a
a <- a_new
}
return(b)
}
then
> loop(30)
[1] 29
If you need a recursion version, below is one realization
loop <- function(n) {
if (n<=2) return(n-1)
2*loop(n-1)-loop(n-2)
}
which also gives
> loop(30)
[1] 29
You can solve it another couple of ways.
Solve the linear homogeneous recurrence relation, let
x(n) = r^n
plugging into the recurrence relation, you get the quadratic
r^n-2*r^(n-1)+r^(n-2) = 0
, i.e.,
r^2-2*r+1=0
, i.e.,
r = 1, 1
leading to general solution
x(n) = c1 * 1^n + c2 * n * 1^n = c1 + n * c2
and with x(1) = 0 and x(2) = 1, you get c2 = 1, c1 = -1, s.t.,
x(n) = n - 1
=> x(30) = 29
Hence, R code to compute x(n) as a function of n is trivial, as shown below:
x <- function(n) {
return (n-1)
}
x(30)
#29
Use matrix powers (first find the following matrix A from the recurrence relation):
(The matrix A has algebraic / geometric multiplicity, its corresponding eigenvectors matrix is singular, otherwise you could use spectral decomposition yourself for fast computation of matrix powers, here we shall use the library expm as shown below)
library(expm)
A <- matrix(c(2,1,-1,0), nrow=2)
A %^% 29 %*% c(1,0) # [x(31) x(30)]T = A^29.[x(2) x(1)]T
# [,1]
# [1,] 30 # x(31)
# [2,] 29 # x(30)
# compute x(n)
x <- function(n) {
(A %^% (n-1) %*% c(1,0))[2]
}
x(30)
# 29
You're not using the variable you're iterating on in the loop, so nothing is updating.
loop <- function(n){
a <- 0
b <- 1
for (i in 1:30){
a <- b
b <- 2*i - a
}
return(a)
}
You could define a recursive function.
f <- function(x, n) {
n <- 1:n
r <- function(n) {
if (length(n) == 2) x[2]
else r({
x <<- c(x[2], 2*x[2] - x[1])
n[-1]
})
}
r(n)
}
x <- c(0, 1)
f(x, 30)
# [1] 29

How to Code a Recursive Function by Vector in R?

I have a function : (1 - (x / d))
which d is members of a vector (V)
Based on length of the vector, a function will be like this:
for example vector is V [2, 3.5, 5, 4.1]
so the function would be:
[(1-(x/2))*(1-(x/3.5))*(1-(x/5))*(1-(x/4.1))]
if I give it an other vector like [1.5, 2] function would be:
[(1-(x/1.5))*(1-(x/2))]
that means the function's shape depends on length of my vector and its elements.
I want a code to create this function and then find its maximum by optimize in R.
Here is a way. Function f returns a function that can be applied to a vector x.
f <- function(d) {
force(d)
function(x) prod(1 - x/d)
}
d <- c(1.5, 2)
g <- f(d)
sapply(1:5, g)
#[1] 0.1666667 0.0000000 0.5000000 1.6666667 3.5000000

understand and modify previous R code

I am new to R environment and would like the understand the code posted in another thread.
Integrating over a PCHIP Function
1 > library(pracma)
2 > xs <- linspace(0, pi, 10)
3 > ys <- sin(xs)
4 > pchipfun <- function(xi, yi) function(x) pchip(xi, yi, x)
5 > f <- pchipfun(xs, ys)
6 > integrate(f, 0, pi)
My questions are as follows:
Line 5 is calling function in line 4, but this is not passing x value. So how does line 4 take x value?
In the above setup, I would like to modify such that if x is in between pi/6 & pi/4, the function should return 0 otherwise return calculated value.
Thanks in advance.
For question 1, you can read about Currying:
https://en.wikipedia.org/wiki/Currying
For question 2, perhaps you can paste what you have tried first.

How to define a constant in R

Let me describe the problem setting. The function I am depicting is a probability function and upon integration it's value would have to be equal to 1. So I will be dividing the result of the integration by 1 to give the value of C. So I can't assign value to C.
Have a look at the below code and error message -
> f <- function(x) (C*x*(exp(-x)))
> z=integrate(f, lower = 0, upper=Inf)
Error in C * x : non-numeric argument to binary operator
How am I supposed to define C here ?
Second Question- Can somebody figure what's wrong with value of z?
> f <- function(x) (x*(exp(-x)))
> z=integrate(f, lower = 0, upper=Inf)
> z
1 with absolute error < 6.4e-06
> 1/z
Error in 1/z : non-numeric argument to binary operator
Make C = 1 for when you compute the integral of the function. For that, you can make it an optional argument to your function with a default value:
f <- function(x, C = 1) C * x * exp(-x)
Then, compute:
z <- integrate(f, lower = 0, upper = Inf)
For the integral to be 1 with the real value for C, you need C * z == 1, i.e.:
C <- 1 / z$value
C
# [1] 1
As it turns out, the integral z is already equal to 1 so picking C = 1 was a lucky choice. You have nothing to do and you can just start using f as-is. Had it not been the case, I would have suggested to redefine f:
f_final <- function(x) f(x, C = 1 / z$value)
(Regarding your second question, you just had to look at the documentation for ?integrate and refer to the "Value" section.)

Resources