Skip to content

Instantly share code, notes, and snippets.

@tophtucker
Last active November 22, 2016 06:16
Show Gist options
  • Save tophtucker/bc2d6937ed83c9e67fab592eef70e0a5 to your computer and use it in GitHub Desktop.
Save tophtucker/bc2d6937ed83c9e67fab592eef70e0a5 to your computer and use it in GitHub Desktop.
The exponential curve has no knee

Perhaps it is precisely the common man who has an intuitive prophetic glimpse of the beginning of an immense new, collective, ant-like heroism? It will be called rationalised heroism and will be regarded as very beautiful. But what can we know of that today? However, at that time there were hundreds of such unanswered questions, all of the greatest importance. They were in the air; they were burning underfoot. The time was on the move. People who were not born then will find it difficult to believe, but the fact is that even then time was moving as fast as a cavalry-camel; it is not only nowadays that it does so. But in those days no one knew what it was moving towards. Nor could anyone quite distinguish between what was above and what below, between what was moving forwards and what backwards.

—Robert Musil, The Man Without Qualities, writing c. 1940 about the time c. 1918

Some things in nature have a knee. Exponential curves are not among them. There is no unambiguous point at which it really starts gettin’ going. Anything you point at as the knee is simply a matter of perspective. Above, as you mouse around, the curve does not change; the y-axis merely scales, and the “knee” appears to translate side to side.

(An exception might be if you were working in non-arbitrary units, in which case you could identify a point at which the slope passes 1, or a point of minimum radius of curvature. But that seems very rare.)

Sometimes folks try to identify “the knee” in some arc of human progress, especially a technological one. That may exist in some models of progress, but not if the progress is truly exponential. Some guy Theodore Modis addresses this in the context of Kurzweil’s The Singularity Is Near here in “The Singularity Myth” (2006). I think Taleb has also written a lot on the scalability of exponentials.

Graphic inspired by this one.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
html, body {
margin: 0;
padding: 0;
}
svg {
overflow: visible;
}
path {
fill: none;
stroke: black;
stroke-width: 1;
}
.axis path {
stroke: none;
}
rect {
pointer-events: all;
visibility: hidden;
}
path, text, line {
pointer-events: none;
}
</style>
<body></body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 20, right: 10, bottom: 20, left: 10},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
format = d3.format('.1e'),
resolution = 1000,
range = d3.scaleLinear()
.domain([0,resolution])
.range([-5,5])
var data = d3.range(resolution).map(function(d) {
return [range(d), Math.exp(range(d))]
})
var xExtent = d3.extent(data, function(d) { return d[0] }),
yExtent = d3.extent(data, function(d) { return d[1] })
var x = d3.scaleLinear()
.domain(xExtent)
.range([0, width])
var y = d3.scaleLinear()
.domain(yExtent)
.range([height, 0])
var xAxis = d3.axisBottom()
.scale(x)
var yAxis = d3.axisRight()
.scale(y)
.tickFormat(format)
var line = d3.line()
.x(function(d) { return x(d[0]) })
.y(function(d) { return y(d[1]) })
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var rect = svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
var xAxisG = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
var yAxisG = svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ",0)")
.call(yAxis)
var path = svg.append("path")
.datum(data)
.attr("d", line)
rect.on("mousemove", function() {
var pt = d3.mouse(this),
x0 = x.invert(pt[0]),
y0 = Math.exp(x0)
y.domain([0, y0 * (height / (height - pt[1]))])
path.attr("d", line)
yAxisG
.attr("transform", "translate(" + pt[0] + ",0)")
.call(yAxis)
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment