Docs: Update benchmark for test 3

This commit is contained in:
github-actions[bot]
2026-03-05 08:30:33 +00:00
parent 72c85a5d2e
commit ce29d3273a
15 changed files with 783 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
async function analyzeSignal(yamlString) {
const [
{ default: jsYaml },
math,
{ default: ndarray },
ndarrayFft,
DOMPurify
] = await Promise.all([
import('https://esm.sh/js-yaml'),
import('https://esm.sh/mathjs'),
import('https://esm.sh/ndarray'),
import('https://esm.sh/ndarray-fft'),
import('https://esm.sh/dompurify')
]);
const cfg = jsYaml.load(yamlString);
const N = cfg.sampleRate * cfg.duration;
const signal = Array(N).fill(0).map((_, i) => {
const t = i / cfg.sampleRate;
return cfg.components.reduce((s, c) =>
s + c.amplitude * math.sin(2 * math.pi * c.frequency * t), 0);
});
const real = ndarray(new Float64Array(signal), [N]);
const imag = ndarray(new Float64Array(N), [N]);
ndarrayFft(1, real, imag);
const half = N / 2;
const mags = Array(half + 1).fill(0).map((_, k) =>
math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / half);
const peaks = mags
.map((m, k) => ({ frequencyHz: Math.round(k * cfg.sampleRate / N), magnitude: +m.toFixed(2) }))
.filter(p => p.magnitude > 0.1)
.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('');
const html = DOMPurify.sanitize(
`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`
);
return { peaks, html, signalLength: N };
}
export default analyzeSignal;
// Generation time: 6.922s
// Result: FAIL

View File

