Published
Edited
Dec 7, 2018
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
stdlib = require( "https://unpkg.com/@stdlib/stdlib@0.0.32/dist/stdlib-flat.min.js" )
Insert cell
Insert cell
Insert cell
Insert cell
randu = stdlib.base.random.randu
Insert cell
Insert cell
randn = stdlib.base.random.normal
Insert cell
Insert cell
plot = stdlib.plot
Insert cell
Insert cell
linspace = stdlib.linspace
Insert cell
Insert cell
vdom2html = require( "https://wzrd.in/standalone/vdom-to-html@2.1" )
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
initial = [ 0.3, 0.7 ] // should sum to 1
Insert cell
Insert cell
transition = [[ 0.2, 0.8 ], [ 0.4, 0.6 ]] // each row should sum to 1
Insert cell
Insert cell
Insert cell
initial_state = ( randu() <= initial[0] ) ? 0 : 1
Insert cell
Insert cell
second_state = ( randu() <= transition[initial_state][0] ) ? 0 : 1
Insert cell
Insert cell
third_state = ( randu() <= transition[second_state][0] ) ? 0 : 1
Insert cell
Insert cell
state_sequence = {
var nsteps = 100;
var states;
var curr;
var i;

states = new Array( nsteps );
states[ 0 ] = initial_state;
curr = initial_state;
for ( i = 1; i < nsteps; i++ ) {
curr = ( randu() <= transition[curr][0] ) ? 0 : 1;
states[ i ] = curr;
}
return states;
}
Insert cell
Insert cell
plt = plot()
Insert cell
Insert cell
function configurePlot( plt, y, numStates ) {
// Disable auto-rendering, deferring, instead, to Observable:
plt.autoRender = false;
// Plot meta data:
plt.description = 'Markov chain simulated state sequence.';
plt.title = 'Simulated Markov Chain';
// Plot dimensions:
plt.width = 800; // pixels
// x-axis configuration:
plt.xLabel = 'Step';
plt.xMin = -1;
plt.xMax = y.length;
// y-axis configuration:
plt.yLabel = 'State';
plt.yMin = -0.1;
plt.yMax = (numStates-1) + 0.1;
plt.yNumTicks = numStates;
// Data point encoding:
plt.symbols = [ 'open-circle' ];
// Values along the abscissa (x-values) will simply be a linearly spaced array representing the step number:
plt.x = [ linspace(0, y.length-1, y.length) ];
// State sequence:
plt.y = [ y ];
return plt;
}
Insert cell
configurePlot( plt, state_sequence, 2 )
Insert cell
Insert cell
function renderPlot( plt, y, numStates ) {
configurePlot( plt, y, numStates );
return vdom2html( plt.render() );
}
Insert cell
Insert cell
html`${renderPlot(plt, state_sequence, 2)}`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function csum( arr ) {
var out;
var i;
out = [];
out.push( arr[ 0 ] );
for ( i = 1; i < arr.length; i++ ) {
out.push( out[ i-1 ] + arr[ i ] );
}
return out;
}
Insert cell
Insert cell
csum( [ 0.1, 0.3, 0.2, 0.1, 0.3 ] )
Insert cell
Insert cell
Insert cell
I = [ 0.1, 0.3, 0.2, 0.1, 0.3 ] // should sum to 1
Insert cell
Insert cell
A = {
var transition = new Array( 5 );
// Transition probabilities when in state s_0:
transition[ 0 ] = [ 0.2, 0.7, 0.1, 0.0, 0.0 ]; // should sum to 1
// Transition probabilities when in state s_1:
transition[ 1 ] = [ 0.4, 0.3, 0.25, 0.05, 0.0 ]; // should sum to 1
// Transition probabilities when in state s_2:
transition[ 2 ] = [ 0.05, 0.2, 0.4, 0.3, 0.05 ]; // should sum to 1
// Transition probabilities when in state s_3:
transition[ 3 ] = [ 0.02, 0.18, 0.2, 0.2, 0.4 ]; // should sum to 1
// Transition probabilities when in state s_4:
transition[ 4 ] = [ 0.3, 0.0, 0.0, 0.2, 0.5 ]; // should sum to 1
return transition;
}
Insert cell
Insert cell
function simulate( initial, transition, n ) {
var nStates;
var states;
var probs;
var r;
var i;
var j;
nStates = initial.length;
// Convert the initial probabilities to cumulative probabilities:
initial = csum( initial );
// Convert each set of transition probabilities to cumulative probabilities:
transition = transition.slice(); // avoid mutation
for ( i = 0; i < nStates; i++ ) {
transition[ i ] = csum( transition[ i ] );
}
// Define the output state array:
states = new Array( n );
// Determine the initial state:
r = randu();
for ( i = 0; i < nStates; i++ ) {
if ( r < initial[ i ] ) {
states[ 0 ] = i;
break;
}
}
// Simulate the next `n-1` steps:
for ( i = 0; i < n-1; i++ ) {
probs = transition[ states[i] ];
r = randu();
for ( j = 0; j < nStates; j++ ) {
if ( r < probs[ j ] ) {
states[ i+1 ] = j;
break;
}
}
}
return states;
}
Insert cell
Insert cell
Insert cell
seq = simulate( I, A, n )
Insert cell
Insert cell
plt2 = plot()
Insert cell
Insert cell
html`${renderPlot( plt2, seq, 5 ) }`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
I_corrupted = [ 0.1, 0.3, 0.2, 0.1, 0.3 ] // should sum to 1
Insert cell
Insert cell
A_corrupted = {
var transition = new Array( 5 );
// Transition probabilities when in state s_0:
transition[ 0 ] = [ 0.2, 0.7, 0.1, 0.0, 0.0 ]; // should sum to 1
// Transition probabilities when in state s_1:
transition[ 1 ] = [ 0.4, 0.3, 0.25, 0.05, 0.0 ]; // should sum to 1
// Transition probabilities when in state s_2:
transition[ 2 ] = [ 0.05, 0.2, 0.4, 0.3, 0.05 ]; // should sum to 1
// Transition probabilities when in state s_3:
transition[ 3 ] = [ 0.02, 0.18, 0.2, 0.2, 0.4 ]; // should sum to 1
// Transition probabilities when in state s_4:
transition[ 4 ] = [ 0.3, 0.0, 0.0, 0.2, 0.5 ]; // should sum to 1
return transition;
}
Insert cell
Insert cell
means = [ 0.2, 0.35, 0.5, 0.6, 0.8 ]
Insert cell
Insert cell
sigmas = [ 0.1, 0.1, 0.1, 0.1, 0.1 ]
Insert cell
Insert cell
function stateSequence( seq, means ) {
var states;
var i;
states = new Array( seq.length );
for ( i = 0; i < seq.length; i++ ) {
states[ i ] = means[ seq[i] ];
}
return states;
}
Insert cell
Insert cell
function corrupt( states, means, sigmas ) {
var state;
var out;
var i;
// Initialize an output array:
out = new Array( states.length );
// For each state, simulate a corrupted observation:
for ( i = 0; i < states.length; i++ ) {
state = states[ i ];
out[ i ] = randn( means[ state ], sigmas[ state ] );
}
return out;
}
Insert cell
Insert cell
Insert cell
seq_corrupted = simulate( I_corrupted, A_corrupted, n_corrupted )
Insert cell
Insert cell
obs = corrupt( seq_corrupted, means, sigmas )
Insert cell
Insert cell
plt3 = plot()
Insert cell
Insert cell
function configurePlotCorrupted( plt, corrupted, underlying ) {
var n;
var x;
n = corrupted.length;
// Disable auto-rendering, deferring, instead, to Observable:
plt.autoRender = false;
// Plot meta data:
plt.description = 'Simulated noisy time series.';
plt.title = 'Simulated Time Series';
plt.labels = [
'noisy',
'true'
];
// Plot dimensions:
plt.width = 800; // pixels
// x-axis configuration:
plt.xLabel = 'Step';
plt.xMin = -1;
plt.xMax = n;
// y-axis configuration:
plt.yLabel = 'Observation';
plt.yMin = 0.0;
plt.yMax = 1.0;
// Data point encoding:
plt.colors = [
'#1f77b4', // blue
'#d62728' // red
];
plt.symbols = 'none';
plt.lineOpacity = [ 1.0, 0.3 ];
// Values along the abscissa (x-values) will simply be a linearly spaced array representing the step number:
x = linspace(0, n-1, n);
plt.x = [ x, x ];
// Observations:
plt.y = [ corrupted, underlying ];
return plt;
}
Insert cell
Insert cell
function renderPlotCorrupted( plt, corrupted, underlying ) {
configurePlotCorrupted( plt, corrupted, underlying );
return vdom2html( plt.render() );
}
Insert cell
Insert cell
html`${renderPlotCorrupted( plt3, obs, stateSequence( seq_corrupted, means ) ) }`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more