How define a multivariate function in R - r

I have the following function:
I would like to write a function in R for f. It should take as arguments x, c1, ..., cn and n.

If the argument lengths are variable, use 3 dots (...)
f1 <- function(x, ...) {
2 * x + sum((x - c(...))^2)
}
-testing
f1(5, 10, 5, 2, 3)
[1] 48

Related

expression object in R

In R, I can calculate the first-order derivative as the following:
g=expression(x^3+2*x+1)
gPrime = D(g,'x')
x = 2
eval(g)
But I think it's not very readable. I prefer to do something like this:
f = function(x){
x^3+2*x+1
}
fPrime = D(g,'x') #This doesn't work
fPrime(2)
Is that possible? Or is there a more elegant way to do ?
1) D This depends on the particular form of f but for similar ones whose body is one line surrounded by {...} and whose single argument is x and whose operations are in the derivative table this works:
# f is from question
f = function(x){
x^3+2*x+1
}
df <- function(f) {
fun <- function(x) {}
environment(fun) <- environment(f)
body(fun) <- D(body(f)[[2]], "x")
fun
}
df(f)
## function (x)
## 3 * x^2 + 2
2) numDeriv::grad Also consider doing this numerically:
library(numDeriv)
grad(f, 2)
## [1] 14
3) deriv Another approach is to use deriv in the base of R with similar restrictions to (1).
df2 <- function(f) {
fun <- function(x) {
f2 <- deriv(body(f)[[2]], "x", function.arg = TRUE)
attr(f2(x), "gradient")
}
environment(fun) <- environment(f)
fun
}
f2Prime <- df2(f)
f2Prime(2)
## x
## [1,] 14
4) Deriv::Deriv Another apprroach is the Deriv package.
library(Deriv)
Deriv(f, "x")
## function (x)
## 2 + 3 * x^2

How to solve "non-numeric argument.." error in numerical integration?

I want to calculate the following integral in R.
I tried to use Vectorize and integrate functions but I got error
Error in (log(z)) * (InIntegl2) : non-numeric argument to binary operator
fxyz= function(x,y,z) { (x*y*z)+z+x+2*y}
InIntegl1 = Vectorize(function(x) { integrate(fxyz, 0,5)$value})
InIntegl2 = Vectorize(function(y) { integrate( InIntegl1, 0,3)$value})
InIntegl3 = Vectorize(function(z) { integrate((log(z))*(InIntegl2), 2,6)$value})
Integral = integrate(InIntegl3 , 2, 6)$value
The first integral must be parameterized by y and z and the second by z. Then we can perform the final integration.
int1 <- Vectorize(function(y, z) integrate(fxyz, 0, 5, y = y, z = z)$value)
int2 <- Vectorize(function(z) integrate(int1, 0, 3, z = z)$value)
integrate(function(z) log(z) * int2(z), 2, 6)$value
## [1] 2071.71
In the spirit of Numerical Triple Integration in R
integrate(Vectorize(function(z) {
log(z)*integrate(Vectorize(function(y) {
integrate(function(x) { x*y*z +x + 2*y + z}, 0, 5)$value }), 0,3)$value }), 2,6)
Package cubature can solve triple integrals with one call.
library(cubature)
f <- function(X){
x <- X[1]
y <- X[2]
z <- X[3]
log(z)*(x*y*z + x+ 2*y + z)
}
loLim <- c(0, 0, 2)
hiLim <- c(5, 3, 6)
tol <- .Machine$double.eps^0.5
hcubature(f, loLim, hiLim, tol = tol)
#$integral
#[1] 2071.71
#
#$error
#[1] 2.059926e-05
#
#$functionEvaluations
#[1] 165
#
#$returnCode
#[1] 0
If only the integral's value is needed,
hcubature(f, loLim, hiLim, tol = tol)$integral
#[1] 2071.71

Recursive function in R of a sequence

I am trying to write a function that takes X and n, and returns element Xn. X is a vector of the first 3 elements of the sequence and n is a positive integer.
Xn = Xn-1 + Xn-2 - Xn-3
I am not sure how to outline a function like this in R. Can someone outline the creation of a recursive function for the above numerical sequence?
I have been working with something like this:
myfunc <- function(x,n){
if (n<0){
print("please enter positive integer")
} else {
return(myfunc(n-1 + n-2 + n-3))
}
}
myfunc (x = c(1, 2, 3), n = 3) #should return 3 (third number in sequence)
myfunc (x = c(1, 2, 3), n = 4) #should return 6
This isn't a recursive function, but it will give you what you want:
myfunc <- function(x, n) sum(x[n - 1:n])
myfunc(1:3, 3) # 3
myfunc(1:3, 4) # 6

