Skip to content

Commit 4a844c8

Browse files
committed
Add bivariate gaussian demo
1 parent 5b4f26a commit 4a844c8

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

redirects/bivariate-gaussian.html

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Bivariate Gaussian Joint Density</title>
7+
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
8+
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js"></script>
9+
<style>
10+
body {
11+
font-family: 'Arial', sans-serif;
12+
background-color: #f4f4f9;
13+
margin: 0;
14+
padding: 0;
15+
}
16+
.container {
17+
max-width: 1200px;
18+
margin: 0 auto;
19+
padding: 20px;
20+
}
21+
.header {
22+
text-align: center;
23+
padding: 20px;
24+
}
25+
.controls {
26+
display: flex;
27+
justify-content: center;
28+
flex-wrap: wrap;
29+
margin-bottom: 20px;
30+
}
31+
.control-group {
32+
margin: 10px;
33+
padding: 10px;
34+
background-color: #ffffff;
35+
border: 1px solid #ddd;
36+
border-radius: 5px;
37+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
38+
}
39+
.control-group label {
40+
display: block;
41+
margin-bottom: 5px;
42+
}
43+
.control-group input[type="range"] {
44+
width: 200px;
45+
}
46+
.plots {
47+
display: grid;
48+
grid-template-columns: 1fr 1fr;
49+
gap: 20px;
50+
}
51+
.plot {
52+
width: 100%;
53+
height: 400px;
54+
}
55+
</style>
56+
</head>
57+
<body>
58+
<div class="container">
59+
<div class="header">
60+
<h1>Joint Density of Bivariate Gaussian Random Variables</h1>
61+
</div>
62+
63+
<div style="margin:0 20px 20px 20px;">This demonstration shows a 3D plot and a plot of a bivariate
64+
Gaussian (Normal) density with zero means. The standard deviations
65+
and correlation coefficient for
66+
the random variables can be adjusted by moving the sliders. Hold
67+
down the mouse button on the 3D surface plot and drag around to
68+
change the viewing perspective.
69+
</div>
70+
71+
<div class="controls">
72+
<div class="control-group">
73+
<label for="std_x">Standard Deviation of X: <span id="std_x_val">1</span></label>
74+
<input type="range" id="std_x" min="0.01" max="2" step="0.01" value="1">
75+
</div>
76+
<div class="control-group">
77+
<label for="std_y">Standard Deviation of Y: <span id="std_y_val">1</span></label>
78+
<input type="range" id="std_y" min="0.01" max="2" step="0.01" value="1">
79+
</div>
80+
<div class="control-group">
81+
<label for="rho">Correlation Coefficient: <span id="rho_val">0</span></label>
82+
<input type="range" id="rho" min="-0.99" max="0.99" step="0.01" value="0">
83+
</div>
84+
</div>
85+
86+
<div class="plots">
87+
<div id="plot_surface" class="plot"></div>
88+
<div id="plot_heatmap" class="plot"></div>
89+
</div>
90+
</div>
91+
92+
<H3 style="margin-left:100px;">Some Things to Try</H3>
93+
<div style="margin-left:110px;width:800px;">
94+
<ol>
95+
<li style="margin-top:1em;"> Start with the default variances of 1 and note the effect of changing the correlation coefficient. What are the possible angles of the major axis of the ellipses you create?</li>
96+
<li style="margin-top:1em;"> Now set the correlation coefficient to a value close to +1. Adjust the standard deviations for the two random variables. What are the possible angles of the major axis of the ellipses you create?</li>
97+
<li style="margin-top:1em;"> Now set the correlation coefficient to a value close to -1. Then adjust the standard deviations for the two random variables. What are the possible angles of the major axis of the ellipses you create?</li>
98+
</ol>
99+
</div>
100+
<script>
101+
const std_x_elem = document.getElementById('std_x');
102+
const std_y_elem = document.getElementById('std_y');
103+
const rho_elem = document.getElementById('rho');
104+
105+
const std_x_val_elem = document.getElementById('std_x_val');
106+
const std_y_val_elem = document.getElementById('std_y_val');
107+
const rho_val_elem = document.getElementById('rho_val');
108+
109+
std_x_elem.oninput = () => { std_x_val_elem.textContent = std_x_elem.value; updatePlots(); };
110+
std_y_elem.oninput = () => { std_y_val_elem.textContent = std_y_elem.value; updatePlots(); };
111+
rho_elem.oninput = () => { rho_val_elem.textContent = rho_elem.value; updatePlots(); };
112+
113+
var firstTime = true;
114+
115+
function updatePlots() {
116+
const std_x = parseFloat(std_x_elem.value);
117+
const std_y = parseFloat(std_y_elem.value);
118+
const rho = parseFloat(rho_elem.value);
119+
120+
const mean = [0, 0];
121+
var rho2 = rho;
122+
if (rho2==1) {
123+
rho2=0.999;
124+
} else if (rho2==-1) {
125+
rho2=-0.999;
126+
}
127+
const cov = [[std_x ** 2, rho2 * std_x * std_y], [rho2 * std_x * std_y, std_y ** 2]];
128+
129+
const x_vals = numeric.linspace(-3, 3, 100);
130+
const y_vals = numeric.linspace(-3, 3, 100);
131+
132+
const X = [];
133+
const Y = [];
134+
for (let i = 0; i < x_vals.length; i++) {
135+
for (let j = 0; j < y_vals.length; j++) {
136+
X.push([x_vals[i], y_vals[j]]);
137+
}
138+
}
139+
140+
const inv_cov = numeric.inv(cov);
141+
const det_cov = numeric.det(cov);
142+
const norm_const = 1 / (2 * Math.PI * Math.sqrt(det_cov));
143+
144+
const mvn_pdf = (pos, mean, inv_cov) => {
145+
const exponent = numeric.dotVV(numeric.dot(pos, inv_cov), pos);
146+
return norm_const*Math.exp(-0.5*exponent);
147+
};
148+
149+
const Z = numeric.rep([100, 100], 0);
150+
for (let i = 0; i < x_vals.length; i++) {
151+
for (let j = 0; j < y_vals.length; j++) {
152+
Z[i][j] = mvn_pdf(X[i + x_vals.length * j], mean, inv_cov);
153+
}
154+
}
155+
156+
const data_surface = [{
157+
z: Z,
158+
x: x_vals,
159+
y: y_vals,
160+
type: 'surface',
161+
showscale: false // Hide the colorbar
162+
}];
163+
164+
const data_heatmap = [{
165+
z: Z,
166+
x: x_vals,
167+
y: y_vals,
168+
type: 'heatmap',
169+
}];
170+
171+
const layout = {
172+
margin: { l: 0, r: 0, b: 0, t: 0 },
173+
};
174+
175+
const layout_surface = {
176+
margin: { l: 0, r: 0, b: 0, t: 0 },
177+
uirevision:true,
178+
scene: {
179+
camera: {
180+
eye: { x: -0.5, y: -2, z: 1.5 },
181+
up: { x: 0, y: 0, z: 1 },
182+
center: { x: 0, y: 0, z: 0 },
183+
}
184+
}
185+
};
186+
var fig = Plotly.react('plot_surface', data_surface, layout_surface);
187+
Plotly.react('plot_heatmap', data_heatmap, layout);
188+
}
189+
190+
window.onload = updatePlots;
191+
</script>
192+
193+
194+
195+
</body>
196+
</html>

0 commit comments

Comments
 (0)