Here I'll park various web demos, as they are constructed. Over the years (sigh) I've written a large number of audio/video interactive programs, often after suggestions by Steina and Woody Vasulka, to enable various installations. However, these were written using Quicktime, and even QuickDraw, 32-bit frameworks which have been "deprecated" for many years. Apple OSX operating systems used to be quite admirable in supporting executables from days of yore, but no more. From around OSX 10.13 onward, it has become increasingly difficult to use 32-bit applications, and access the built-in webcam as before. So what to do? If one is going to port code, where's the stable platform to port to? Apple has even "deprecated" OpenGL, which was considered a standard, in favor of a proprietary and probably ephemeral in-house graphics framework. So Apple is out, where do we go?

The answer seems to be, into the browser. WebGL allows use of the GPU in a browser, using OpenGL commands, and is probably not going away soon. An additional advantage is that being in a browser gives one independence from any particular operating system (though each of the major browsers have in fact its own peculiarities). Further, modern browsers implement WebAssembly, a binary code format that allows cross-compilation from, for example, C, into browser code which can run at near-native speed.

At the moment, Chrome-based browsers have trouble with these demos running under http, Firefox and Safari work fine. If you access them via https://robshaw.net:4433/rob-demos.html everything should work, even Chrome. For some reason, demos run in Chrome can initially stutter, and run at reduced speed. Reloading the page a couple of times seems to clear this problem up.

Balls

This is a first demo using WebAssembly. The original code is written in C, and the screen is accessed via SDL. Using the Emscripten package, it is possible to compile the code either to a native executable, or to a .wasm file, which gets loaded and run by the browser. The code runs in the browser typically around 80% native speed.

Video Cube Demo

  A minimal WebGL demo which uses the HTML5 call getUserMedia() to grab a video stream from the webcam, and apply it to the surfaces of a cube using minimal shaders. Assembled from old code fragments, sorry, credits have been lost.

Logistic Map Bifurcation Plot

  Here are plotted iterates of the logistic map x = rx(1-x) as a function of the parameter r. The parameter r varies along the horizontal axis from values (3.5, 4.0) and each iterate is plotted as a dot along the vertical axis, with values between (0, 1). The successive bifurcations as r is increased are apparent, you can pan across the diagram with the arrow keys, and zoom in/out with shift up/down arrow keys. This is now a familiar and canonical figure, prominantly featured, for example, in a wikipedia article, or two, or in a Wolfram Mathworld article. I believe this diagram was first constructed in Santa Cruz, back in the day, perhaps by Jim Crutchfield. In the intervening 40 years (ak!), readily-available CPU speeds have increased by a factor of something like 10,000, so it's now possible to compute this figure in real time. This WebAssembly demo can easily compute and display 500,000 iterates, at 60 frames a second. The limiting ratio of the r values of successive period-doubling bifurcations is called the Feigenbaum constant, after the late Mitchell Feigenbaum.

Simple Speed Test, Logistic Map

  This is a raw speed test, the default is to crank away at the logistic map, 100,000,000 iterations per display frame. My 2.9 GHz 2012 Macbook Pro runs at about 340 million iterations per second (mits) natively. In a browser, it runs typically at about 95% of this speed. Firefox currently seems a percent or so faster than the other browsers. This high speed is typical of computational tasks which can be accomplished in the registers, more complicated tasks typically run in the browser at around 80% of native speed. This is because memory accesses have to be checked, to make sure they are not trying to access something out of bounds. WebAssembly, like all browser code, is "sandboxed", we don't want some downloaded .html file doing something untoward to our local machine. For comparison, my $100 Lenovo smartphone runs the logistic map at about half the speed of a browser on the laptop.