Setting up a Horner polynomial in R

I am trying to set up a function in R that computes a polynomial
P(x) = c1 + c2*x + c3*x^2 + ... + cn-1*x^n-2 + cn*x^n-1
for various values of x and set coefficients c.
Horner's method is to
Set cn = bn
For i = n-1, n-1, ..., 2, 1, set bi = bi+1*x + ci
Return the output
What I have so far:
hornerpoly1 <- function(x, coef, output = tail(coef,n=1), exp = seq_along(coef)-1) {
for(i in 1:tail(exp,n=1)) {
(output*x)+head(tail(coef,n=i),n=1)
}
}
hornerpoly <- function(x, coef) {
exp<-seq_along(coef)-1
output<-tail(coef,n=1)
if(length(coef)<2) {
stop("Must be more than one coefficient")
}
sapply(x, hornerpoly1, coef, output,exp)
}
I also need to error check on the length of coef, that's what the if statement is for but I am not struggling with that part. When I try to compute this function for x = 1:3 and coef = c(4,16,-1), I get three NULL statements, and I can't figure out why. Any help on how to better construct this function or remedy the null output is appreciated. Let me know if I can make anything more clear.
How about the following:
Define a function that takes x as the argument at which to evaluate the polynomial, and coef as the vector of coefficients in decreasing order of degree. So the vector coef = c(-1, 16, 4) corresponds to P(x) = -x^2 + 16 * x + 4.
The Horner algorithm is implemented in the following function:
f.horner <- function(x, coef) {
n <- length(coef);
b <- rep(0, n);
b[n] <- coef[n];
while (n > 0) {
n <- n - 1;
b[n] <- coef[n] + b[n + 1] * x;
}
return(b[1]);
}
We evaluate the polynomial at x = 1:3 for coef = c(-1, 16, 4):
sapply(1:3, f.horner, c(-1, 16, 4))
#[1] 19 47 83
Some final comments:
Note that the check on the length of coef is realised in the statement while (n > 0) {...}, i.e. we go through the coefficients starting from the last and stop when we reach the first coefficient.
You don't need to save the intermediate b values as a vector in the function. This is purely for (my) educational/trouble-shooting purposes. It's easy to rewrite the code to store bs last value, and then update b every iteration. You could then also vectorise f.horner to take a vector of x values instead of only a scalar.

How to sum values printed by print() in R

T <- function (p,q) {
for (x in 1:3) {
for (y in 1:3) {
sum(p*x + q*y)
print(sum(p*x + q*y))
}
}
}
sum(T(2,2))
I want the sum of 4, 6, 8, 6, 8, 10, 8, 10, 12 which is the output of the loop where p=2 and q=2 but the result is
sum(T(2,2))
[1] 4
[1] 6
[1] 8
[1] 6
[1] 8
[1] 10
[1] 8
[1] 10
[1] 12
Is there any way that I can get the sum or change the printed value to a vector rather than a list of each value? sum() function doesn't work on printed value.
Printing to the screen does exactly that; it doesn't return the value printed to the calling code. Your function needs to build a vector and return that. Here's a few different ways of doing it:
Code along the lines of what you were trying to do, but starting with an empty numeric vector and building it for each iteration:
T1 <- function(p, q) {
out <- numeric(0)
for (x in 1:3) {
for (y in 1:3) {
out <- c(out, p * x + q * y)
}
}
out
}
Preassigning the vector size and assigning to specific members of the vector
T2 <- function(p, q) {
out <- numeric(3 ^ 2)
for (x in 1:3) {
for (y in 1:3) {
out[(x - 1) * 3 + y] <- p * x + q * y
}
}
out
}
Using one of the map functions in purrr (overkill here but can be extended to functions which don't easily vectorise)
library(purrr)
T3 <- function(p, q) {
map2_dbl(rep(1:3, each = 3), rep(1:3, 3), function(x, y) p * x + q * y)
}
Using vector arithmetic to return the result in one command
T4 <- function(p, q) {
rep(1:3, each = 3) * p + rep(1:3, 3) * q
}
Using outer to achieve the same as T4 (as per #alistaire's comment):
T5 <- function(p, q) {
c(outer(1:3 * p, 1:3 * q, `+`))
}
It should be noted that the efficiency of these method will vary as the size of the loops increases, but that in general method 4 will be the most efficient closely followed by method 5. For small loops, interestingly method 1 seems to be better than 2, but 1 becomes inefficient as the loop size increases because R has to move memory around to keep increasing the size of the vector.

Resources