@@ -0,0 +1,62 @@
async function analyzeSignal(yamlString) {
const [
jsYaml,
math,
ndarray,
ndarrayFft,
DOMPurify
] = await Promise.all([
import("https://cdn.jsdelivr.net/npm/js-yaml@4/+esm").then(m => m.default || m),
import("https://cdn.jsdelivr.net/npm/mathjs@13/+esm").then(m => m.default || m),
import("https://cdn.jsdelivr.net/npm/ndarray@1/+esm").then(m => m.default || m),
import("https://cdn.jsdelivr.net/npm/ndarray-fft@1/+esm").then(m => m.default || m),
import("https://cdn.jsdelivr.net/npm/dompurify@3/+esm").then(m => m.default || m),
]);
const config = jsYaml.load(yamlString);
const { sampleRate, duration, components } = config;
const N = sampleRate * duration;
const signalData = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / sampleRate;
let sum = 0;
for (const { frequency, amplitude } of components)
sum += amplitude * math.sin(2 * math.pi * frequency * t);
signalData[i] = sum;
}
const real = ndarray(new Float64Array(signalData), [N]);
const imag = ndarray(new Float64Array(N), [N]);
ndarrayFft(1, real, imag);
const half = N / 2;
const magnitudes = [];
for (let k = 0; k <= half; k++) {
const r = real.get(k);
const im = imag.get(k);
magnitudes.push(math.sqrt(r ** 2 + im ** 2) / half);
}
const peaks = magnitudes
.map((mag, k) => ({
frequencyHz: Math.round(k * sampleRate / N),
magnitude: Math.round(mag * 100) / 100
}))
.filter(p => p.magnitude > 0.1)
.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks
.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`)
.join("");
const html = DOMPurify.sanitize(
`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`
);
return { peaks, html, signalLength: N };
}
export default analyzeSignal;
// Generation time: 9.844s
// Result: PASS

View File

@@ -0,0 +1,54 @@
const analyzeSignal = async (yamlStr) => {
const [
{ load: loadYaml },
math,
ndarray,
{ fft },
DOMPurify
] = await Promise.all([
import('https://cdn.jsdelivr.net/npm/js-yaml@4/dist/js-yaml.mjs'),
import('https://cdn.jsdelivr.net/npm/mathjs@12/lib/esm/index.js'),
import('https://cdn.jsdelivr.net/npm/ndarray@1/+esm'),
import('https://cdn.jsdelivr.net/npm/ndarray-fft@1/+esm'),
import('https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.es.mjs')
]);
const config = loadYaml(yamlStr);
const N = config.sampleRate * config.duration;
const signal = Array.from({ length: N }, (_, i) => {
const t = i / config.sampleRate;
return config.components.reduce((sum, { frequency, amplitude }) =>
sum + amplitude * math.sin(2 * math.pi * frequency * t), 0);
});
const real = ndarray(new Float64Array(signal), [N]);
const imag = ndarray(new Float64Array(N), [N]);
fft(1, real, imag);
const magnitude = Array.from({ length: Math.floor(N / 2) + 1 }, (_, k) =>
math.sqrt(math.pow(real.get(k), 2) + math.pow(imag.get(k), 2)) / (N / 2));
const peaks = magnitude
.map((mag, k) => ({
frequencyHz: Math.round(k * config.sampleRate / N),
magnitude: Math.round(mag * 100) / 100
}))
.filter(({ magnitude }) => magnitude > 0.1)
.sort((a, b) => b.magnitude - a.magnitude);
const html = `<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${
peaks.map(({ frequencyHz, magnitude }) =>
`<tr><td>${frequencyHz}</td><td>${magnitude}</td></tr>`).join('')
}</table>`;
return {
peaks,
html: DOMPurify.sanitize(html),
signalLength: N
};
};
export default analyzeSignal;
// Generation time: 8.641s
// Result: FAIL

View File

@@ -0,0 +1,60 @@
async function analyzeSignal(yamlString) {
const CDN = "https://cdn.jsdelivr.net/npm";
const [{ default: jsyaml }, { create, all }, { default: ndarray }, { default: fft }, { default: DOMPurify }] =
await Promise.all([
import(`${CDN}/js-yaml/dist/js-yaml.mjs`),
import(`${CDN}/mathjs/src/entry/allLimitedExports.mjs`),
import(`${CDN}/ndarray/ndarray.mjs`),
import(`${CDN}/ndarray-fft/dist/ndarray-fft.mjs`),
import(`${CDN}/dompurify/dist/purify.es.mjs`),
]);
const math = create(all);
const config = jsyaml.load(yamlString);
const { sampleRate, duration, components } = config;
const N = sampleRate * duration;
const signal = Array.from({ length: N }, (_, i) => {
const t = i / sampleRate;
return components.reduce((sum, { frequency, amplitude }) =>
sum + amplitude * math.sin(2 * math.pi * frequency * t), 0);
});
const realData = new Float64Array(signal);
const imagData = new Float64Array(N);
const real = ndarray(realData, [N]);
const imag = ndarray(imagData, [N]);
fft(1, real, imag);
const half = N / 2;
const magnitude = Array.from({ length: half + 1 }, (_, k) =>
math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / half
);
const peaks = magnitude
.reduce((acc, mag, k) => {
if (mag > 0.1) acc.push({
frequencyHz: Math.round(k * sampleRate / N),
magnitude: Math.round(mag * 100) / 100,
});
return acc;
}, [])
.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks.map(({ frequencyHz, magnitude }) =>
`<tr><td>${frequencyHz}</td><td>${magnitude}</td></tr>`
).join("");
const rawHtml =
`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`;
const html = DOMPurify.sanitize(rawHtml);
return { peaks, html, signalLength: N };
}
export default analyzeSignal;
// Generation time: 8.705s
// Result: FAIL

View File

@@ -0,0 +1,59 @@
const analyzeSignal = async (yamlString) => {
const { load } = await import('https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/+esm');
const math = await import('https://cdn.jsdelivr.net/npm/mathjs@11.9.1/+esm');
const ndarray = await import('https://cdn.jsdelivr.net/npm/ndarray@1.0.19/+esm');
const fft = await import('https://cdn.jsdelivr.net/npm/ndarray-fft@1.0.6/+esm');
const DOMPurify = await import('https://cdn.jsdelivr.net/npm/dompurify@3.0.6/+esm');
const config = load(yamlString);
const { sampleRate, duration, components } = config;
const N = sampleRate * duration;
const signal = new Float64Array(N);
for (let i = 0; i < N; i++) {
let t = i / sampleRate;
let value = 0;
for (const comp of components) {
value += comp.amplitude * math.sin(2 * math.pi * comp.frequency * t);
}
signal[i] = value;
}
const real = ndarray.default(signal.slice());
const imag = ndarray.default(new Float64Array(N));
fft.default(1, real, imag);
const magnitudes = [];
const halfN = Math.floor(N / 2);
for (let k = 0; k <= halfN; k++) {
const re = real.get(k);
const im = imag.get(k);
magnitudes[k] = Math.sqrt(re * re + im * im) / halfN;
}
const peaks = [];
for (let k = 0; k <= halfN; k++) {
if (magnitudes[k] > 0.1) {
peaks.push({
frequencyHz: Math.round(k * sampleRate / N),
magnitude: Math.round(magnitudes[k] * 100) / 100
});
}
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
let html = `<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>`;
peaks.forEach(p => {
html += `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`;
});
html += `</table>`;
return {
peaks,
html: DOMPurify.default.sanitize(html),
signalLength: N
};
};
export default analyzeSignal;
// Generation time: 19.364s
// Result: FAIL

View File

@@ -0,0 +1,54 @@
async function analyzeSignal(yamlStr) {
const [
{ load: parseYaml },
math,
ndarray,
fft,
{ default: purify }
] = await Promise.all([
import('https://cdn.skypack.dev/js-yaml'),
import('https://cdn.skypack.dev/mathjs'),
import('https://cdn.skypack.dev/ndarray'),
import('https://cdn.skypack.dev/ndarray-fft'),
import('https://cdn.skypack.dev/dompurify')
]);
const { sampleRate: fs, duration, components } = parseYaml(yamlStr);
const N = fs * duration;
const signal = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / fs;
signal[i] = components.reduce((acc, { frequency: f, amplitude: a }) =>
acc + a * math.sin(2 * math.pi * f * t), 0);
}
const real = ndarray(new Float64Array(signal), [N]);
const imag = ndarray(new Float64Array(N), [N]);
fft(1, real, imag);
const peaks = [];
for (let k = 0; k <= N / 2; k++) {
const mag = math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / (N / 2);
if (mag > 0.1) {
peaks.push({
frequencyHz: Math.round(k * fs / N),
magnitude: +mag.toFixed(2)
});
}
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('');
const rawHtml = `<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`;
return {
peaks,
html: purify.sanitize(rawHtml),
signalLength: N
};
}
export default analyzeSignal;
// Generation time: 4.379s
// Result: FAIL

View File

@@ -0,0 +1,50 @@
const analyzeSignal = async (yamlInput) => {
const cdn = 'https://esm.sh/',
[Yaml, MathPkg, ndarray, fft, DOMPurify] = await Promise.all(
['js-yaml', 'mathjs', 'ndarray', 'ndarray-fft', 'dompurify'].map(lib =>
import(`${cdn}${lib}`).then(m => m.default || m)
)
);
const { sampleRate: sr, duration: dur, components: comps } = Yaml.load(yamlInput),
N = sr * dur,
realData = new Float64Array(N),
imagData = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / sr;
realData[i] = comps.reduce((acc, { frequency: f, amplitude: a }) =>
acc + a * MathPkg.sin(2 * MathPkg.pi * f * t), 0);
}
const r = ndarray(realData, [N]),
i = ndarray(imagData, [N]);
fft(1, r, i);
const peaks = [];
for (let k = 0; k <= N / 2; k++) {
const mag = MathPkg.sqrt(r.get(k) ** 2 + i.get(k) ** 2) / (N / 2);
if (mag > 0.1) {
peaks.push({
frequencyHz: Math.round(k * sr / N),
magnitude: +mag.toFixed(2)
});
}
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join(''),
rawHtml = `<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`,
purifier = DOMPurify(self);
return {
peaks,
html: purifier.sanitize(rawHtml),
signalLength: N
};
};
export default analyzeSignal;
// Generation time: 50.247s
// Result: PASS

View File

@@ -0,0 +1,42 @@
async function analyzeSignal(yaml) {
const [yamlLib, math, ndarray, fft, purify] = await Promise.all([
import('https://cdn.skypack.dev/js-yaml'),
import('https://cdn.skypack.dev/mathjs'),
import('https://cdn.skypack.dev/ndarray'),
import('https://cdn.skypack.dev/ndarray-fft'),
import('https://cdn.skypack.dev/dompurify')
]);
const { sampleRate, duration, components } = yamlLib.load(yaml);
const N = sampleRate * duration;
const real = ndarray(new Float64Array(N));
const imag = ndarray(new Float64Array(N));
for (let i = 0; i < N; i++) {
const t = i / sampleRate;
real.set(i, components.reduce((acc, c) =>
acc + c.amplitude * math.sin(2 * math.pi * c.frequency * t), 0));
}
fft(1, real, imag);
const peaks = [];
for (let k = 0; k <= N / 2; k++) {
const mag = math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / (N / 2);
if (mag > 0.1) peaks.push({
frequencyHz: Math.round(k * sampleRate / N),
magnitude: Math.round(mag * 100) / 100
});
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
const html = purify.sanitize(`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>` +
peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('') +
`</table>`);
return { peaks, html, signalLength: N };
}
export default analyzeSignal;
// Generation time: 2.100s
// Result: FAIL

View File

@@ -0,0 +1,44 @@
export async function analyzeSignal(y) {
const [yM, mM, nM, fM, dM] = await Promise.all([
'js-yaml', 'mathjs', 'ndarray', 'ndarray-fft', 'dompurify'
].map(p => import(`https://esm.sh/${p}`)));
const load = yM.load || yM.default.load || yM.default;
const { sin, pi, sqrt } = mM.default || mM;
const ndarray = nM.default || nM;
const fft = fM.default || fM;
const DP = dM.default || dM;
const c = load(y);
const N = c.sampleRate * c.duration;
const R = new Float64Array(N), I = new Float64Array(N);
for (let i = 0; i < N; i++) {
let t = i / c.sampleRate, s = 0;
for (const p of c.components) s += p.amplitude * sin(2 * pi * p.frequency * t);
R[i] = s;
}
const r = ndarray(R), img = ndarray(I);
fft(1, r, img);
const pks = [], norm = N / 2;
for (let k = 0; k <= norm; k++) {
const m = sqrt(r.get(k) ** 2 + img.get(k) ** 2) / norm;
if (m > 0.1) pks.push({
frequencyHz: Math.round(k * c.sampleRate / N),
magnitude: +m.toFixed(2)
});
}
pks.sort((a, b) => b.magnitude - a.magnitude);
const h = `<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${
pks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('')
}</table>`;
return { peaks: pks, html: DP.sanitize(h), signalLength: N };
}
export default analyzeSignal;
// Generation time: 50.698s
// Result: PASS