The Three Body Problem

  Here is a simulation showing that it might be a bad idea to take up residence on a planet that is in a close orbit around a binary star. This is the "restricted three body problem", we have three coplanar objects, two of which are large (the stars), and are not perturbed by the third small body (the planet). The simulation starts off with an ensemble of 5000 "planets" which are initially very close in position and momentum. But, for these initial conditions, the system is chaotic, and the 5000 planets quickly proceed along different histories. Most of them end up crashing into one star or the other, and being incinerated. The remaining "survivors", around 900, are ejected from the binary system, at greater than the escape velocity, into the frigid reaches of outer space. It was possibly this example that led Poincaré to first appreciate what we now call low-dimensional chaos. You can experiment with different initial conditions wrt the phase of the binary star orbits by hitting the 'n' key, 's' and 'S' speeds up or slows down the simulation.

Elastic Hard Disk Experiments

  Here we have 3000 disks, initially confined to the right side of a chamber. After a transient, the partition is removed. A histogram shows the density of disks as a function of the x position. Note the "slosh". Question, how do we define a "slosh"? Here is a simulation, this time the histogram records the number of disks, as a function of the average speed. The red curve is the equilibrium Maxwell-Boltzmann distribution. The "slosh" can be seen as a deviation from the equilibrium distribution. The ideal gas doesn't slosh. Now what is plotted is the x position of the green balls. Note the rapid spreading. But if we do a simulation with interacting balls, the spreading of the green balls is slow, even with the dynamics. The system reaches equilibrium in momentum space rapidly, but slowly in configuration space, due to stearic hindering. I believe there is an old paper by Joel Lebowitz that mentions this effect, but I've lost the reference. All this could be quantified with p log p measures. There are various keyboard commands that might be of interest, 'n' restarts a simulation, 's' and 'S' changes the speed, 'h' cycles through various histograms. Again, there is some problem with Chrome, you may have to reload the page a few times to get the simulation to run at full speed.

