diff --git a/playground/acf_pacf.html b/playground/acf_pacf.html new file mode 100644 index 00000000..72e6232f --- /dev/null +++ b/playground/acf_pacf.html @@ -0,0 +1,393 @@ + + + + + + tsb — ACF / PACF / Portmanteau Tests + + + + +
+
+
Initializing playground…
+
+ + ← Back to roadmap +

ACF / PACF & Portmanteau Tests

+

+ Autocorrelation (acf), partial autocorrelation (pacf), + cross-correlation (ccf), Durbin-Watson, Ljung-Box, and Box-Pierce tests — + mirrors statsmodels.tsa.stattools and pd.Series.autocorr. +

+ +
+

1 — Single-lag autocorrelation (pandas-style)

+

+ autocorr(x, lag) computes the Pearson correlation between + x[0..n−lag−1] and x[lag..n−1], exactly like + pd.Series.autocorr(lag). +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ +
+

2 — Full ACF with Bartlett confidence intervals

+

+ acf(x, { nlags, alpha }) returns all autocorrelations at lags 0…nlags. + With alpha=0.05, Bartlett confidence intervals are returned: lags whose + CI excludes zero are statistically significant. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ +
+

3 — Partial ACF (Levinson-Durbin)

+

+ pacf(x, { nlags, alpha }) uses the Levinson-Durbin recursion to compute + partial autocorrelations. For a true AR(p) process, only the first p PACF values are + significantly non-zero — this is how you identify the AR order. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ +
+

4 — Cross-Correlation Function (CCF)

+

+ ccf(x, y, { nlags, alpha }) measures the linear relationship between + x[t] and y[t+k] at each lag k. Peaks in the CCF reveal + lead/lag relationships between two series. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ +
+

5 — Durbin-Watson statistic

+

+ durbinWatson(residuals) tests for first-order autocorrelation in OLS residuals. + Values near 2 indicate no autocorrelation; values near 0 indicate positive autocorrelation; + values near 4 indicate negative autocorrelation. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ +
+

6 — Ljung-Box & Box-Pierce portmanteau tests

+

+ ljungBox(x, { lags }) and boxPierce(x, { lags }) test the null + hypothesis that no autocorrelation exists up to a given lag. Small p-values reject the + white-noise hypothesis. Ljung-Box has better finite-sample properties. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + + + + + diff --git a/playground/arima.html b/playground/arima.html new file mode 100644 index 00000000..17b2fe6d --- /dev/null +++ b/playground/arima.html @@ -0,0 +1,406 @@ + + + + + + tsb — ARIMA + + + +
+
+

Loading tsb runtime…

+
+ + ← back to tsb playground +

ARIMA

+

+ ARIMA(p, d, q) time-series model — estimation, forecasting, and prediction intervals. + Mirrors statsmodels.tsa.arima.model.ARIMA. +

+ + +
+

1 — Fit an AR(1) model

+

+ new ARIMAModel({ p, d, q }) constructs the model; + .fit(y) estimates the parameters using the Hannan-Rissanen + two-step method and returns coefficients, sigma², AIC, and BIC. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

2 — Multi-step forecast with prediction intervals

+

+ model.forecast(steps) returns point forecasts and 95 % prediction + intervals computed via ψ-weight recursion. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

3 — ARMA(1,1) model

+

+ Combine AR and MA terms. ARMA(1,1): x_t = φ x_{t−1} + θ ε_{t−1} + ε_t. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

4 — ARIMA(1,1,0): integrated series

+

+ Set d=1 for I(1) series (random walk, stock prices, etc.). + The model differences the series before fitting. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

5 — fitArima convenience function

+

+ fitArima(y, opts) is a one-liner shorthand for constructing + and fitting an ARIMA model. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + + + diff --git a/playground/avro.html b/playground/avro.html new file mode 100644 index 00000000..e4e48cd6 --- /dev/null +++ b/playground/avro.html @@ -0,0 +1,347 @@ + + + + + + tsb — Apache Avro I/O + + + +
+
+

