Weight Functions
Kernel functions for distance weighting.
Overview
Section titled “Overview”Weight functions (kernels) determine how neighboring points contribute to each local fit. Points closer to the target receive higher weights.
Available Kernels
Section titled “Available Kernels”| Kernel | Efficiency | Smoothness | Support |
|---|---|---|---|
| Tricube | 0.998 | Very smooth | Compact |
| Epanechnikov | 1.000 | Smooth | Compact |
| Gaussian | 0.961 | Infinite | Unbounded |
| Biweight | 0.995 | Very smooth | Compact |
| Cosine | 0.999 | Smooth | Compact |
| Triangle | 0.989 | Moderate | Compact |
| Uniform | 0.943 | None | Compact |
Efficiency = AMISE relative to Epanechnikov (1.0 = optimal)
Tricube (Default)
Section titled “Tricube (Default)”Cleveland’s original choice. Best all-around performance.
$$w(u) = (1 - |u|^3)^3$$
Use when: Default choice for most applications.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "tricube" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1662Epanechnikov
Section titled “Epanechnikov”Theoretically optimal for kernel density estimation.
$$w(u) = \frac{3}{4}(1 - u^2)$$
Use when: Optimal MSE properties desired.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "epanechnikov" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1905Gaussian
Section titled “Gaussian”Infinitely smooth. No boundary effects.
$$w(u) = \exp(-u^2/2)$$
Use when: Maximum smoothness needed, computational cost acceptable.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "gaussian" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.2220Biweight
Section titled “Biweight”Good balance of efficiency and smoothness.
$$w(u) = (1 - u^2)^2$$
Use when: Alternative to Tricube with slightly different properties.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "biweight" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1593Cosine
Section titled “Cosine”Smooth and computationally efficient.
$$w(u) = \cos(\pi u / 2)$$
Use when: Want smooth kernel with simple form.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "cosine" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1845Triangle
Section titled “Triangle”Simple linear taper.
$$w(u) = 1 - |u|$$
Use when: Simple, interpretable weights.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "triangle" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1646Uniform
Section titled “Uniform”Equal weights within window. Fastest but least smooth.
$$w(u) = 1$$
Use when: Speed is critical, smoothness less important.
const { Lowess } = require('fastlowess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Lowess({ weight_function: "uniform" });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.2381Choosing a Kernel
Section titled “Choosing a Kernel”flowchart TD A[Choose Kernel] --> B{Need maximum smooth} B -- Yes --> C[Gaussian] B -- No --> D{Default acceptable} D -- Yes --> E[Tricube] D -- No --> F{Optimal MSE} F -- Yes --> G[Epanechnikov] F -- No --> H{Speed critical} H -- Yes --> I[Uniform] H -- No --> J[Biweight]