View File

@@ -0,0 +1,68 @@
let _jsYaml, _math, _ndarray, _fft, _purify;
if (!_jsYaml) {
_jsYaml = (await import('https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.mjs')).default;
}
const { sampleRate, duration, components } = _jsYaml.load(yamlString);
const N = sampleRate * duration;
if (!_math) {
_math = await import('https://cdn.jsdelivr.net/npm/mathjs@11.8.0/lib/esm/index.js');
}
const signal = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / sampleRate;
let sum = 0;
for (const { frequency, amplitude } of components) {
sum += amplitude * _math.sin(2 * _math.pi * frequency * t);
}
signal[i] = sum;
}
if (!_ndarray) {
const ndMod = await import('https://cdn.jsdelivr.net/npm/ndarray@1.0.19/index.mjs');
_ndarray = ndMod.default || ndMod.ndarray;
}
if (!_fft) {
const fftMod = await import('https://cdn.jsdelivr.net/npm/ndarray-fft@1.0.0/index.mjs');
_fft = fftMod.fft || fftMod.default;
}
if (!_purify) {
const purifyMod = await import('https://cdn.jsdelivr.net/npm/dompurify@3.0.3/dist/purify.es.js');
_purify = purifyMod.default || purifyMod;
}
const real = _ndarray(signal, [N]);
const imag = _ndarray(new Float64Array(N), [N]);
_fft(1, real, imag);
const half = N / 2;
const peaks = [];
for (let k = 0; k <= half; k++) {
const re = real.get(k);
const im = imag.get(k);
const mag = _math.sqrt(re * re + im * im) / half;
if (mag > 0.1) {
const freq = Math.round(k * sampleRate / N);
const magRounded = Math.round(mag * 100) / 100;
peaks.push({ frequencyHz: freq, magnitude: magRounded });
}
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
let html = '<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>';
for (const p of peaks) {
html += `<tr><td>${p.frequencyHz}</td><td>${p.magnitude.toFixed(2)}</td></tr>`;
}
html += '</table>';
const sanitized = _purify.sanitize(html);
return { peaks, html: sanitized, signalLength: N };
}
export default analyzeSignal;
// Generation time: 94.075s
// Result: FAIL