Loading tsb runtime…

+
+ + ← back to tsb playground +

Apache Avro I/O

+

+ Read and write Apache Avro Object Container Files (OCF) as DataFrames. + Mirrors pandas.read_avro(). Pure TypeScript, no external deps. +

+ + +
+

1 — Write and read back an Avro file

+

+ toAvro(df) serializes a DataFrame to an uncompressed Avro OCF buffer. + readAvro(buf) parses it back. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

2 — Nullable columns

+

+ Columns containing null are automatically serialized as + Avro unions (["null", type]) and decoded back with nulls + preserved. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

3 — Select specific columns with usecols

+

+ Pass usecols to read only a subset of columns, saving + memory and parse time. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

4 — Error handling

+

+ readAvro throws descriptive errors for bad magic bytes or + unsupported codecs (deflate, snappy). +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + + + diff --git a/playground/dlm.html b/playground/dlm.html new file mode 100644 index 00000000..9f39cdaa --- /dev/null +++ b/playground/dlm.html @@ -0,0 +1,533 @@ + + + + + + tsb — Dynamic Linear Model (DLM) + + + + +← back to index + +

Dynamic Linear Model (DLM)

+

+ The DLM (West & Harrison state-space framework) generalises the Kalman filter to + named components — local level, linear trend, Fourier seasonality — that can be + freely combined. Fits observation and state noise by MLE. +

+ + +
+

1 · Model & data

+
+
+ + +
+
+ + +
+
+ +
+ + 1.0 +
+
+
+ +
+ + 0.30 +
+
+
+ +
+ + 60 +
+
+
+ +
+ + 10 +
+
+
+
+ + + + +
+
+ + +
+

2 · Filter / smoother / forecast

+
+
+
+
+ + +
+

3 · Code

+
// loading…
+
+ + + + + diff --git a/playground/ets.html b/playground/ets.html new file mode 100644 index 00000000..beacabbe --- /dev/null +++ b/playground/ets.html @@ -0,0 +1,550 @@ + + + + + + tsb — Exponential Smoothing (ETS / Holt-Winters) + + + +
+
+

Loading tsb runtime…

+
+ + ← back to tsb playground +

Exponential Smoothing (ETS / Holt-Winters)

+

+ Simple Exponential Smoothing, Holt linear trend, and full Holt-Winters seasonal models. + Mirrors statsmodels.tsa.holtwinters.ExponentialSmoothing. +

+ + +
+

1 — Simple Exponential Smoothing (SES)

+

+ SimpleExpSmoothing fits ETS(A,N,N): level-only smoothing with + parameter α. All h-step forecasts equal the final level. α is estimated by + minimising SSE via Nelder-Mead. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

2 — Holt's Linear Trend (Double Exponential Smoothing)

+

+ Holt extends SES with a trend component β (ETS(A,A,N)). + Optionally damps the trend with φ (ETS(A,Ad,N)) to prevent over-shooting. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

3 — Holt-Winters Additive Seasonal

+

+ ExponentialSmoothing with trend: "add" and + seasonal: "add" models data with a linear trend plus additive + seasonal fluctuations. Classic Holt-Winters ETS(A,A,A). +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

4 — Holt-Winters Multiplicative Seasonal

+

+ Use seasonal: "mul" when the amplitude of seasonal swings + grows with the level (common in economic time series). ETS(A,A,M). +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

5 — Forecast with prediction intervals

+

+ forecastWithCI(steps, alpha) returns point forecasts plus + (1 − α) % prediction intervals. Intervals widen with forecast horizon. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

6 — Model selection via AIC/BIC

+

+ Compare SES, Holt, and Holt-Winters using information criteria. Lower AIC/BIC + indicates a better balance of fit and parsimony. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

7 — Known initialisation and fixed parameters

+

