time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

samples.js (1890B)


      1 // Imports
      2 
      3 import stdlib_normal from '@stdlib/random/base/normal/lib/main.js';
      4 import stdlib_lognormal from '@stdlib/random/base/lognormal/lib/main.js';
      5 
      6 // Functions
      7 const DEFAULT_N = 10**6
      8 function generator(f) {
      9   let g = (a, b, n = DEFAULT_N) => {
     10     let result = new Array(n)
     11     for (let i = 0; i < n; i++) {
     12       result[i] = f(a, b, n)
     13     }
     14     return result
     15   }
     16   return g
     17 }
     18 const sum = xs => xs.reduce((acc, x) => acc + x, 0)
     19 
     20 const normal = generator(stdlib_normal)
     21 const lognormal = generator(stdlib_lognormal)
     22 const to = (low, high, n = DEFAULT_N) => {
     23   let normal95confidencePoint = 1.6448536269514722
     24   let logLow = Math.log(low)
     25   let logHigh = Math.log(high)
     26   let meanlog = (logLow + logHigh) / 2
     27   let sdlog = (logHigh - logLow) / (2.0 * normal95confidencePoint)
     28   return lognormal(meanlog, sdlog, n)
     29 }
     30 
     31 const mixture = (dists_array, weights_array, n = DEFAULT_N) => {
     32   let normalized_weights = weights_array.map(w => w / sum(weights_array))
     33   let cummulative_sums = Array(normalized_weights.length)
     34   normalized_weights.reduce((acc, x, i) => {
     35     cummulative_sums[i] = acc + x
     36     return cummulative_sums[i]
     37   }, 0)
     38   const helper_probs = [...new Array(n)].map(_ => Math.random())
     39   const results = helper_probs.map(p => {
     40     let match_index = cummulative_sums.findIndex(x => x > p)
     41     if(match_index == -1){
     42       console.log("Error: This should never happen.")
     43     }
     44     let target_loc = match_index // == -1 ? 0 : match_index
     45     let target_samples = dists_array[target_loc]
     46     return target_samples[Math.floor(Math.random() * target_samples.length)];
     47   })
     48   return(results)
     49 
     50 }
     51 
     52 // Example
     53 let p_a = 0.8
     54 let p_b = 0.5
     55 let p_c = p_a * p_b
     56 
     57 let dists = [
     58   [0], [1], to(1, 3),
     59   to(2, 10)
     60 ]
     61 let weights = [
     62   (1 - p_c),
     63   p_c / 2,
     64   p_c / 4,
     65   p_c / 4
     66 ]
     67 let result = mixture(dists, weights)
     68 let mean_result = sum(result)/result.length
     69 console.log(mean_result)