View File

@@ -0,0 +1,27 @@
const analyzeSignal=async y=>{
const[{load},{sin,pi,sqrt},ndarray,fft,{default:DOMPurify}]=await Promise.all([
import('https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.mjs'),
import('https://cdn.jsdelivr.net/npm/mathjs@11.8.0/lib/esm/index.js'),
import('https://cdn.jsdelivr.net/npm/ndarray@1.0.19/+esm'),
import('https://cdn.jsdelivr.net/npm/ndarray-fft@1.0.3/+esm'),
import('https://cdn.jsdelivr.net/npm/dompurify@3.0.3/dist/purify.es.mjs')
]);
const{sampleRate:s,duration:d,components:c}=load(y),N=s*d,
signal=Array(N).fill().map((_,i)=>{
const t=i/s;
return c.reduce((a,{frequency:f,amplitude:m})=>a+m*sin(2*pi*f*t),0)
}),
real=ndarray(signal),
imag=ndarray(Array(N).fill(0));
fft(1,real,imag);
const H=N/2,
mags=Array(H+1).fill().map((_,k)=>sqrt(real.get(k)**2+imag.get(k)**2)/H),
peaks=mags.map((m,k)=>({frequencyHz:Math.round(k*s/N),magnitude:Math.round(m*100)/100}))
.filter(p=>p.magnitude>.1)
.sort((a,b)=>b.magnitude-a.magnitude),
html=`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${peaks.map(p=>`<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('')}</table>`;
return{peaks,html:DOMPurify.sanitize(html),signalLength:N}
}
export default analyzeSignal;
// Generation time: 171.544s
// Result: FAIL

View File

@@ -0,0 +1,64 @@
const libsPromise = (async () => {
const [y, m, n, f, d] = await Promise.all([
import("https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/+esm"),
import("https://esm.sh/mathjs@13.0.3"),
import("https://esm.sh/ndarray@1.0.19"),
import("https://esm.sh/ndarray-fft@1.0.3"),
import("https://unpkg.com/dompurify@3.1.6/dist/purify.es.mjs")
]);
return {
yaml: y.default?.load ? y.default : y,
math: m.default?.sin ? m.default : m,
ndarray: n.default || n,
fft: f.default || f.fft || f,
DOMPurify: d.default?.sanitize ? d.default : d
};
})();
async function analyzeSignal(yamlString) {
const { yaml, math, ndarray, fft, DOMPurify } = await libsPromise;
const cfg = yaml.load(String(yamlString || "")) || {};
const sampleRate = Number(cfg.sampleRate) || 64;
const duration = Number(cfg.duration) || 1;
const components = Array.isArray(cfg.components) ? cfg.components : [];
const N = Math.max(1, Math.floor(sampleRate * duration));
const signal = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / sampleRate;
let v = 0;
for (let j = 0; j < components.length; j++) {
const c = components[j] || {};
v += (Number(c.amplitude) || 0) * math.sin(2 * math.pi * (Number(c.frequency) || 0) * t);
}
signal[i] = v;
}
const realData = new Float64Array(signal);
const imagData = new Float64Array(N);
const real = ndarray(realData, [N]);
const imag = ndarray(imagData, [N]);
fft(1, real, imag);
const half = Math.floor(N / 2);
const norm = N / 2 || 1;
const peaks = [];
for (let k = 0; k <= half; k++) {
const mag = math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / norm;
if (mag > 0.1) peaks.push({
frequencyHz: Math.round((k * sampleRate) / N),
magnitude: Number(mag.toFixed(2))
});
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
const rows = peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join("");
const html = DOMPurify.sanitize(`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`);
return { peaks, html, signalLength: N };
}
export default analyzeSignal;
// Generation time: 28.814s
// Result: PASS

View File

@@ -0,0 +1,51 @@
async function analyzeSignal(yamlString) {
const { load } = await import('https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.mjs');
const { create, all } = await import('https://cdn.jsdelivr.net/npm/mathjs@12.4.1/+esm');
const math = create(all);
const ndarray = (await import('https://unpkg.com/ndarray@1.0.19?module')).default;
const fft = (await import('https://unpkg.com/ndarray-fft@1.0.3?module')).default;
const DOMPurify = (await import('https://cdn.jsdelivr.net/npm/dompurify@3.1.6/dist/purify.es.js')).default;
const config = load(yamlString);
const sampleRate = config.sampleRate;
const duration = config.duration;
const N = sampleRate * duration;
const signal = new Array(N);
for (let i = 0; i < N; i++) {
const t = i / sampleRate;
let val = 0;
for (let comp of config.components) {
val += comp.amplitude * math.sin(2 * math.pi * comp.frequency * t);
}
signal[i] = val;
}
const real = ndarray(new Float64Array(signal), [N]);
const imag = ndarray(new Float64Array(N), [N]);
fft(1, real, imag);
const halfN = N / 2;
const magnitude = new Array(Math.floor(halfN) + 1);
for (let k = 0; k < magnitude.length; k++) {
magnitude[k] = math.sqrt(math.pow(real.get(k), 2) + math.pow(imag.get(k), 2)) / halfN;
}
const peaks = [];
for (let k = 0; k < magnitude.length; k++) {
const m = magnitude[k];
if (m > 0.1) {
const freq = k * sampleRate / N;
peaks.push({
frequencyHz: Math.round(freq),
magnitude: Number(m.toFixed(2))
});
}
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
let html = '<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>';
for (let p of peaks) {
html += `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`;
}
html += '</table>';
const sanitized = DOMPurify.sanitize(html);
return { peaks, html: sanitized, signalLength: N };
}
export default analyzeSignal;
// Generation time: 85.724s
// Result: FAIL

View File

@@ -0,0 +1,60 @@
async function analyzeSignal(str) {
const [
{ load },
{ create, all },
{ default: ndarray },
{ default: ndfft },
{ default: purify }
] = await Promise.all([
import('https://cdn.skypack.dev/js-yaml'),
import('https://cdn.skypack.dev/mathjs'),
import('https://cdn.skypack.dev/ndarray'),
import('https://cdn.skypack.dev/ndarray-fft'),
import('https://cdn.skypack.dev/dompurify')
]);
const m = create(all);
const { sampleRate: s, duration: d, components: c } = load(str);
const N = s * d;
const sig = new Float64Array(N);
for (let i = 0; i < N; i++) {
const t = i / s;
let v = 0;
for (const { frequency: f, amplitude: a } of c) {
v += a * m.sin(2 * m.pi * f * t);
}
sig[i] = v;
}
const r = ndarray(sig);
const im = ndarray(new Float64Array(N));
ndfft(1, r, im);
const peaks = [];
const half = N / 2;
for (let k = 0; k <= half; k++) {
const rv = r.get(k);
const iv = im.get(k);
const mag = m.sqrt(rv * rv + iv * iv) / half;
if (mag > 0.1) {
peaks.push({
frequencyHz: Math.round(k * s / N),
magnitude: Number(mag.toFixed(2))
});
}
}
peaks.sort((x, y) => y.magnitude - x.magnitude);
const html = peaks.reduce((h, p) =>
`${h}<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`,
`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>`
) + "</table>";
return { peaks, html: purify.sanitize(html), signalLength: N };
}
export default analyzeSignal;
// Generation time: 341.010s
// Result: FAIL

View File

@@ -0,0 +1,42 @@
async function analyzeSignal(yamlStr) {
const [{ default: yaml }, { default: math }, { default: nd }, { default: fft }, { default: purify }] = await Promise.all([
import('https://esm.sh/js-yaml'),
import('https://esm.sh/mathjs'),
import('https://esm.sh/ndarray'),
import('https://esm.sh/ndarray-fft'),
import('https://esm.sh/dompurify')
]);
const { sampleRate: sr, duration, components } = yaml.load(yamlStr);
const N = sr * duration;
const sig = Array.from({ length: N }, (_, i) =>
components.reduce((s, { frequency, amplitude }) =>
s + amplitude * math.sin(2 * math.pi * frequency * i / sr), 0)
);
const re = nd(new Float64Array(sig), [N]);
const im = nd(new Float64Array(N), [N]);
fft(1, re, im);
const peaks = [];
for (let k = 0; k <= N / 2; k++) {
const mag = math.sqrt(re.get(k) ** 2 + im.get(k) ** 2) / (N / 2);
if (mag > 0.1) peaks.push({
frequencyHz: Math.round(k * sr / N),
magnitude: +mag.toFixed(2)
});
}
peaks.sort((a, b) => b.magnitude - a.magnitude);
return {
peaks,
html: purify.sanitize(`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${
peaks.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`).join('')
}</table>`),
signalLength: N
};
}
export default analyzeSignal;
// Generation time: 285.288s
// Result: FAIL