I think you may have a mistake in your transcription of the function as well. More than that, you say you used uniroot
. That is a one-dimensional root finder. The Weibull is a two-parameter distribution, and it must be optimized over both parameters simultaneously. As a rough analogy, you are restricting yourself to moving North-South only or East-West only along the two-dimensional parameter surface. You have to follow the shape of the surface, even diagonally, to find the minimum. I'll provide an example of simultaneously fitting both shape and scale.
Using the Klugmnan-Panjer-Wilmott (KPW) notation (standard notation for US actuaries), the Weibull has:
$$
\begin{align}
f(x) &= \frac{\tau\left(\frac{x}{\theta}\right)^\tau e^{-\left(\frac{x}{\theta}\right)^\tau}}{x}\\
F(x) &= 1-e^{-\left(\frac{x}{\theta}\right)^\tau}\\
E\left(X^r\right) &= \theta^r\cdot\Gamma\left(1+\frac{r}{\tau}\right),\quad k \gt -\tau
\end{align}
$$
Given that, one can use a numerical optimization routine, as you did, to find $r, \theta$.
set.seed(716)
library(nloptr)
SqErr <- function(par, Mean, Var){
t <- par[[1]]
q <- par[[2]]
Mu <- q * gamma(1 + 1 / t)
SigSq <- q ^ 2 * gamma(1 + 2 / t)
ParVar <- SigSq - Mu ^ 2
return((Mu - Mean) ^ 2 + (ParVar - Var) ^ 2)
}
A <- nloptr(c(2, 1), SqErr, Mean = 1000, Var = 500000,
opts = list(algorithm = "NLOPT_LN_NELDERMEAD",
maxeval = 1e5, ftol = 1e-12))
print(A$solution)
[1] 1.435442 1101.254610
B <- rweibull(1e5, A$solution[[1]], scale = A$solution[[2]])
mean(B); var(B)
[1] 1000.568
[1] 499458.7