How to optimize multiple arrays in R? - r

I need minimize a funtion based in Hsieh Model, using R language. The main objective is to minimize a distance function that depends on a set of other functions.
obj = function(x1){
s = sf()
h_til = h_tilf()
w_til = w_tilf(x1)
w_r = w_rf()
p_ir = p_irf()
#H_tr = H_trf(x1)
W = Wf(x1)
f1 = matrix(0, i, r)
f2 = matrix(0, i, r)
for (c in 1:i){
for (j in 1:r){
f1[c, j] = ( (W[c, j] - W_t[c, j]) / W_t[c, j] ) ** 2
f2[c, j] = ( (p_ir[c, j] - p_t[c, j]) / p_t[c, j] ) ** 2
}
}
d1 = sum(f1)
d2 = sum(f2)
D = d1 + d2
return(D)
}
Therefore, my algorithm must find three parameters (w, tau_w, tau_h) that minimize this distance function. These three parameters are arrays with i rows and r columns. Given by:
w = runif(i*r, 0, 1)
tau_w = runif(i*r, -1, 1)
tau_h = runif(i*r, -1, 1)
x1 = array( c(tau_w, tau_h, w), dim = c(i, r, 3))
I trying solve this using optimx and Rsolnp libraries.
res = optim(x1, #starting values
obj) #function to optimise
But i get this error:
Error in x1[c, j, 1] : incorrect number of dimensions
This minimization is usually done using the Nelder-Mead algorithm.
I'm beginner in optimization and apreciate any help. My complete code is here.

The dimensions of the array x1 are lost when you do optim(x1, obj). So the error you get is returned by w_tilf(x1) because it involves x1[c,j,1].
Reconstruct the array at the beginning of the obj function:
obj = function(x1){
x1 = array(x1, dim = c(i, r, 3))
s = sf()
......
}
Then opt <- optim(x1, obj) should work now. It will return the solution in the opt$par field as a vector, you will have to do array(opt$par, dim = c(i, r, 3)) to get an array.

Related

Double integration with a differentiation inside in R

I need to integrate the following function where there is a differentiation term inside. Unfortunately, that term is not easily differentiable.
Is this possible to do something like numerical integration to evaluate this in R?
You can assume 30,50,0.5,1,50,30 for l, tau, a, b, F and P respectively.
UPDATE: What I tried
InnerFunc4 <- function(t,x){digamma(gamma(a*t*(LF-LP)*b)/gamma(a*t))*(x-t)}
InnerIntegral4 <- Vectorize(function(x) { integrate(InnerFunc4, 1, x, x = x)$value})
integrate(InnerIntegral4, 30, 80)$value
It shows the following error:
Error in integrate(InnerFunc4, 1, x, x = x) : non-finite function value
UPDATE2:
InnerFunc4 <- function(t,L){digamma(gamma(a*t*(LF-LP)*b)/gamma(a*t))*(L-t)}
t_lower_bound = 0
t_upper_bound = 30
L_lower_bound = 30
L_upper_bound = 80
step_size = 0.5
integral = 0
t <- t_lower_bound + 0.5*step_size
while (t < t_upper_bound){
L = L_lower_bound + 0.5*step_size
while (L < L_upper_bound){
volume = InnerFunc4(t,L)*step_size**2
integral = integral + volume
L = L + step_size
}
t = t + step_size
}
Since It seems that your problem is only the derivative, you can get rid of it by means of partial integration:
Edit
Not applicable solution for lower integration bound 0.

R mknapsack function

I run the R program from article where used mknapsack function from adagio package, and everything's good. But if I want using a random values I get an error "Error condition raised".
I have a program:
n=16
m=5
max=700
min = 10
planks_we_have = floor(runif(n=m, min = 100, max = max))
planks_we_want = floor(runif(n=n, min = min, max = 16))
library(adagio)
# mknapsack calling signature is: mknapsack(values, weights, capacities)
solution <- mknapsack(planks_we_want, planks_we_want, planks_we_have)
# Above I added +1 cm to each length to compensate for the loss when sawing.
solution$ksack
# Now pretty printing what to cut so that we don't make mistakes...
assignment <- data.frame(cut_this = planks_we_have[solution$ksack], into_this = planks_we_want)
t(assignment[order(assignment[,1]), ])
Result:
Warning
In mknapsack(planks_we_want, planks_we_want, planks_we_have) :
Error condition raised: check input data ...!
Error
In data.frame(cut_this = planks_we_have[solution$ksack], into_this = planks_we_want) :
Arguments imply different numbers of lines: 0, 5
I don't understand what is the reason. The source code of the knapsack function gives me nothing:
function (p, w, k, bck = -1)
{
stopifnot(is.numeric(p), is.numeric(w), is.numeric(k))
if (any(w <= 0))
stop("'weights' must be a vector of positive numbers.")
if (any(p <= 0))
stop("'profits' must be a vector of positive numbers.")
if (any(floor(p) != ceiling(p)) || any(floor(w) != ceiling(w)) ||
any(floor(k) != ceiling(k)) || any(p >= 2^31) || any(w >=
2^31) || any(k >= 2^31))
stop("All inputs must be positive integers < 2^31 !")
n <- length(p)
m <- length(k)
if (length(w) != n)
stop("Profit 'p' and weight 'w' must be vectors of equal length.")
xstar <- vector("integer", n)
vstar <- 0
num <- 5 * m + 14 * n + 4 * m * n + 3
wk <- numeric(n)
iwk <- vector("integer", num)
S <- .Fortran("mkp", as.integer(n), as.integer(m), as.integer(p),
as.integer(w), as.integer(k), bs = as.integer(bck),
xs = as.integer(xstar), vs = as.integer(vstar), as.numeric(wk),
as.integer(iwk), as.integer(num), PACKAGE = "adagio")
if (S$vs < 0)
warning("Error condition raised: check input data ...!")
return(list(ksack = S$xs, value = S$vs, btracks = S$bs))
}
Versions:
R - 3.4.1
Adagio - 0.7.1
Please read first the help page if you have problems with a function. Looking at the solution returned, it has error code vs=-7 and help says "vs=-7 if array k is not correctly sorted". Sorting the vector of capacities may give another error, for instance in case all items can be put in one knapsack. Of course, all this depends on the random numbers generated (better fix random numbers before asking).

