Published
Edited
Apr 21, 2020
Importers
6 stars
Insert cell
Insert cell
sma = n => arr => arr.map((d, i, arr) => d3.mean(arr.slice(i - n + 1, i + 1)))
Insert cell
Insert cell
Insert cell
// no normalization!
_convolve = filter => signal => {
const arr = [];
// offset centers the filter window on the current index of the signal
const offset = Math.floor(filter.length / 2);
// loop over each entry in the signal
for (let i = 0; i < signal.length; i++) {
let sum = 0;
for (let j = 0; j < filter.length; j++) {
const offsetI = i + j - offset;
// skip out-of-bounds entries
if (offsetI >= 0 && offsetI < signal.length) {
// sum the products of the filter entries and signal entries
sum += signal[i + j - offset] * filter[j];
}
}
arr.push(sum);
}
return arr;
}
Insert cell
Insert cell
_convolve([1, 1, 1])([1, -1, 1, -1, 1, -1])
Insert cell
_convolve([1, 2, 1])([1, -1, 1, -1, 1, -1])
Insert cell
Insert cell
_convolve([1, 2, 1])([1, 1, 1])
Insert cell
Insert cell
// with normalization!
convolve = filter => signal => {
const arr = [];
const offset = Math.floor(filter.length / 2);
for (let i = 0; i < signal.length; i++) {
let numerator = 0,
denominator = 0;
for (let j = 0; j < filter.length; j++) {
const offsetI = i + j - offset;
if (offsetI >= 0 && offsetI < signal.length) {
numerator += signal[i + j - offset] * filter[j];
denominator += filter[j];
}
}
arr.push(numerator / denominator);
}
return arr;
}
Insert cell
Insert cell
convolve([1, 1, 1])([1, -1, 1, -1, 1, -1])
Insert cell
convolve([1, 2, 1])([1, -1, 1, -1, 1, -1])
Insert cell
Insert cell
Insert cell
Insert cell
// calculates one row of pascal's triangle, i.e. the binomial coefficients, n choose 0 thru n choose n
// https://en.wikipedia.org/wiki/Pascal's_triangle#Calculating_a_row_or_diagonal_by_itself
binomialCoef = n => {
const arr = [1];
while (arr.length <= n) {
const k = arr.length;
arr.push((arr[k - 1] * (n + 1 - k)) / k);
}
return arr;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
convolveAlt = filter => signal =>
signal.map((_, i) => {
const [numerator, denominator] = filter.reduce(
([numerator, denominator], f, j) => {
const offsetI = i - Math.floor(filter.length / 2) + j;
return offsetI >= 0 && offsetI < signal.length
? [numerator + f * signal[offsetI], denominator + f]
: [numerator, denominator];
},
[0, 0]
);
return numerator / denominator;
})
Insert cell
binomialCoefAlt = n =>
Array(n)
.fill(true)
.reduce(
arr => (
arr.push((arr[arr.length - 1] * (n + 1 - arr.length)) / arr.length), arr
),
[1]
)
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