Skip to content

Instantly share code, notes, and snippets.

@lsbardel
Last active October 9, 2018 09:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lsbardel/fcf9f7e17e628f126c503067a9058198 to your computer and use it in GitHub Desktop.
Save lsbardel/fcf9f7e17e628f126c503067a9058198 to your computer and use it in GitHub Desktop.
Sobol Low Discrepancy Sequence
license: bsd-3-clause

Visualisation of the first 10 dimensions of the Sobol low discrepancy sequence.

Low-discrepancy sequences are also called quasi-random sequences, due to their common use as a replacement of uniformly distributed random numbers. Quasi-random numbers have an advantage over pure random numbers in that they cover the domain of interest quickly and evenly. This is an important feature when performing numerical integration via Monte Carlo techniques.

The Sobol sequence preserves low discrepancy properties in multi dimensions which makes it a good candidate for quasi Monte Carlo methods on random paths.

Sobol implementation in d3-quant, single code base visualisations on svg and canvas thanks to d3-canvas-transition module.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sobol Low Discrepancy Sequence</title>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://giottojs.org/d3-canvas-transition/0.3.4/d3-canvas-transition.js"></script>
<script src="https://giottojs.org/d3-quant/0.4.2/d3-quant.js"></script>
<style>
#panel {
background-color: rgba(245,245,245,0.9);
padding: 5px;
position: absolute;
display: block;
}
</style>
</head>
<body>
<div id="panel">
<div id="paper">
<label>
<input id='svg' name="type" type="radio" checked>
<span>svg</span>
</label>
<label>
<input id='canvas' name="type" type="radio">
<span>canvas</span>
</label>
</div>
<button>Randomise</button>
<label>Dimensions</label>
<select>Dimensions
<option value="1">1-2</option>
<option value="2">2-3</option>
<option value="3">3-4</option>
<option value="4">4-5</option>
<option value="5">5-6</option>
<option value="6">6-7</option>
<option value="7">7-8</option>
<option value="8">8-9</option>
</select>
</div>
<div id="example" style="max-width: 960px"></div>
<script src="./script.js">
</script>
</body>
(function () {
d3.select('#svg').on('click', function () {
draw('svg');
});
d3.select('#canvas').on('click', function () {
draw('canvas');
});
if (d3.resolution() > 1) {
d3.select('#paper').append('label').html(
"<input id='canvas-low' name='type' type='radio'><span>canvas low resolution</span>"
);
d3.select('#canvas-low').on('click', function () {
draw('canvas', 1);
});
}
var N = 2000,
sobol = d3.sobol(10),
data = sobol.generate(N),
dim = 0,
currentType,
currentRes,
paper, x, y;
d3.select('button').on('click.randomise', function () {
data = sobol.generate(N);
refresh();
});
d3.select('select').on('change.dimension', function () {
dim = d3.select(this).property('value') - 1;
refresh();
});
draw('svg');
function draw(type, r) {
var example = d3.select("#example"),
width = d3.getSize(example.style('width')),
height = Math.min(500, width);
x = d3.scaleLinear().range([0, width]);
y = d3.scaleLinear().range([height, 0]);
currentRes = r;
currentType = type;
example.select('.paper').remove();
paper = example
.append(type)
.classed('paper', true)
.attr('width', width).attr('height', height).canvasResolution(r).canvas(true);
paper.append('rect')
.attr('width', width)
.attr('height', height)
.style('fill', '#fff');
refresh();
}
function refresh () {
var points = paper.selectAll('circle').data(data);
points
.enter()
.append('circle')
.style('fill', '#999')
.style('stroke', '#333')
.style('stroke-width', '1px')
.attr('r', 2)
.attr('cx', x(0.5))
.attr('cy', y(0.5))
.merge(points)
.transition()
.duration(1000)
.attr('cx', function (d) {return x(d[dim]);})
.attr('cy', function (d) {return y(d[dim+1]);});
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment