Last active
August 29, 2015 14:17
-
-
Save newby-jay/177089781d487a9ee7f7 to your computer and use it in GitHub Desktop.
Stochastic bistable switching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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