Skip to content

Instantly share code, notes, and snippets.

@andreasplesch
Last active August 29, 2015 14:27
Show Gist options
  • Save andreasplesch/ada4b4e89738d4e5d4af to your computer and use it in GitHub Desktop.
Save andreasplesch/ada4b4e89738d4e5d4af to your computer and use it in GitHub Desktop.
testing d3 v.4 range() method, wait ...

These are some tests to check behavior of the d3 range() method when it is used with fractional step sizes.

https://github.com/d3/d3-arrays has the candidate versions for a new release d3. The range() function below is copied over from there.

<html>
<body>
<p>
number of unexpected range(0, 1, step) lengths for steps 1/n with n = 1 to
<span id='result1'> </span>.
</p>
<p>with workaround</p>
<p>
number of unexpected range(0, 1-eps, step) lengths for eps=1e<sup>-17</sup> and steps 1/n with n = 1 to
<span id='result2'> </span>.
</p>
<p>
number of unexpected range(0, (1-eps)*max, step) lengths for steps max/n and max = 2<sup>m</sup> with n = 1 to
<span id='result3'> </span>.
</p>
<p>
number of unexpected range(offset, offset + (1-eps)*max, step) lengths for steps max/n, max = 2<sup>m</sup> and offset = 3<sup>m</sup> with n = 1 to
<span id='result4'> </span>.
</p>
number of unexpected range(0, 1-eps, step) lengths for eps=1e<sup>-16</sup> and steps 1/n with n = 1 to
<span id='result2b'> </span>.
</p>
<p>
number of unexpected range(0, (1-eps)*max, step) lengths for steps max/n and max = 2<sup>m</sup> with n = 1 to
<span id='result3b'> </span>.
</p>
<p>
number of unexpected range(offset, offset + (1-eps)*max, step) lengths for steps max/n, max = 2<sup>m</sup> and offset = 3<sup>m</sup> with n = 1 to
<span id='result4b'> </span>.
</p>
<p>
number of unexpected range((1-eps)*offset, (1-eps)*(offset + max), step) lengths for steps max/n, max = 2<sup>m</sup> and offset = 3<sup>m</sup> with n = 1 to
<span id='result4c'> </span>.
</p>
<p>
number of unexpected range((1-eps)*offset, (1-eps)*(offset + max), step) lengths for eps=1e<sup>-10</sup> and steps max/n, max = 2<sup>m</sup> and offset = 3<sup>m</sup> with n = 1 to
<span id='result4d'> </span>.
</p>
<script>
//this is the new range function
function range(start, stop, step) {
if ((n = arguments.length) < 3) {
step = 1;
if (n < 2) {
stop = start;
start = 0;
}
}
var i = -1,
n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
k = scale(Math.abs(step)),
range = new Array(n);
start *= k;
step *= k;
while (++i < n) {
range[i] = (start + i * step) / k;
}
return range;
};
function scale(x) {
var k = 1;
while (x * k % 1) k *= 10;
return k;
};
//test
function collect_mismatches(max_d, eps, eps2, offset, max) {
var mismatches = [];
var max = max;
range(1, max_d).forEach(function(d) {
if (range(offset * (1-eps2), offset * (1-eps2) + max * (1-eps), max/d).length !== d)
{mismatches.push([offset, max, d]);}
});
return mismatches;
};
function mismatches_thru_domains(max_d, eps, eps2, minscale, max_e) {
var collected = [];
range(0, max_e).forEach(function(e) {
var max = Math.pow(2, e);
var min = Math.pow(3, e) * minscale;
collected = collected.concat(collect_mismatches(max_d, eps, eps2, min, max));
});
return collected;
};
var max_denominator = 1000;
var max_expo = 64;
var r1 = collect_mismatches(max_denominator, 0, 0, 0, 1).length;
var r2 = collect_mismatches(max_denominator, 1e-17, 0, 0, 1).length;
var r3 = mismatches_thru_domains(max_denominator, 1e-17, 0, 0, max_expo).length;
var r4 = mismatches_thru_domains(max_denominator, 1e-17, 0, 1, max_expo).length;
var r2b = collect_mismatches(max_denominator, 1e-16, 0, 0, 1).length;
var r3b = mismatches_thru_domains(max_denominator, 1e-16, 0, 0, max_expo).length;
var ar4b = mismatches_thru_domains(max_denominator, 1e-16, 0 , 1, max_expo);
var ar4c = mismatches_thru_domains(max_denominator, 1e-16, 1e-16, 1, max_expo);
var ar4d = mismatches_thru_domains(max_denominator, 1e-10, 1e-10, 1, max_expo);
document.getElementById('result1').textContent = max_denominator + " : " + r1;
document.getElementById('result2').textContent = max_denominator + " : " + r2;
document.getElementById('result3').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + r3;
document.getElementById('result4').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + r4;
document.getElementById('result2b').textContent = max_denominator + " : " + r2b;
document.getElementById('result3b').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + r3b;
document.getElementById('result4b').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + ar4b.length + " ; first: " + ar4b[0];
document.getElementById('result4c').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + ar4c.length + " ; first: " + ar4c[0];
document.getElementById('result4d').textContent = max_denominator + " and m = 0 to " + max_expo + " : " + ar4d.length + " ; first: " + ar4d[0];
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment