Complete function reference with examples and performance benchmarks
npm install micro-ml
import { linearRegression, init } from 'micro-ml';
// Optional: explicitly initialize WASM (auto-initializes on first call)
await init();
// Fit a model
const model = await linearRegression([1, 2, 3, 4, 5], [2, 4, 6, 8, 10]);
console.log(model.slope); // 2
console.log(model.intercept); // 0
console.log(model.rSquared); // 1
console.log(model.predict([6, 7, 8])); // [12, 14, 16]
<script type="module">
import * as ml from './node_modules/micro-ml/dist/index.js';
const model = await ml.linearRegression([1, 2, 3], [2, 4, 6]);
console.log(model.slope); // 2
</script>
Fit a line: y = slope * x + intercept
| Parameter | Type | Description |
|---|---|---|
| x | number[] | Independent variable values |
| y | number[] | Dependent variable values (same length as x) |
| Property | Type | Description |
|---|---|---|
| slope | number | Slope coefficient (m) |
| intercept | number | Y-intercept (b) |
| rSquared | number | Coefficient of determination (0-1) |
| n | number | Number of data points |
| predict(x) | (number[]) => number[] | Predict y values for given x |
| toString() | () => string | Human-readable equation |
// Stock price trend
const days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const prices = [100, 102, 105, 103, 108, 110, 112, 115, 118, 120];
const model = await linearRegression(days, prices);
console.log(`Trend: $${model.slope.toFixed(2)}/day`);
console.log(`R² = ${(model.rSquared * 100).toFixed(1)}%`);
// Predict next 5 days
const forecast = model.predict([11, 12, 13, 14, 15]);
Convenience function when x values are just indices (0, 1, 2, ...). Useful for time series.
// Equivalent calls:
const model1 = await linearRegressionSimple([10, 20, 30, 40]);
const model2 = await linearRegression([0, 1, 2, 3], [10, 20, 30, 40]);
Fit a curve: y = c₀ + c₁x + c₂x² + c₃x³ + ...
| Parameter | Type | Description |
|---|---|---|
| x | number[] | Independent variable values |
| y | number[] | Dependent variable values |
| options.degree | number | Polynomial degree (default: 2) |
| Property | Type | Description |
|---|---|---|
| degree | number | Polynomial degree |
| rSquared | number | Coefficient of determination |
| n | number | Number of data points |
| getCoefficients() | () => number[] | Returns [c₀, c₁, c₂, ...] |
| predict(x) | (number[]) => number[] | Predict y values |
// Projectile motion (parabola)
const time = [0, 0.5, 1, 1.5, 2, 2.5, 3];
const height = [0, 11.4, 19.6, 24.5, 26.1, 24.5, 19.6];
const model = await polynomialRegression(time, height, { degree: 2 });
console.log('Coefficients:', model.getCoefficients());
// [c₀, c₁, c₂] representing: height = c₀ + c₁*t + c₂*t²
// Find max height
const tMax = 1.5;
console.log('Max height:', model.predict([tMax])[0]);
Fit growth/decay: y = a × e^(bx)
| Property | Type | Description |
|---|---|---|
| a | number | Initial value coefficient |
| b | number | Growth rate (positive = growth, negative = decay) |
| rSquared | number | Coefficient of determination |
| doublingTime() | () => number | Time to double (for growth) |
| predict(x) | (number[]) => number[] | Predict y values |
// Bacterial growth
const hours = [0, 1, 2, 3, 4, 5, 6];
const population = [100, 150, 225, 338, 506, 759, 1139];
const model = await exponentialRegression(hours, population);
console.log(`Initial: ${model.a.toFixed(0)} bacteria`);
console.log(`Growth rate: ${(model.b * 100).toFixed(1)}% per hour`);
console.log(`Doubling time: ${model.doublingTime().toFixed(2)} hours`);
// Predict after 10 hours
const future = model.predict([10]);
console.log(`After 10 hours: ${future[0].toFixed(0)} bacteria`);
Fit logarithmic curve: y = a + b × ln(x)
| Property | Type | Description |
|---|---|---|
| a | number | Intercept |
| b | number | Logarithmic coefficient |
| rSquared | number | Coefficient of determination |
| predict(x) | (number[]) => number[] | Predict y values |
// Learning curve (diminishing returns)
const practice = [1, 2, 5, 10, 20, 50, 100];
const skill = [10, 25, 45, 60, 75, 90, 100];
const model = await logarithmicRegression(practice, skill);
console.log(`Skill = ${model.a.toFixed(2)} + ${model.b.toFixed(2)} × ln(practice)`);
console.log(`R² = ${(model.rSquared * 100).toFixed(1)}%`);
// How much practice for 95% skill?
// Solve: 95 = a + b * ln(x)
const target = Math.exp((95 - model.a) / model.b);
console.log(`Need ${target.toFixed(0)} hours for 95% skill`);
Fit power law: y = a × x^b
// Kepler's third law: T² ∝ r³
const orbitalRadius = [0.39, 0.72, 1.0, 1.52, 5.2, 9.54]; // AU
const orbitalPeriod = [0.24, 0.62, 1.0, 1.88, 11.86, 29.46]; // years
const model = await powerRegression(orbitalRadius, orbitalPeriod);
console.log(`Period = ${model.a.toFixed(4)} × radius^${model.b.toFixed(4)}`);
// b should be close to 1.5 (Kepler's law: T = r^1.5)
Smooth noisy time series data.
| Function | Description | Use Case |
|---|---|---|
| sma | Simple Moving Average - equal weight to all periods | General smoothing |
| ema | Exponential MA - more weight to recent values | Trend following, quick response |
| wma | Weighted MA - linearly decreasing weights | Balance between SMA and EMA |
// Stock price smoothing
const prices = [100, 102, 98, 105, 110, 108, 115, 112, 120, 118, 125];
const simple = await sma(prices, 3);
const exponential = await ema(prices, 3);
const weighted = await wma(prices, 3);
console.log('SMA:', simple); // [NaN, NaN, 100, 101.67, 104.33, ...]
console.log('EMA:', exponential); // [NaN, NaN, 100, 102.5, 106.25, ...]
console.log('WMA:', weighted); // [NaN, NaN, 99.33, 103.17, 106.17, ...]
// Using generic function
const result = await movingAverage(prices, { window: 5, type: 'ema' });
| Property | Type | Description |
|---|---|---|
| direction | 'up' | 'down' | 'flat' | Trend direction |
| slope | number | Rate of change per period |
| strength | number | R² value (0-1), how well trend fits |
| getForecast() | () => number[] | Predicted future values |
// Sales trend analysis
const monthlySales = [42, 45, 48, 52, 55, 58, 62, 68, 72, 75, 80, 85];
const trend = await trendForecast(monthlySales, 6);
console.log(`Direction: ${trend.direction}`); // 'up'
console.log(`Growth: $${trend.slope.toFixed(2)}/month`);
console.log(`Confidence: ${(trend.strength * 100).toFixed(1)}%`);
console.log(`Next 6 months:`, trend.getForecast());
// Rate of change (% change from n periods ago)
const roc = await rateOfChange(monthlySales, 3);
console.log('3-month ROC:', roc);
// Momentum (absolute change from n periods ago)
const mom = await momentum(monthlySales, 3);
console.log('3-month momentum:', mom);
Returns indices of local maxima (peaks) or minima (troughs).
One-liner: fit linear model and predict in single call.
Quick trend line with future predictions.
// Find peaks and troughs in stock data
const prices = [100, 105, 102, 110, 108, 115, 112, 120, 118];
const peaks = await findPeaks(prices); // indices of local highs
const troughs = await findTroughs(prices); // indices of local lows
console.log('Peak indices:', peaks); // [1, 3, 5, 7]
console.log('Peak values:', peaks.map(i => prices[i]));
// Quick prediction
const predicted = await predict(
[1, 2, 3, 4, 5], // x training
[10, 20, 30, 40, 50], // y training
[6, 7, 8] // x to predict
);
console.log('Predicted:', predicted); // [60, 70, 80]
Test micro-ml with large datasets to see WASM performance.
Benchmarked on real hardware (median of 5 runs)
| Data Size | Linear Regression | Polynomial (deg 3) | Moving Average |
|---|---|---|---|
| 1,000 | < 1ms | < 1ms | < 1ms |
| 10,000 | < 1ms | < 1ms | < 1ms |
| 100,000 | 1ms | 5ms | 3-4ms |
| 1,000,000 | 6-12ms | 53ms | 30-35ms |
| 10,000,000 | 50-100ms | ~530ms | ~280ms |
| 100,000,000 | ~500ms-1s | - | ~2.9s |
// Pre-load WASM during app startup
import { init } from 'micro-ml';
// Call early in your app lifecycle
await init(); // ~10-50ms first time
// Now all calls are fast
const model = await linearRegression(x, y); // < 1ms
// Each call has ~0.1ms overhead for array conversion
// For 100,000 points: ~1ms conversion + ~10ms computation
// If doing multiple operations, they share the same conversion cost
const linear = await linearRegression(x, y); // includes conversion
const poly = await polynomialRegression(x, y); // includes conversion again
// Good: degree 2-4
const quadratic = await polynomialRegression(x, y, { degree: 2 }); // Fast, stable
// Risky: degree 5-7
const quintic = await polynomialRegression(x, y, { degree: 5 }); // May have precision issues
// Avoid: degree > 7
const high = await polynomialRegression(x, y, { degree: 10 }); // Likely unstable
// Each number = 8 bytes (Float64)
// 1M points = ~8MB per array
// Linear regression with 1M points = ~16MB (x + y arrays)
// For very large datasets, consider:
// 1. Sampling: Use every nth point
// 2. Chunking: Process in batches
// 3. Web Workers: Keep UI responsive
// For large datasets, use Web Workers to avoid blocking UI
import { createWorker } from 'micro-ml/worker';
const worker = await createWorker();
// Non-blocking regression on huge dataset
const model = await worker.linearRegression(hugeX, hugeY);
// Clean up when done
worker.terminate();
| Issue | Cause | Solution |
|---|---|---|
| Error: "All y values must be positive" | exponentialRegression with y ≤ 0 | Filter/transform data or use different model |
| Error: "Arrays must have same length" | Mismatched x and y arrays | Verify array lengths match |
| R² is negative | Wrong model type for data | Try different regression type |
| NaN in results | Division by zero or log of negative | Check input data for zeros/negatives |
| Slow performance | Many small calls instead of batching | Batch predictions in single predict() call |