Public
Edited
Oct 4, 2023
Insert cell
Insert cell
params = ({
startYear: -443,
endYear: -374,
survived: 0.25,
extinctionRate: 0.25, // percent of the species per million years https://royalsocietypublishing.org/doi/10.1098/rstb.1998.0212
originationRate: 0.25, // percent of species per million years
initialSpecies: 20
})
Insert cell
function duration() {
return params.endYear - params.startYear;
}
Insert cell
function newSpecies(start) {
return { start: start };
}
Insert cell
data = {
return [...Array(params.initialSpecies).keys()].map((d) =>
newSpecies(params.startYear)
);
}
Insert cell
function stepper(data) {
for (let i = 1; i < duration(); i++) {
data = oneYear(params.startYear + i, data);
}
return data;
}
Insert cell
stepper(data)
Insert cell
function oneYear(year, data) {
data = data.map((d) => goesExtinct(year, d));
data = [...data, ...originate(year, data)];
return data;
}
Insert cell
oneYear(440, data)
Insert cell
function goesExtinct(year, species) {
if (Math.random() < params.extinctionRate && !species.end) {
species.end = year;
}
return species;
}
Insert cell
goesExtinct(440, data[2])
Insert cell
function originate(year, data) {
let alive = data.filter((d) => !d.end || d.end > year);
let newSpecies = [];
for (let i = 0; i < alive.length; i++) {
if (Math.random() < params.originationRate) {
newSpecies.push({ start: year });
}
}
return newSpecies;
}
Insert cell
originate(440, data)
Insert cell
{
let test = 0;
for (let i = 0; i < 100; i++) {
if (goesExtinct(400, { start: 0 }).end == 400) {
test++;
}
}
return test;
}
Insert cell
{
let test = 0;
for (let i = 0; i < 100; i++) {
test = test + originate(400, data).length;
}
return test / 100;
}
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