Skip to content

Execution Modes

Choose the right adapter for your use case.

Overview

graph LR A[Data] --> B{Size?} B -->|Fits in memory| C{Real-time?} B -->|Too large| D[Streaming] C -->|No| E[Batch] C -->|Yes| F[Online]
Mode Use Case Memory Features
Batch Complete datasets Full All features
Streaming Large files (>100K) Chunked Residuals, robustness
Online Real-time sensors Fixed window Incremental updates

Adapter Comparison


Batch Adapter

Standard mode for complete datasets. Supports all features.

When to Use

  • Dataset fits in memory
  • Need intervals, cross-validation, or diagnostics
  • Processing complete files

Gap Handling

Example

model <- Loess(
    fraction = 0.5,
    iterations = 3,
    confidence_intervals = 0.95,
    prediction_intervals = 0.95,
    return_diagnostics = TRUE,
    parallel = TRUE
)
result <- model$fit(x, y)
model = fl.Loess(
    fraction=0.5,
    iterations=3,
    confidence_intervals=0.95,
    prediction_intervals=0.95,
    return_diagnostics=True,
    parallel=True
)
result = model.fit(x, y)
use fastLoess::prelude::*;

let model = Loess::new()
    .fraction(0.5)
    .iterations(3)
    .confidence_intervals(0.95)
    .prediction_intervals(0.95)
    .return_diagnostics()
    .parallel(true)
    .build()?;

let result = model.fit(&x, &y)?;
using FastLOESS

model = Loess(;
    fraction=0.5,
    iterations=3,
    confidence_intervals=0.95,
    prediction_intervals=0.95,
    return_diagnostics=true,
    parallel=true
)
result = fit(model, x, y)
const fastloess = require('fastloess');

const model = new fastloess.Loess({
    fraction: 0.5,
    iterations: 3,
    confidence_intervals: 0.95,
    prediction_intervals: 0.95,
    return_diagnostics: true
});
const result = model.fit(x, y);
import { Loess } from 'fastloess-wasm';

const model = new Loess({
    fraction: 0.5,
    iterations: 3,
    confidence_intervals: 0.95,
    prediction_intervals: 0.95,
    return_diagnostics: true
});
const result = model.fit(x, y);
#include "fastloess.hpp"

fastloess::Loess model({
    .fraction = 0.5,
    .iterations = 3,
    .confidence_intervals = 0.95,
    .prediction_intervals = 0.95,
    .return_diagnostics = true,
    .parallel = true
});
auto result = model.fit(x, y).value();

Streaming Adapter

Process large datasets in chunks with configurable overlap.

When to Use

  • Dataset >100,000 points
  • Memory-constrained environments
  • Batch processing pipelines

Parameters

Parameter Default Description
chunk_size 5000 Points per chunk
overlap 500 Overlap between chunks
merge_strategy "weighted_average" How to merge overlaps

Merge Strategies

Strategy Behavior
"average" Average overlapping values
"weighted_average" Distance-weighted blend (default)
"take_first" Keep left chunk values
"take_last" Keep right chunk values

Merge Strategies

Example

model <- StreamingLoess(
    fraction = 0.3,
    iterations = 2,
    chunk_size = 5000,
    overlap = 500,
    merge_strategy = "average"
)
result <- model$process_chunk(x, y)
final <- model$finalize()
model = fl.StreamingLoess(
    fraction=0.3,
    iterations=2,
    chunk_size=5000,
    overlap=500,
    merge_strategy="average"
)
model.process_chunk(x, y)
result = model.finalize()
let mut processor = StreamingLoess::new()
    .fraction(0.3)
    .iterations(2)
    .chunk_size(50)
    .overlap(10)
    .merge_strategy("average")
    .build()?;

let result = processor.process_chunk(&x_chunk, &y_chunk)?;
println!("Chunk processed: {} points", result.y.len());

let final_result = processor.finalize()?;
println!("Final: {} points", final_result.y.len());
using FastLOESS

model = StreamingLoess(;
    fraction=0.3,
    iterations=2,
    chunk_size=5000,
    overlap=500,
    merge_strategy="average"
)
process_chunk(model, x, y)
result = finalize(model)
const { StreamingLoess } = require('fastloess');

const processor = new StreamingLoess(
    { fraction: 0.3, iterations: 2 },
    { chunk_size: 5000, overlap: 500 }
);

// Process chunks
for (const {x, y} of dataChunks) {
    const result = processor.processChunk(x, y);
    // ...
}

const finalResult = processor.finalize();
import { StreamingLoess } from 'fastloess-wasm';

const processor = new StreamingLoess(
    { fraction: 0.3, iterations: 2 },
    { chunk_size: 5000, overlap: 500 }
);

// Process chunks
for (const {x, y} of dataChunks) {
    const result = processor.processChunk(x, y);
    // ...
}

const finalResult = processor.finalize();
#include "fastloess.hpp"

fastloess::StreamingOptions opts;
opts.fraction = 0.3;
opts.iterations = 2;
opts.chunk_size = 5000;
opts.overlap = 500;

fastloess::StreamingLoess stream(opts);
(void)stream.process_chunk(x, y);
auto result = stream.finalize().value();

Always call finalize()

In Rust, always call processor.finalize() after processing all chunks to retrieve buffered overlap data.

Online Adapter

Incremental updates with a sliding window for real-time data.

When to Use

  • Data arrives incrementally (sensors, streams)
  • Need real-time smoothed values
  • Fixed memory budget

Online Adapter

Parameters

Parameter Default Description
window_capacity 1000 Max points in window
min_points 2 Points before output starts
update_mode "incremental" Update strategy

Update Modes

Mode Behavior Speed
"incremental" Update only affected fits Faster
"full" Recompute entire window More accurate

Example

model <- OnlineLoess(
    fraction = 0.2,
    iterations = 1,
    window_capacity = 100,
    min_points = 5,
    update_mode = "incremental"
)
for (i in seq_along(x)) {
    result <- model$add_point(x[i], y[i])
    if (!is.null(result)) cat(result$smoothed, "\n")
}
model = fl.OnlineLoess(
    fraction=0.2,
    iterations=1,
    window_capacity=100,
    min_points=5,
    update_mode="incremental"
)
for xi, yi in zip(x, y):
    result = model.add_point(float(xi), float(yi))
    if result is not None:
        print(result.smoothed)
let mut processor = OnlineLoess::new()
    .fraction(0.2)
    .iterations(1)
    .window_capacity(100)
    .min_points(5)
    .update_mode("incremental")
    .build()?;

for i in 0..x.len() {
    if let Some(output) = processor.add_point(&[x[i]], y[i])? {
        println!("Smoothed: {:.2}", output.smoothed);
    }
}
using FastLOESS

model = OnlineLoess(;
    fraction=0.2,
    iterations=1,
    window_capacity=100,
    min_points=5,
    update_mode="incremental"
)
for i in eachindex(x)
    result = add_point(model, x[i], y[i])
    if result !== nothing
        println(result.smoothed)
    end
end
const { OnlineLoess } = require('fastloess');

const processor = new OnlineLoess(
    { fraction: 0.2, iterations: 1 },
    { window_capacity: 100, min_points: 5, update_mode: "incremental" }
);

// Add points
for (const [x, y] of sensorStream) {
    const res = processor.add_point(x, y);
    if (res !== null) {
        console.log(`Smoothed: ${res.smoothed.toFixed(2)}`);
    }
}
import { OnlineLoess } from 'fastloess-wasm';

const processor = new OnlineLoess(
    { fraction: 0.2, iterations: 1 },
    { window_capacity: 100, min_points: 5, update_mode: "incremental" }
);

// Add points
for (const [x, y] of sensorStream) {
    const res = processor.add_point(x, y);
    if (res !== undefined) {
        console.log(`Smoothed: ${res.smoothed.toFixed(2)}`);
    }
}
#include "fastloess.hpp"

fastloess::OnlineOptions opts;
opts.fraction = 0.2;
opts.iterations = 1;
opts.window_capacity = 100;
opts.min_points = 5;
opts.update_mode = "incremental";

fastloess::OnlineLoess model(opts);
for (size_t i = 0; i < x.size(); ++i) {
    auto out = model.add_point(x[i], y[i]).value();
    if (out.has_value())
        std::cout << out.smoothed() << std::endl;
}

Feature Comparison

Feature Batch Streaming Online
Confidence intervals
Prediction intervals
Cross-validation
Diagnostics
Residuals
Robustness weights
Parallel execution

Next Steps