Skip to content

Instantly share code, notes, and snippets.

@newby-jay
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save newby-jay/177089781d487a9ee7f7 to your computer and use it in GitHub Desktop.
Save newby-jay/177089781d487a9ee7f7 to your computer and use it in GitHub Desktop.
Stochastic bistable switching
<!DOCTYPE html>
<html lang="en">
<head></head>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
tex: {extensions: ["color.js"]}});
</script>
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG">
</script>
<style>
body {
top: 100%;
left: 100%;
background: #002b36;
}
#QSAAnimation rect {
fill-opacity: .6;
fill: #ff3300;
}
#graphAnimation {
fill: #fff;
font: 10px serif;
}
.yaxis line, .yaxis path {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
.v.line, .f.line {
stroke-width: 1.5px;
shape-rendering: optimizeSpeed;
}
</style>
<body>
<table>
<tr>
<td style=" border-bottom: 1px solid #fff;"><div id="graphAnimation"></div></td>
<td style=" border-bottom: 1px solid #fff;"><div id="QSAAnimation"></div></td>
</tr>
<tr>
<td><p width="800" style="color:#fff; font: 32px sans-serif;">\[dX=-X(X^2-1)dt + \sqrt{\epsilon} dW\]</p></td>
<td><p width="800" style="color:#ff3300; font: 32px sans-serif; font-weight: 200;">histogram</p></td>
</tr>
</table>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="QSA.js"></script>
</body>
</html>
(function anim () {
var sigma = 0.4,
dt = 0.05,
x = -1,
t = 0,
nSamples = 1,
rn = d3.random.normal(0, sigma*Math.sqrt(dt));
function evolveSimulation() {
var i = 0;
while (i++ < 25) {
var f = -x*(x*x-1);
x += 1.5*f*dt + rn();
t += dt;
var iBin = Math.floor((1.6+x)*nBins/3.2);
if ((iBin>0)&&(iBin<=nBins)) {
nodes[iBin] ++;
nSamples ++;
}
}
}
function uniform(a, b) {
return a + (b - a)*Math.random(1);
}
function randint(a, b) {
r = uniform(a, b);
return Math.round(r);
}
/////////////////////////
//// animation setup ////
/////////////////////////
var QSAboxWidth = 300,
graphBoxSeparation = 0,
nBins = 50,
barWidth = 5,
graphWidth = 960 - QSAboxWidth - graphBoxSeparation,
graphHeight = 350,
channelRadius = 1.5,
cNa = "#FF4000", // orange
cK = "#0080FF"; // blue
//// svg
var graphSvg = d3.select("#graphAnimation")
.append("svg")
.attr("width", graphWidth)
.attr("height", graphHeight),
g = graphSvg.append("g"),
QSASvg = d3.select("#QSAAnimation")
.append("svg")
.attr("width", QSAboxWidth)
.attr("height", graphHeight);
/////////////////////////////
/////////// graph ///////////
/////////////////////////////
var xgraph = g.append("g"), // voltage graph
data = d3.range(2000).map(
function (i) {
return {t:-600 + 600*i/2000, x: -1};
});
function tsf(tc) {return -50 - t + tc;}
var xs = d3.scale.linear()
.domain([-1.6, 1.6])
.range([graphHeight-10, 5]),
xline = d3.svg.line()
.x(function(d, i) { return tsf(d.t); })
.y(function(d, i) { return xs(d.x); }),
//// axis for v
xaxis = xgraph
.attr("class", "yaxis")
.attr("transform", "translate(" + (graphWidth-5) + ", 0)")
.call(d3.svg.axis().scale(xs).orient("left").tickValues([-1.6, -1, 0, 1, 1.6]));
xpath = xgraph
.append("path")
.datum(data)
.attr("class", "v line")
.attr("d", xline);
var frameRate = 10;
function tick() {
// Main function that graphs voltage and ion channel fractions
data.push({t: t, x: x}); // get current values from simulation data
hist.transition().duration(frameRate)
.attr("width", function(d, i) {return hs(nodes[i]/nSamples); });
xpath.attr("d", xline).attr("transform", null)
.transition()
.duration(frameRate)
.ease("linear")
.each("end", function () {
data.shift();
evolveSimulation(); // evolve monte carlo simulation forward in time, which alters data
tick();
});
}
/////////////////////////////
var QSAbox = QSASvg.append("g"),
hs = d3.scale.linear()
.domain([0, 0.17])
.range([0, QSAboxWidth]);
var nodes = d3.range(nBins+1).map(function(i) {return 0;});
nodes[Math.floor(nBins*0.6/3.2)] = 100;
var hist = QSAbox.selectAll("rect")
.data(nodes).enter()
.append("rect")
.attr("x", 0)
.attr("height", barWidth)
.attr("y", function(d, i) {return xs(-1.6 + i*3.2/nBins)-barWidth/2; })
.attr("width", function(d, i) {return hs(nodes[i]/nSamples); });
tick();
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment