can you use variable limits of integration with the Cubature library - r

I'm trying to use a variable limit of integration using the Cubature library.
For example:
adaptIntegrate(function(x) {x[1]*x[2]},
lowerLimit = c(0,0),
upperLimit = c(x[2],1))$integral
This doesn't work
Thanks

The integral has form \int_O^1 \int_0^{x[2]} f dx[1] dx[2]
The domain of integration is a triangle (make a picture!) with vertices (0,0), (0,1), (1,1). For such a domain, use the SimplicialCubature package.
> f <- function(x) x[1]*x[2]
> S <- cbind(c(0,0),c(0,1),c(1,1)) # the triangle (simplex)
> library(SimplicialCubature)
> adaptIntegrateSimplex(f, S)
$integral
[1] 0.125
$estAbsError
[1] 1.25e-13
$functionEvaluations
[1] 32

Cubature is a package for adaptive multidimensional integration over hypercubes. I am also looking for packages which do multidimensional integration over any specific region (i.e. use variable as limits), anyone knows?
In addition, the definition of the function is not appropriate. I guess what you want is
function(x1,x2) x1*x2

Related

How to pass nonlinear objective functions into ROI package in R?

I'm trying to tackle a nonlinear optimization problem where the objective functions are non-linear and constraints are linear. I read a bit on the ROI package in R and I decided to use the same. However, I am facing a problem while solving the optimization problem.
I am essentially trying to minimize the area under a supply-demand curve. The equation for the supply and demand curves are defined in the code:
Objective function: minimize (Integral of supply curve + integral of demand curve),
subject to constraints q greater than or equal to 34155 (stored in a variable called ICR),
q greater than or equal to 0
and q less than or equal to 40000.
I have tried to run this through the ROI package in RStudio and I keep getting an error telling me that there is no solver to be found.
library(tidyverse)
library(ROI)
library(rSymPy)
library(mosaicCalc)
# Initializing parameters for demand curve
A1 <- 6190735.2198302800
B1 <- -1222739.9618776600
C1 <- 103427.9556133250
D1 <- -4857.0627045073
E1 <- 136.7660814828
# Initializing parameters for Supply Curve
S1 <- -1.152
S2 <- 0.002
S3 <- a-9.037e-09
S4 <- 2.082e-13
S5 <- -1.64e-18
ICR <- 34155
demand_curve_integral <- antiD(A1 + B1*q + C1*(q^2)+ D1*(q^3) + E1*(q^4) ~q)
supply_curve_integral <- antiD(S1 + S2*(q) + S3*(q^2) + S4*(q^3) + S5*(q^4)~q)
# Setting up the objective function
obj_func <- function(q){ (18.081*demand_curve_integral(q))+supply_curve_integral(q)}
# Setting up the optimization Problem
lp <- OP(objective = F_objective(obj_func, n=1L),
constraints=L_constraint(L=matrix(c(1, 1, 1), nrow=3),
dir=c(">=", ">=", "<="),
rhs=c(ICR, 0, 40000, 1))),
maximum = FALSE)
sol <- ROI_solve(lp)
This is the error that I keep getting in RStudio:
Error in ROI_solve(lp) : no solver found for this signature:
objective: F
constraints: L
bounds: V
cones: X
maximum: FALSE
C: TRUE
I: FALSE
B: FALSE
What should I do to rectify this error?
In general you could use ROI.plugin.alabama or ROI.plugin.nloptr for this optimization problem.
But I looked at the problem and this raised several questions.
a is not defined in the code.
You state that q has length 1 and add 3 linear constraints the constraints say
q >= 34155, q >= 0, q <= 40000 or q <= 1
I am not entirely sure since the length of rhs is 4 but L and dir
suggest there are only 3 linear constraints.
How should the constraint look like?
34155 <= q <= 40000?
Then you could specify the constraint as bounds and use ROI.plugin.optimx
or since you have a one dimensional optimization problem just use optimize
from the stats package https://stat.ethz.ch/R-manual/R-devel/library/stats/html/optimize.html.
I haven't run NLP using ROI. But you have to install an ROI solver plug-in and then load the library in your code. The current solver plug-ins are:
library(ROI.plugin.glpk)
library(ROI.plugin.lpsolve)
library(ROI.plugin.neos)
library(ROI.plugin.symphony)
library(ROI.plugin.cplex)
Neos provides access to NLP solvers but I don't know how to pass solver parameters via an ROI plug-in function call.
https://neos-guide.org/content/nonlinear-programming

Writing an R function that evens out both sides of equation

I am quite new to r, so I turned to the internet for some help.
My question is:
for the equation ln(n/n0) = kln(1+x/k),
I would like to write a function that estimates k (based of trial and error) if all other variables are known.
In other words: function that would solve the equation like
0.85 = k * ln(1+0.56/k).
In my work I have to estimate k over and over again so the automation of the process would save me alot of time.
Thanks
Too long for a comment...
The equation x*ln(1+a/x) = b (for suitable values of a and b) has a solution expressed with the Lambert W function, available in the gsl package under the name lambert_W0. This solution is -a*b/(a*W(-b/(a*exp(b/a)))+b) where W is the Lambert W function.
> library(gsl)
> a=0.56; b=0.85
> x <- -a*b/(a*lambert_W0(-b/(a*exp(b/a)))+b) # solution of the equation
> x*log(1+a/x)
[1] 0.85
I don't know exactly for which values of a and b this solution works. It seems to work whenever a<b.
For some cases of a>b, there is a solution in terms of the Lambert W_{-1} function, lambert_Wm1 in gsl:
> library(gsl)
> a=0.6; b=0.4
> x <- -a*b/(a*lambert_Wm1(-b/(a*exp(b/a)))+b)
> x*log(1+a/x)
[1] 0.4
The domains of definition of W and W_{-1} can be found in the documentation of the lamW package (section "Details" page 3).

solve complex number equation in R

I am getting an equation with this form
exp(az) = 1 + cz
which I wanna solve for z,
where c is a complex number, so expectedly z is complex also.
I cannot figure out how to solve an equation involving complex number in R.
I hope anybody can help me
Wolfram Alpha can get a solution in terms of the Lambert W function (which it calls the ProductLog function):
The emdbook package (among others) has an implementation of the Lambert W function. (In order to make this work I had to fix a bug, so you can't use the CRAN implementation. Instead, install the latest version from Github: library(devtools); install_github("bbolker/emdbook") ...
library(emdbook)
sfun <- function(a,c) {
w <- lambertW(-a/c*exp(-a/c))
-(c*w+a)/(a*c)
}
Example
a <- 2+1i; c <- 1+1i
(z <- sfun(a,c))
## [1] -0.1686391-0.2337278i
Check answer:
(exp(a*z)-(1+c*z))
## [1] 0+5.551115e-17i
This is zero to within expected numeric tolerance ...
The intermediate step in Ben Bolker's solution:

Integration with cuhre

I am using cuhre from R2Cuba 1.1-0 for integrating the following function
fn <- function(x) {
pnorm((-2-sum(sqrt(vecRho)*x))/sqrt(1-sum(vecRho)))*prod(dnorm(x))
}
where vecRho is a vector of 6 numbers between 0 and 0.1, i.e.
vecRho<-runif(6,0,0.1)
By definition, the integrand fn is between 0 and 1. The integration is expected to be positive. However, using cuhre the result becomes negative when the length of vecRho exceeds 5.
NDIM<-length(vecRho)
cuhre(NDIM, 1, fn,
flags = list(verbose =0),
lower = rep(-10,NDIM),
upper = rep(10,NDIM))$value
[1] -0.4738284
Moreover, when the length of vecRho >=6 the absolute value of the integration increases as the length of vecRho increases.
Is there something I can do to fix this? Thanks!
ok, got it, you have 6D integral with 6 gaussian kernels inside. I know good answer for 1D integration with gaussian kernel. It is called Gauss-Hermite quadrature, and there is an R package for that. If you go this route, you'll have to
make curry functions, but it might worth it.
Some sample code:
library(gaussquad)
n.quad <- 128 # integration order
# get the particular (weights,abscissas) as data frame
# with 2 observables and n.quad observations
rule <- ghermite.h.quadrature.rules(n.quad, mu = 0.0)[[n.quad]]
# test function - integrate 1 over exp(-x^2) from -Inf to Inf
# should get sqrt(pi) as an answer
f <- function(x) {
1.0
}
q <- ghermite.h.quadrature(f, rule)
print(q - sqrt(pi))

Relative Minimum via Derivative using R

I am trying to get the value of x that would minimize my equation y. I would like to use R.
The equation is:
y= [(a-bx)^2] / {[2bx /(1+x)]+c}
where a, b, c are all constant, but different to one another.
Thanks.
The standard optimize function should be sufficient for simple one-dimensional minimization:
a <- 2
b <- 1
c <-1
func <- function(x){(a-b*x)^2/((2*b*x/(1+x))+c)}
optimize(f=func, interval = c(-3,3))
$minimum
[1] -0.3333377
$objective
[1] -277201.4

Resources