Random Waves and Shaders

  Here's some more compulsive computation, of possible interest. Many years ago, Bill Burke introduced me to random wave patterns, generated by simply superposing monochromatic plane waves, traveling in random directions. The resulting patterns he called "refrigerator mold", and they show up in a lot of places, including studies of laser speckle, quantum chaos, and even in cosmology as will be suggested below. Sadly, he died in a traffic accident, and I was unable to show him my real-time simulations.

  The first problem, for the computers of that time, was that to make a picture, you needed to compute sines and/or cosines at each pixel, e.g. cos(kx-wt) for each traveling wave. That's a lot of cranking, which put real-time simulations out of reach 30 years ago. However, I noticed that, on a lattice, you can expand cos(kx-wt) with a trig identity, and get rid of the cosines. Effectively, to find the phase at an interior point, you integrate the harmonic oscillator equation in from the boundaries. Each pixel is only four multiplies per wave, instead of a cosine. That gave a speedup of something like four. Further, the PPC processors that Apple was using had something called "AltiVec", a vector unit which provided another factor of nearly four. This allowed some pretty nice real-time stuff, which Bill never saw.

  So this sat on the disk, gathering dust. But lately I thought I might resurrect the simulation. Computers have sped up more than an order of magnitude in the intervening time, and the Intel processors include an SSE vector unit, which is an easy port from AltiVec code. The result looked great, so I says to myself, says I, let's port this to WebAssembly, where people could see it in any browser. Well, after an embarrassing length of time, I found out that the SSE instructions haven't been ported to WebAssembly, only emulated (there is work on this though). The slow, nonvectorized CPU version can be run here. By clicking, or using a touch screen, you can cycle through a bunch of presets, with color maps, selected on an esthetic basis. There's a lower resolution version for phones, here.

  Well, what about shaders, to speed things up? The problem with the trick described above is that you have to compute the pixels in serial order, to propagate the phase from one pixel to the next. I didn't see a way that the many independent shaders could do that. So, what the heck, let's just try having the shaders do the sines and cosines, that way each pixel can be independently computed. The results were shocking to me. My 2012 2.9 GHz laptop, with vanilla built-in Intel GPU, can crank out more than 8 billion cosines per second, operating a factor of something like 60 faster than the SSE code. So it became worth it to do the WebAssembly port of the shader code. It was a total pain in the ass, with gotchas galore, and an absence of informative error messages. But it now runs. It's set up with a symmetric initial condition of 100 waves, with a little dispersion added so that the pattern over time becomes random, as will be discussed below. You can zoom in with up arrow, restart with 'n', speed up and slow down with 's' and 'S'. Color maps will be added "later". The clever trick has been completely obsoleted, hopefully not me along with it...

  Another surprise was that the WebAssembly running in the Chrome browser is actually a bit faster than native code. The shaders are compiled on the fly every time you run the code, and apparently, the Chrome shader compiler is better than the GLSL compiler built into OSX 12.

  I looked around the literature a little, found this competition, which uses Matlab (boo!) and starts with a sampled unit circle in k space, then uses a FFT to generate the pattern (that's cheating!). A direct comparison can't be made at this time, but I expect the GPU simulation to be about 10 times faster. Here's another accessible reference on this subject.

  Notice how this simulation naturally generates "walls" and "voids". A quantum-mechanical eigenfunction of a higher energy state is expected to look like this, a funny-shaped boundary classically will generate a chaotic billiard path. We just have the Helmholtz equation on a funny-shaped drum. This work is partially motivated by a desire to understand "quantum chaos". I might be late to the party, but the party is far from over!

  Further, these patterns are qualitatively reminiscent of galaxy distributions, collected along thin slices projected out into space. Note the walls and voids. Coincidence?? (Cue the Twilight Zone music). Maybe not. There is a cosmological theory that the anisotropies observed in galaxy distributions are due to baryon acoustic oscillations, sound density waves traveling, presumably in random directions, in the early universe plasma. When things cooled off enough that atoms could combine, photons could freely travel, and the pattern became frozen. A particular wavelength was favored, the baryon acoustic peak, hence the similarity in the patterns.

  To reveal a trick, a pure superposition of monochromatic waves traveling at constant velocity would generate a basically static pattern that locally simply cycles every two pi. This is visually uninteresting, and perhaps unphysical. To get the squirmy effect seen, a small dispersion is added to the energy; the superposed waves have the same wavelength, but travel at different speeds. This effectively moves the pattern through an ensemble of possible pictures, generated by random phases of the superposed waves. Any single snapshot is a correct member of the ensemble.

Scott-Gray Reaction-Diffusion Equations

  The above simulations were written in C, and ported to WebAssembly using Emscripten. However, when I tried to port trickier shaders, which implement reaction-diffusion systems, I started to run into problems. Apparently browsers have WebGL limitations on their shaders, and I couldn't get around them. So rather than write in C, I was forced to call shaders from javascript, using WebGL. This is OK, as I'm going to be using the camera, and will have to use the HTML5 call getUserMedia(), and javascript anyway, as in the video cube demo above. For CPU-intensive tasks, one can still make WebAssembly calls into C code from javascript.   There are a bunch of WebGL examples of reaction-diffusion on the web, the nicest example I found was work by Robin Houston. This is a piece of art code, minimal, though with error messages, and attractively free of licensing. Other good collections can be found here and here.

  My version uses a color map, for esthetic effect. The 'n' key will reset the initial condition, and the 'N' key will give a blank initial condition. You can then use the mouse to perturb the system. More bells and whistles will be added "later".

Array of Locally Coupled Limit Cycles

  Here is a simulation consisting of a 512 x 512 array of limit cycles, each one diffusively coupled to the four nearest neighbors. As in the Scott-Gray example above, this is written in straight WebGL, the source can be directly examined via the browser. The limit cycle used is the Schnakenberg system, which has the advantage that the limit cycle calculation supplied to the updater requires only two multiplies, and a few adds. The cycle is a model for a periodic chemical reaction of the Belusov-Zhabotinsky type.

  Try perturbing the system by dragging the mouse around, you'll find that a strong enough perturbation will disrupt the global phase coherence, and nucleate pairs of Winfree-type phase singularities. The 'n' or 'N' key will reset the initial conditions, the 'a' key toggles between a direct display of one of the chemical species, and a display of the "amplitude" of the limit cycle.



Research Interests   Curriculum Vitae  Other Stuff