Note
Unfortunately I'm not in a position to provide a reproducible example since I have a rather large code segment. I don't think it's a good idea to paste 300+ lines of code so I have provided a skeleton and some pseudo-code to try and explain the problem.
Problem
I am working on an optimization problem in R using nlminb. The
optimizer has worked quite well except for one particular data set with my objective function. The following provides some context about the problem (with syntax simplified).
# Function with parameters to optimize
#
# my_function = function(params, additional_values1, additional_values2, data){
# Perform calculations
# return(value)
# }
# init = vector of initial values
# my_data = relevant data
#
> optimize = nlminb(init, my_function,
additional_values1 = matrix1, additional_values2 = matrix2,
data = my_data, hessian = T)
> optimize
$par
[1] -2.367386 3.032712 -1.146100 3.620519
$objective
[1] -Inf
$convergence
[1] 0
$iterations
[1] 5
$evaluations
function gradient
8 24
$message
[1] "X-convergence (3)"
The convergence of 0 suggests that the optimizer has converged, however the objective function returns a value of -Inf.
Is it possible to set a lower bound on the objective function, or get nlminb to provide the last real value of the objective function (along with the corresponding parameter values)?
I have tried playing around with the control parameters of nlminb however I have not been successful.
Please provide a reproducible example. You could check in your objective function whether the returned value will be -Inf, and then perhaps have the function report the parameters or debug the function in some other way.
In general, convergence merely means that some stopping criterion has been satisfied; so you should not trust it too much:
nlminb(c(0, 0), function(x) -Inf)
## $par
## [1] 0 0
##
## $objective
## [1] -Inf
##
## $convergence
## [1] 0
##
## $iterations
## [1] 1
##
## $evaluations
## function gradient
## 2 2
##
## $message
## [1] "X-convergence (3)"
When I tried to use nlminb to optimize a function with three parameters, it showed this error message
"Error in objective(.par, ...) : argument "x" is missing, with no default".
Could anyone tell me how to fix it?
My code is following:
coeff<-10**(-4)
z<-100
X1<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yh*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yh*yh)+(12*yh)}
X2<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yh*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yh*yh)-(12*yh)}
X3<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yt*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yt*yt)+(3*yt)}
X4<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yt*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yt*yt)-(3*yt)}
f<-function(X1,X2,X3,X4){-(4/9*log(X1)+2/9*log(X2)+2/9*log(X3)+1/9*log(X4))}
nlminb(c(6.944444,5.787037,11.574074),f)
Note that nlminb needs the function to be optimized to take a single vector as the starting point rather than multiple entries.
One possible go around is to do a wrapping for the function f. Also it seems that you want f to take 3 values. f already has access to X1 up to X4.
> coeff<-10**(-4)
> z<-100
>
> X1<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yh*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yh*yh)+(12*yh)}
> X2<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yh*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yh*yh)-(12*yh)}
> X3<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yt*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yt*yt)+(3*yt)}
> X4<- function(x,yh,yt){(15/2*x)+(-5/4*coeff*yt*x)+(25/16*z)-(25/16*coeff*x*x)-(-5/4*coeff*yt*yt)-(3*yt)}
> f<-function(x, yh, yt){-(4/9*log(X1(x,yh, yt))+2/9*log(X2(x,yh, yt))+2/9*log(X3(x,yh, yt))+1/9*log(X4(x,yh, yt)))}
> g <- function(p){
+ f(p[1], p[2], p[3])
+ }
> nlminb(c(6.944444,5.787037,11.574074),g)
produces
$par
[1] 23867.17644 48.34801 566.85042
$objective
[1] -11.40553
$convergence
[1] 0
$iterations
[1] 22
$evaluations
function gradient
25 113
$message
[1] "relative convergence (4)"
I have calculated the required Safety Stock using the excel goal seek function. Below is the image.
But now I want to do the same using R.
The below function gives me the same excel results when I enter the SafetyStock & SD. Now I need to do the reverse calculation(Whenever I provide x & SD I need the SS). Could someone help me with the same?
I tried Optix and other similar R packages but couldn't succeed.
opt<-function(SS,SD){
x=-SS*(1-pnorm(SS/SD)) + SD * dnorm(SS/SD,mean=0,sd =1,0)
print(x)
}
Excel Goal seek
Solving f(x)=c for x is the same as solving f(x)-c=0. You can use uniroot to find the root:
f <- function(SS, SD, ESC) {
-SS*(1-pnorm(SS/SD)) + SD * dnorm(SS/SD,mean=0,sd =1,0) - ESC
}
zero <- uniroot(f,c(0,1000),SD=600,ESC=39.3)
zero$root
The second argument is the interval to search: between 0 and 1000. This returns
674.0586
The zero structure has more interesting information:
$root
[1] 674.0586
$f.root
[1] 1.933248e-08
$iter
[1] 8
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
I want to know how can I calculate large values multiplication in R.
R returns Inf!
For example:
6.350218e+277*2.218789e+215
[1] Inf
Let me clarify the problem more:
consider the following code and the results of outFunc function:
library(hypergeo)
poch <-function(a,b) gamma(a+b)/gamma(a)
n<-c(37 , 41 , 4 , 9 , 12 , 13 , 2 , 5 , 23 , 73 , 129 , 22 , 121 )
v<-c(90.2, 199.3, 61, 38, 176.3, 293.6, 318.6, 328.7, 328.1, 313.3, 142.4, 92.9, 95.5)
DF<-data.frame(n,v)
outFunc<-function(k,w,r,lam,a,b) {
((((w*lam)^k) * poch(r,k) * poch(a,b) ) * hypergeo(r+k,a+k,a+b+k,-(w*lam)) )/(poch(a+k,b)*factorial(k))
}
and the function returns:
outFunc(DF$n,DF$v,0.2, 1, 3, 1)
[1] 0.002911330+ 0i 0.003047594+ 0i 0.029886646+ 0i 0.013560599+ 0i 0.010160073+ 0i
[6] 0.008928524+ 0i 0.040165795+ 0i 0.019402318+ 0i 0.005336008+ 0i 0.001689114+ 0i
[11] Inf+NaNi 0.005577985+ 0i Inf+NaNi
As can be seen above, outFunc returns Inf+NaNi for n values of 129 and 121.
I checked the code sections part by part and I find that the returned results of (wlam)^k poch(r,k) for these n values are Inf. I also check my code with equivalent code in Mathematica which everything is OK:
in: out[indata[[All, 1]], indata[[All, 2]], 0.2, 1, 3, 1]
out: {0.00291133, 0.00304759, 0.0298866, 0.0135606, 0.0101601, 0.00892852, \
0.0401658, 0.0194023, 0.00533601, 0.00168911, 0.000506457, \
0.00557798, 0.000365445}
Now please let me know how we can solve this issue as simple as it is in Mathematica. regards.
One option you have available in base R, which does not require a special library, is to convert the two numbers to a common base, and then add the exponents together to get the final result:
> x <- log(6.350218e+277, 10)
> x
[1] 277.8028
> y <- log(2.218789e+215, 10)
> y
[1] 215.3461
> x + y
[1] 493.1489
Since 10^x * 10^y = 10^(x+y), your final answer is 10^493.1489
Note that this solution does not allow to actually store numbers which R would normally treat as INF. Hence, in this example, you still cannot compute 10^493, but you can tease out what the product would be.
For first, I'd recommend two useful reads: logarithms and how floating values are handled by a computer. These are pertinent because with some "tricks" you can handle much bigger values than you think. For instance, your definition of the poch function is terrible. This because the fraction can be simplified a lot but a computer will evaluate the numerator first and if it overflows the result will be useless. That's why R provides beside gamma the lgamma function: it just calculates the logarithm of gamma and can handle much bigger values. So, we calculate the log of each factor in your function and then we use exp to restore the intended values. Try this:
#redefine poch properly
poch<-function(a,b) lgamma(a+b) - lgamma(a)
#redefine outFunc
outFunc<-function(k,w,r,lam,a,b) {
exp((k*(log(w)+log(lam))+ poch(r,k) + poch(a,b) ) +
log(hypergeo(r+k,a+k,a+b+k,-(w*lam)))- poch(a+k,b)-lgamma(k+1))
}
#Now we go
outFunc(DF$n,DF$v,0.2, 1, 3, 1)
#[1] 0.0029113299+0i 0.0030475939+0i 0.0298866458+0i 0.0135605995+0i
#[5] 0.0101600732+0i 0.0089285243+0i 0.0401657947+0i 0.0194023182+0i
#[9] 0.0053360084+0i 0.0016891144+0i 0.0005064566+0i 0.0055779850+0i
#[13] 0.0003654449+0i
> library(gmp)
> x<- pow.bigz(6.350218,277)
> y<- pow.bigz(2.218789,215)
> x*y
Big Integer ('bigz') :
[1] 18592826814872791919942226542714580401488894909642693257011204682802122918146288728149155739011270579948954646130492024596687919148494136290260248656581476275790189359808616520170359345612068099238508437236172770752199936303947098513476300142414338199993261924467166943683593371648
This is likely a duplicate question, but maybe I'm just not using the proper keywords to find what I'm looking for.
Currently, if I have a vector x, if I want a unit equivalent I would just do
x_unit <- x/sum(x)
This is an extremely basic task and may not be made any more efficiently than this, but I'm wondering if there is a function which obtains this task but has an na.rm feature or a handles the case when sum(x) == 0.
James
Here's a little function that does what you ask:
unit_vec <- function(vec){
return(vec/(sqrt(sum(vec**2,na.rm=TRUE))))
}
let's test it!
!> vec
[1] 87.45438 83.96820 111.47986 106.00922 110.13914 107.26847 86.53061
[8] 103.61227 85.79385 88.16059 NA
!> unit_vec(vec)
[1] 0.2832068 0.2719174 0.3610094 0.3432936 0.3566677 0.3473715 0.2802153
[8] 0.3355315 0.2778294 0.2854937 NA
!> sqrt(sum(unit_vec(vec)**2,na.rm=TRUE))
[1] 1
It works when the sum is 0 too!
> vec2
[1] 10 -10
> unit_vec(vec2)
[1] 0.7071068 -0.7071068
!> sqrt(sum(unit_vec(vec2)**2,na.rm=TRUE))
[1] 1
I hope this helps.