+ You can supply fixed smoothing parameters or initial state values. + Use initializationMethod: "known" to set the initial state + directly without estimating it. +

+
+
+ JavaScript +
+ + +
+
+ +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + + + diff --git a/playground/filters.html b/playground/filters.html new file mode 100644 index 00000000..0bfe91a8 --- /dev/null +++ b/playground/filters.html @@ -0,0 +1,534 @@ + + + + + + tsb — Digital Filters + + + + +
+
+
Initializing playground…
+
+ + ← Back to roadmap +

🎛️ Digital Filters — Interactive Playground

+

+ FIR and IIR filter design and application — mirrors scipy.signal.
+ Edit any code block below and press ▶ Run + (or Ctrl+Enter) to execute it live in your browser. +

+ + +
+

1. Low-pass FIR with firwin

+

Design a 51-tap Hamming-windowed low-pass FIR and check its DC and Nyquist gain.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

2. High-pass FIR

+

Pass high frequencies by setting pass_zero: false. DC gain should be near 0, Nyquist near 1.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

3. Apply FIR: lfilter vs filtfilt

+

lfilter is causal (has phase delay); filtfilt applies the filter twice for zero-phase output.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

4. Butterworth low-pass filter design

+

Design a 4th-order Butterworth IIR filter. butter returns both SOS form (numerically preferred) and ba form.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

5. Apply Butterworth: sosfilt vs sosfiltfilt

+

Filter a noisy 50 Hz signal to remove 300 Hz interference. Zero-phase output is closer to the clean reference.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

6. High-pass Butterworth

+

A 2nd-order Butterworth high-pass attenuates DC and passes high frequencies.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

7. Butterworth gain at cutoff — multiple orders

+

All Butterworth filters have exactly −3 dB gain at the cutoff frequency, regardless of order.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

API Reference

+ + + + + + + + + + +
FunctionDescriptionMirrors
firwin(n, cutoff, opts?)FIR design (windowed-sinc)scipy.signal.firwin
butter(N, Wn, type?)Butterworth IIR designscipy.signal.butter
freqz(b, a?, worN?)FIR/IIR frequency responsescipy.signal.freqz
sosfreqz(sos, worN?)SOS frequency responsescipy.signal.sosfreqz
lfilter(b, a, x)Causal FIR/IIR filterscipy.signal.lfilter
filtfilt(b, a, x)Zero-phase filterscipy.signal.filtfilt
sosfilt(sos, x)Causal SOS filterscipy.signal.sosfilt
sosfiltfilt(sos, x)Zero-phase SOS filterscipy.signal.sosfiltfilt
+
+ + + + + + + diff --git a/playground/hmm.html b/playground/hmm.html new file mode 100644 index 00000000..a2cdcc40 --- /dev/null +++ b/playground/hmm.html @@ -0,0 +1,333 @@ + + + + + + tsb — Hidden Markov Models + + + + +

Hidden Markov Models

+

+ tsb implements GaussianHMM and MultinomialHMM: + Hidden Markov Models with Baum-Welch EM parameter estimation and Viterbi decoding. + Mirrors the hmmlearn API. +

+ +

1 · Gaussian HMM — two hidden regimes

+

Generate a regime-switching time series (e.g. bull/bear market) and recover the hidden states.

+
+ +
+
+ +

2 · Multinomial HMM — discrete symbols

+

Fit a model to a discrete sequence (e.g. text symbols, DNA codons).

+
+ +
+
+ +

3 · Viterbi standalone

+

Given known parameters, decode the most-likely state sequence directly.

+
+ +
+
+ +

API Reference

+
import { GaussianHMM, MultinomialHMM, fitGaussianHMM, hmmViterbi } from "tsb";
+
+// Gaussian HMM
+const model = new GaussianHMM({ nComponents: 2, nIter: 100 });
+model.fit(observations);
+const states = model.predict(newObs);   // Viterbi
+const logP   = model.score(newObs);     // log P(obs | model)
+const proba  = model.predictProba(obs); // posterior P(z_t | obs)
+const sample = model.sample(100);       // { states, obs }
+
+// Multinomial HMM (integer symbols)
+const mmodel = new MultinomialHMM({ nComponents: 2, nFeatures: 4, nIter: 100 });
+mmodel.fit(integerObs);
+const mstates = mmodel.predict(integerObs);
+
+// Convenience: fit and return model
+const fitted = fitGaussianHMM(obs, 2);
+
+// Standalone Viterbi with known parameters
+const decoded = hmmViterbi(startProb, transmat, emissionProb, obs);
+
+ + + + diff --git a/playground/index.html b/playground/index.html index 02628c32..cb64c303 100644 --- a/playground/index.html +++ b/playground/index.html @@ -601,6 +601,56 @@

✅ Complete +
+

📡 Signal Processing — FFT, STFT, Welch PSD

+

FFT/IFFT/RFFT (Cooley-Tukey radix-2), fftFreq, fftshift/ifftshift, 8 window functions (getWindow), Short-Time Fourier Transform (stft/istft with overlap-add), Welch power spectral density, and periodogram. Mirrors numpy.fft and scipy.signal.

+
✅ Complete
+
+
+

🎛️ Digital Filters — FIR, Butterworth IIR

+

FIR filter design via windowed-sinc (firwin), Butterworth IIR (butter), frequency response (freqz, sosfreqz), and filter application: lfilter (causal), filtfilt (zero-phase), sosfilt, sosfiltfilt. Mirrors scipy.signal.

+
✅ Complete
+
+
+

🗂️ ORC Format I/O — readOrc / toOrc

+

Apache ORC (Optimized Row Columnar) file format reader and writer. Supports BOOLEAN, INT/LONG, FLOAT/DOUBLE, STRING columns with NONE compression and RLE v1 / direct encoding. Mirrors pandas.read_orc() and DataFrame.to_orc().

+
✅ Complete
+
+
+

📈 ACF / PACF & Portmanteau Tests

+

autocorr, acf (Bartlett CI), pacf (Levinson-Durbin), ccf, durbinWatson, Ljung-Box and Box-Pierce portmanteau tests. Mirrors statsmodels.tsa.stattools and pd.Series.autocorr.

+
✅ Complete
+
+
+

📉 ARIMA(p,d,q) Time-Series Models

+

ARIMAModel and fitArima — Hannan-Rissanen two-step estimation, multi-step forecasting, prediction intervals, AIC/BIC. Mirrors statsmodels.tsa.arima.model.ARIMA.

+
✅ Complete
+
+
+

🔭 Kalman Filter & RTS Smoother

+

KalmanFilter — linear Gaussian state-space models with forward Kalman filter and backward RTS smoother. Factory helpers localLevel, localLinearTrend. Missing observations handled transparently.

+
✅ Complete
+
+
+

📦 Apache Avro OCF I/O — readAvro / toAvro

+

readAvro and toAvro — Apache Avro Object Container File reader and writer. Supports all Avro primitives, arrays, maps, unions, and records. Zigzag varint encoding. Mirrors pandas.read_avro().

+
✅ Complete
+
+
+

📊 Exponential Smoothing — ETS / Holt-Winters

+

SimpleExpSmoothing, Holt, and ExponentialSmoothing — SES, Holt linear trend, and full Holt-Winters with additive/multiplicative seasonal components. Nelder-Mead parameter optimisation, AIC/BIC/AICc, prediction intervals. Mirrors statsmodels.tsa.holtwinters.ExponentialSmoothing.

+
✅ Complete
+
+
+

🔲 Dynamic Linear Model (DLM)

+

DLM — West & Harrison state-space framework. Local-level, local-linear-trend, polynomial trend, Fourier seasonal components, free combination via combineDLMs. Kalman filter, RTS smoother, h-step forecasting, MLE fitting, discount-factor model. Mirrors the R dlm package.