Complex numbers and missing arguments in R function

I am solving a task for my R online course. The task is to write a function, that solves the quadratic equation with the Lagrange resolvents, or:
x1<--p/2+sqrt((p/2)^2-q)
x2<--p/2-sqrt((p/2)^2-q)
1) If the arguments are non-numeric, the function should return an explained error (or why the error has happend). 2) If there are missing arguments, the function should return an explained error (different from the default). 3) If x1 and x2 are complex numbers (for example if p=-4 and q=7, then x1=2+i*1.73 and x2=2-i*1.73), the function should should also solve the equation instead of generating NaNs and return a warning message, that the numbers are complex. Maybe if I somehow cast it to as.complex, but I want this to be a special case and don't want to cast the basic formula.
My function looks like this:
quadraticEquation<-function(p,q){
if(!is.numeric(c(p,q)))stop("p and q are not numeric") #partly works
if(is.na(c(p,q)))stop("there are argument/s missing") #does not work
x1<--p/2+sqrt((p/2)^2-q)
x2<--p/2-sqrt((p/2)^2-q)
#x1<--p/2+sqrt(as.complex((p/2)^2-q)) works, but I want to perform this only in case the numbers are complex
#x2<--p/2-sqrt(as.complex((p/2)^2-q))
return (c(x1,x2))
}
When testing the function:
quadraticEquation(4,3) #basic case is working
quadraticEquation(TRUE,5) #non-numeric, however the if-statement is not executed, because it assumes that TRUE==1
quadraticEquation(-4,7) #complex number
1) how to write the function, so it assumes TRUE (without "") and anything that is non-numeric as non-numeric?
2) basic case, works.
3) how can I write the function, so it solves the equation and prints the complex numbers and also warns that the numbers are complex (warning())?
Something like this?
quadraticEquation <- function(p, q){
## ------------------------% chek the arguments %---------------------------##
if(
missing(p) | missing(q) # if any of arguments is
){ # missing - stop.
stop("[!] There are argument/s missing")
}
else if(
!is.numeric(p) | !is.numeric(q) | any(is.na(c(p, q))) # !is.numeric(c(1, T))
){ # returns TRUE - conver-
stop("[!] Argument/s p or/and q are not numeric") # tion to the same type
}
## --------------------% main part of the function %--------------------------##
r2 <- p^2 - 4*q # calculate r^2,
if(r2 < 0){ # if r2 < 0 (convert) it
warning("equation has complex roots") # to complex and warn
r2 <- as.complex(r2)
}
# return named roots
setNames(c(-1, 1) * sqrt(r2)/2 - p/2, c("x1", "x2"))
}
quadraticEquation() # No arguments provided
#Error in quadraticEquation() : [!] There are argument/s missing
quadraticEquation(p = 4) # Argument q is missing
#Error in quadraticEquation(p = 4) : [!] There are argument/s missing
quadraticEquation(p = TRUE, q = 7) # p is logical
#Error in quadraticEquation(p = TRUE, q = 7) :
#[!] Argument/s p or/and q are not numeric
quadraticEquation(p = NA, q = 7) # p is NA
#Error in quadraticEquation(p = NA, q = 7) :
#[!] Argument/s p or/and q are not numeric
quadraticEquation(p = 7, q = -4) # real roots
# x1 x2
#-7.5311289 0.5311289
quadraticEquation(p = -4, q = 7) # complex roots
# x1 x2
#2-1.732051i 2+1.732051i
#Warning message:
#In quadraticEquation(p = -4, q = 7) : equation has complex roots
When you write is.numeric(c(p, q)), R first evaluates c(p, q) before determining whether it is numeric or not. In particular if p = TRUE and q = 3, then c(p, q) is promoted to the higher type: c(1, 3).
Here is a vectorized solution, so if p and q are vectors instead of scalars the result is also a vector.
quadraticEquation <- function(p, q) {
if (missing(p)) {
stop("`p` is missing.")
}
if (missing(q)) {
stop("`q` is missing.")
}
if (!is.numeric(p)) {
stop("`p` is not numeric.")
}
if (!is.numeric(q)) {
stop("`q` is not numeric.")
}
if (anyNA(p)) {
stop("`p` contains NAs.")
}
if (anyNA(q)) {
stop("`q` contains NAs.")
}
R <- p^2 / 4 - q
if (min(R) < 0) {
R <- as.complex(R)
warning("Returning complex values.")
}
list(x1 = -p / 2 + sqrt(R),
x2 = -p / 2 - sqrt(R))
}
Also, you should never write x1<--p/2. Keep spaces around infix operators: x1 <- -p/2.

Static arguments to NLsolve.jl

I am trying to use NLsolve.jl to solve a set of 6 equations with known Jacobian matrix.
The unknowns are in the array U, so following the repository example I created a function fun! as
function fun!(F, U, k)
W = anotherFunction(U, k)
F[1] = U[1] + 4*k[1]*U[4] - W[1]
F[2] = U[2] - 4*k[2]*U[5] - W[2]
F[3] = U[3] - 4*k[3]*U[6] - W[3]
F[4] = U[1]*(U[4]*U[4]*U[4]*U[4]) -
U[2]*(U[5]*U[5]*U[5]*U[5]) -
U[3]*(U[6]*U[6]*U[6]*U[6])
F[5] = k[7]*(U[4]*U[4]*k[4] - 1 ) -
(k[8]*(U[5]*U[5]*k[5] - 1))
F[6] = k[7]*(U[4]*U[4]*k[4] - 1 ) -
(k[9]*(U[6]*U[6]*k[6] - 1))
end
where the values of W are computed throuhg another function. Similarly, the Jacobian reads
function jac!(J, U, k)
J = eye(6)
J[1,4] = 4*k[1]
J[2,5] = -4*k[2]
J[3,6] = -4*k[3]
J[4,1] = (U[4]*U[4]*U[4]*U[4])
J[4,2] = -(U[5]*U[5]*U[5]*U[5])
J[4,3] = -(U[6]*U[6]*U[6]*U[6])
J[4,4] = 4*U[1]*(U[4]*U[4]*U[4])
J[4,5] = -4*U[2]*(U[5]*U[5]*U[5])
J[4,6] = -4*U[3]*(U[6]*U[6]*U[6])
J[5,1] = 0.
J[5,2] = 0.
J[5,4] = 2*k[7]*U[4]*k[4]
J[5,5] = -2*k[8]*U[5]*k[5]
J[6,1] = 0.
J[6,3] = 0.
J[6,4] = 2*k[7]*U[4]*k[4]
J[6,6] = -2*k[9]*U[6]*k[6]
end
The k array is constant and defined before calling nlsove, therefore I create two more functions to enclose fun! and jac! as described here, here, and here
f_closure!(U) = fun!(F, U, k)
j_closure!(U) = jac!(J, U, k)
However, calling res = nlsolve(f_closure!, j_closure!, U) results in this error
ERROR: LoadError: MethodError: no method matching
(::#f_closure!#5{Array{Float64,1}})(::Array{Float64,1},
::Array{Float64,1}) Closest candidates are: f_closure!(::Any)
Is there a different way to pass the k array? Thanks!

Integrate a sum in R

I am trying to compute the MISE of an estimator and for that i need to do the integral of :
(fp(x) - f(x))^2 where f(x) is exp(-x) and fp(x) is : sum_{i}^n { (1/n)*((K((x - X[i])/h))/h) }
The problem here is that X is a matrix, and i don't know how integrate this sum.
I've tried this :
Kgauss <- function(u) dnorm(u) #Gaussian kernel
func = function(x, n, h, X){ ((1/n) * sum(Kgauss((x-X[0:n])/h)/h) - exp(-x))^2 } # h, n are constants
vfunc = Vectorize(func)
integrate(vfunc, n = 3, K = Kgauss, h = 0.25, X = rexp(3), lower = 0, Inf)
But sadly it didn't work out. The big problem here is fp(x), it consists of the sum of multiple functions .
I hope you can help me with this one, I've been struggling for a while now.
Basically i want to make : integral((K(X1) + ... + K(Xn) - exp(-x))²)
You can define the n, h, and K outside the func and then have x as the only parameter:
n = 3; h = 0.25; X = rexp(3)
func = function(x){ ((1/n) * sum(dnorm((x-X[0:n])/h)/h) - exp(-x))^2 }
vfunc = function(x) { sapply(x, func)}
integrate(vfunc, lower = 0, Inf)
# 0.2070893 with absolute error < 1.7e-05
(I'm not sure that you even need to vectorize func. It's built with vectorized functions already.)

Resources