title: Generating lognormally distributed random number from mean, coeff of variation
body: <p>Most functions for generating lognormally distributed random numbers take the mean and standard deviation of the associated normal distribution as parameters.</p>
  
  <p>My problem is that I only know the mean and the coefficient of variation of the lognormal distribution.  It is reasonably straight forward to derive the parameters I need for the standard functions from what I have:</p>
  
  <p>If <code>mu</code> and <code>sigma</code> are the mean and standard deviation of the associated normal distribution, we know that</p>
  
  <pre><code>coeffOfVar^2 = variance / mean^2
               = (exp(sigma^2) - 1) * exp(2*mu + sigma^2) / exp(mu + sigma^2/2)^2
               = exp(sigma^2) - 1
  </code></pre>
  
  <p>We can rearrange this to </p>
  
  <pre><code>sigma = sqrt(log(coeffOfVar^2 + 1))
  </code></pre>
  
  <p>We also know that</p>
  
  <pre><code>mean = exp(mu + sigma^2/2)
  </code></pre>
  
  <p>This rearranges to </p>
  
  <pre><code>mu = log(mean) - sigma^2/2
  </code></pre>
  
  <p>Here's my R implementation</p>
  
  <pre><code>rlnorm0 &lt;- function(mean, coeffOfVar, n = 1e6)
  {
     sigma &lt;- sqrt(log(coeffOfVar^2 + 1))
     mu &lt;- log(mean) - sigma^2 / 2
     rlnorm(n, mu, sigma)
  }
  </code></pre>
  
  <p>It works okay for small coefficients of variation</p>
  
  <pre><code>r1 &lt;- rlnorm0(2, 0.5)
  mean(r1)                 # 2.000095
  sd(r1) / mean(r1)        # 0.4998437
  </code></pre>
  
  <p>But not for larger values</p>
  
  <pre><code>r2 &lt;- rlnorm0(2, 50)
  mean(r2)                 # 2.048509
  sd(r2) / mean(r2)        # 68.55871
  </code></pre>
  
  <p>To check that it wasn't an R-specific issue, I reimplemented it in MATLAB. (Uses stats toolbox.)</p>
  
  <pre><code>function y = lognrnd0(mean, coeffOfVar, sizeOut)
  if nargin &lt; 3 || isempty(sizeOut)
     sizeOut = [1e6 1];
  end
  sigma = sqrt(log(coeffOfVar.^2 + 1));
  mu = log(mean) - sigma.^2 ./ 2;
  y = lognrnd(mu, sigma, sizeOut);
  end
  
  r1 = lognrnd0(2, 0.5);
  mean(r1)                  % 2.0013
  std(r1) ./ mean(r1)       % 0.5008
  
  r2 = lognrnd0(2, 50);
  mean(r2)                  % 1.9611
  std(r2) ./ mean(r2)       % 22.61
  </code></pre>
  
  <p>Same problem.  The question is, why is this happening?  Is it just that the standard deviation is not robust when the variation is that wide?  Or have I screwed up somewhere?</p>