+
✅ Complete
+
+
+

🔮 Hidden Markov Model (HMM)

+

GaussianHMM, MultinomialHMM — Baum-Welch EM parameter estimation, Viterbi decoding, forward-backward log-space algorithm. Regime detection, sequence labeling. Mirrors hmmlearn.

+
✅ Complete
+
diff --git a/playground/kalman.html b/playground/kalman.html new file mode 100644 index 00000000..b89ce40e --- /dev/null +++ b/playground/kalman.html @@ -0,0 +1,476 @@ + + + + + + tsb — Kalman Filter & State-Space Models + + + + +
+
+

Loading tsb…

+
+ +← Back to index +

🔭 Kalman Filter & State-Space Models

+

+ Linear Gaussian state-space model — Kalman filter (forward pass) and + RTS smoother (backward pass). Mirrors statsmodels.tsa.statespace + and pykalman.KalmanFilter. +

+ + +
+

📐 The State-Space Model

+

+ A linear Gaussian SSM describes a latent state x_t and + observations y_t via two equations: +

+
+ x_t = F · x_{t-1} + w_t, w_t ~ N(0, Q) (state transition)
+ y_t = H · x_t + v_t, v_t ~ N(0, R) (observation)
+ x_0 ~ N(m_0, P_0) +
+
    +
  • F — state transition matrix (n_states × n_states)
  • +
  • H — observation matrix (n_obs × n_states)
  • +
  • Q — process noise covariance
  • +
  • R — observation noise covariance
  • +
  • m_0, P_0 — initial state distribution
  • +
+

+ The Kalman filter computes filtered state + estimates x_{t|t} (posterior after seeing observation t). + The RTS smoother computes smoothed estimates + x_{t|T} using all T observations. +

+
+ + +
+

📈 Local-Level Model (Random Walk + Noise)

+

+ The simplest SSM: a hidden state that follows a random walk, observed + with noise. Perfect for denoising a noisy scalar time series or + estimating a slowly changing mean. +

+
+
+ example-1.ts +
+ + +
+
+ +
Click ▶ Run to execute
+
+
+ + +
+

🔄 RTS Smoother — Filling Gaps Retrospectively

+

+ The filter only uses observations up to time t. The smoother uses + all observations to produce better estimates, especially for + time-steps near missing values. Smoothed uncertainty is always ≤ filtered. +

+
+
+ example-2.ts +
+ + +
+
+ +
Click ▶ Run to execute
+
+
+ + +
+

📊 Local Linear Trend (Level + Slope)

+

+ A 2-state model: [level, slope]. The level increases by the + slope each step; both drift over time. Great for tracking slowly changing + trends with missing observations. +

+
+
+ example-3.ts +
+ + +
+
+ +
Click ▶ Run to execute
+
+
+ + +
+

⚙️ Custom State-Space Model (AR(1) State)

+

+ Build your own model by specifying the four matrices directly. + Here: a state that follows an AR(1) process with coefficient 0.9. +

+
+
+ example-4.ts +
+ + +
+
+ +
Click ▶ Run to execute
+
+
+ + +
+

🔢 Multi-Dimensional Observations

+

+ The Kalman filter naturally handles multi-dimensional observations. + Here: 2 sensors observing a single latent state. +

+
+
+ example-5.ts +
+ + +
+
+ +
Click ▶ Run to execute
+
+
+ + +
+

📖 API Reference

+
    +
  • KalmanFilter.localLevel(opts?) — random-walk + noise (1-D)
  • +
  • KalmanFilter.localLinearTrend(opts?) — level + slope (2-D state)
  • +
  • new KalmanFilter(opts) — custom F, H, Q, R, m0, P0
  • +
  • kf.filter(observations)KalmanFilterResult
  • +
  • kf.smooth(observations)KalmanSmootherResult
  • +
  • kalmanFilter1D(obs, opts?) — scalar convenience wrapper
  • +
  • kalmanSmooth1D(obs, opts?) — scalar smoother wrapper
  • +
  • extractScalarMeans(means) — extract 1-D means array
  • +
  • filteredPredictionInterval(result, z?){lower, upper}
  • +
+

+ Missing observations: pass null in any observation row. The + filter skips the update step for that time-step (covariance grows). + The smoother retroactively interpolates using future observations. +

+
+ + + + diff --git a/playground/orc.html b/playground/orc.html new file mode 100644 index 00000000..494d18e7 --- /dev/null +++ b/playground/orc.html @@ -0,0 +1,207 @@ + + + + + + tsb · ORC Format I/O + + + +

← tsb playground

+

ORC Format I/O

+

+ pandas.read_orc + DataFrame.to_orc +

+

+ Apache ORC (Optimized Row Columnar) is a self-describing, type-aware columnar file format designed + for large-scale analytical workloads. tsb supports reading and writing ORC files with + NONE compression using RLE v1 integer encoding, direct float/double, and direct string encoding. +

+ +
+ ℹ️ This playground runs entirely in-browser via a bundled tsb build. ORC buffers are created + in-memory — no file system access is required. +
+ +

1 — Write & read a DataFrame

+

Create a DataFrame, serialize it to ORC bytes, then parse it back:

+
import { DataFrame, readOrc, toOrc } from "tsb";
+
+const df = DataFrame.fromColumns({
+  id:     [1, 2, 3, 4, 5],
+  name:   ["Alice", "Bob", "Carol", "Dave", "Eve"],
+  score:  [95.5, 87.0, 92.3, 78.1, 99.9],
+  passed: [true, false, true, false, true],
+});
+
+// Serialize to binary ORC
+const buf = toOrc(df);
+console.log("ORC buffer size:", buf.length, "bytes");
+
+// Parse back
+const df2 = readOrc(buf);
+console.log(df2.toString());
+ +
Click "Run" to execute…
+ +

2 — Nullable columns

+

ORC natively supports null values via PRESENT streams:

+
import { DataFrame, readOrc, toOrc } from "tsb";
+
+const df = DataFrame.fromColumns({
+  x:    [1, null, 3, null, 5],
+  name: ["a", null, "c", null, "e"],
+});
+
+const buf = toOrc(df);
+const rt = readOrc(buf);
+console.log("x values:", rt.col("x").values.join(", "));
+console.log("name values:", rt.col("name").values.join(", "));
+ +
Click "Run" to execute…
+ +

3 — Column selection

+

Use the columns option to read only a subset of columns:

+
import { DataFrame, readOrc, toOrc } from "tsb";
+
+const df = DataFrame.fromColumns({
+  a: [1, 2, 3],
+  b: ["x", "y", "z"],
+  c: [true, false, true],
+  d: [10.0, 20.0, 30.0],
+});
+
+const buf = toOrc(df);
+
+// Only read columns a and c
+const partial = readOrc(buf, { columns: ["a", "c"] });
+console.log("columns:", partial.columns.toArray().join(", "));
+console.log("a:", partial.col("a").values.join(", "));
+console.log("c:", partial.col("c").values.join(", "));
+ +
Click "Run" to execute…
+ +

4 — Large dataset benchmark

+

Serialize and parse a 10 000-row DataFrame to measure throughput:

