awacke1's picture
Update index.html
314c009 verified
raw
history blame
3.41 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Gradient-Free BOED via Interacting Particle Systems</title>
<style>
body { margin: 0; overflow: hidden; }
#info {
position: absolute;
top: 10px; left: 10px;
color: #fff;
font-family: sans-serif;
background: rgba(0,0,0,0.4);
padding: 8px 12px;
border-radius: 4px;
font-size: 14px;
}
</style>
</head>
<body>
<div id="info">
<strong>Particles:</strong> Ensemble Kalman Inversion (attraction to mean)<br/>
<strong>Noise:</strong> Affine-Invariant Langevin Dynamics
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
<script>
// --- SCENE SETUP ---
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 50);
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new THREE.OrbitControls(camera, renderer.domElement);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// --- PARTICLE SYSTEM PARAMETERS ---
const PARTICLE_COUNT = 100;
const particles = [];
const geometry = new THREE.SphereGeometry(0.5, 8, 8);
// Initialize particles with random positions
for (let i = 0; i < PARTICLE_COUNT; i++) {
let material = new THREE.MeshBasicMaterial({
color: new THREE.Color(Math.random(), Math.random(), Math.random())
});
let p = new THREE.Mesh(geometry, material);
p.position.set(
(Math.random() - 0.5) * 40,
(Math.random() - 0.5) * 40,
(Math.random() - 0.5) * 40
);
particles.push(p);
scene.add(p);
}
// --- UPDATE LOOP ---
function updateParticles() {
// 1) Compute ensemble mean
let mean = new THREE.Vector3();
particles.forEach(p => mean.add(p.position));
mean.divideScalar(PARTICLE_COUNT);
// 2) Compute a rough measure of covariance (average squared distance)
let cov = 0;
particles.forEach(p => cov += p.position.distanceToSquared(mean));
cov /= PARTICLE_COUNT;
// 3) For each particle: apply EKI‐style attraction + ALDI noise
const attractionStrength = 0.01;
const noiseScale = 0.1 * Math.sqrt(cov);
particles.forEach(p => {
// Attraction toward mean (EKI)
let toMean = mean.clone().sub(p.position).multiplyScalar(attractionStrength);
// Affine-Invariant Langevin noise
let noise = new THREE.Vector3(
(Math.random() - 0.5),
(Math.random() - 0.5),
(Math.random() - 0.5)
).multiplyScalar(noiseScale);
// Update position
p.position.add(toMean).add(noise);
});
}
// --- RENDER LOOP ---
function animate() {
requestAnimationFrame(animate);
updateParticles();
controls.update();
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>