+
import { DataFrame, readOrc, toOrc } from "tsb";
+
+const N = 10_000;
+const ids    = Array.from({ length: N }, (_, i) => i);
+const names  = Array.from({ length: N }, (_, i) => `user_${i}`);
+const scores = Array.from({ length: N }, () => Math.random() * 100);
+
+const df = DataFrame.fromColumns({ id: ids, name: names, score: scores });
+
+const t0 = performance.now();
+const buf = toOrc(df);
+const t1 = performance.now();
+const df2 = readOrc(buf);
+const t2 = performance.now();
+
+console.log(`Rows: ${df2.height}, Columns: ${df2.width}`);
+console.log(`ORC size: ${buf.length.toLocaleString()} bytes`);
+console.log(`Write: ${(t1 - t0).toFixed(1)} ms`);
+console.log(`Read:  ${(t2 - t1).toFixed(1)} ms`);
+ +
Click "Run" to execute…
+ + + + diff --git a/playground/signal.html b/playground/signal.html new file mode 100644 index 00000000..cfc646c5 --- /dev/null +++ b/playground/signal.html @@ -0,0 +1,621 @@ + + + + + + tsb — Signal Processing + + + + +
+
+
Initializing playground…
+
+ + ← Back to roadmap +

📡 Signal Processing — Interactive Playground

+

+ FFT, windows, STFT, Welch PSD, and periodogram — mirrors numpy.fft + and scipy.signal.
+ Edit any code block below and press ▶ Run + (or Ctrl+Enter) to execute it live in your browser. +

+ + +
+

1. Basic FFT of a sinusoidal signal

+

Compute a 32 Hz sine wave's FFT and identify the peak frequency bin.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

2. Parseval's theorem — energy preservation

+

The total energy is preserved between time and frequency domains.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

3. RFFT round-trip

+

Real-input FFT produces a half-spectrum; irfft reconstructs the original signal.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

4. Window functions

+

Named windows reduce spectral leakage. Use getWindow(name, n) to obtain any built-in window.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

5. Short-Time Fourier Transform (STFT)

+

Analyze a chirp signal whose frequency increases linearly over time.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

6. ISTFT reconstruction (round-trip)

+

Invert an STFT back to the time domain. Interior reconstruction error should be near machine epsilon.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

7. Welch PSD — detect signal frequency

+

Welch's method averages periodograms of overlapping segments for a lower-variance PSD estimate.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

8. Periodogram

+

A single-segment PSD estimate — higher variance but simpler than Welch.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

9. fftshift / ifftshift

+

Rearrange the FFT output so that the zero-frequency component is in the centre.

+
+
+ TypeScript +
+ + +
+
+ + +
Click ▶ Run to execute
+
Ctrl+Enter to run · Tab to indent
+
+
+ + +
+

API Reference

+ + + + + + + + + + + + + + + +
FunctionDescriptionMirrors
fft(x)N-point DFT (pads to power of 2)numpy.fft.fft
ifft(X)Inverse FFTnumpy.fft.ifft
rfft(x)Real-input FFT (one-sided)numpy.fft.rfft
irfft(X, n?)Inverse real FFTnumpy.fft.irfft
fftFreq(n, d?)DFT sample frequenciesnumpy.fft.fftfreq
rfftFreq(n, d?)One-sided DFT frequenciesnumpy.fft.rfftfreq
fftshift(x)Shift DC to centrenumpy.fft.fftshift
ifftshift(x)Inverse of fftshiftnumpy.fft.ifftshift
getWindow(name, n)Named window functionscipy.signal.get_window
stft(x, opts?)Short-Time Fourier Transformscipy.signal.stft
istft(Zxx, opts?)Inverse STFT (overlap-add)scipy.signal.istft
welch(x, opts?)Welch PSD estimatescipy.signal.welch
periodogram(x, opts?)Periodogram PSD estimatescipy.signal.periodogram
+
+ + + + + + + diff --git a/src/core/frame.ts b/src/core/frame.ts index e21c341e..5e13d577 100644 --- a/src/core/frame.ts +++ b/src/core/frame.ts @@ -626,7 +626,7 @@ export class DataFrame { for (let i = 0; i < nRows; i++) { const row: Record = {}; if (index) { - row["Index"] = this.index.at(i) as Scalar; + row.Index = this.index.at(i) as Scalar; } for (const name of colNames) { row[name] = this.col(name).iat(i); @@ -833,9 +833,7 @@ function isIndexLike(v: unknown): v is Index