Skip to content

Julia Examples

Complete Julia examples demonstrating FastLOESS with native Julia integration.

Batch Smoothing

Process complete datasets with confidence intervals and diagnostics.

#!/usr/bin/env julia
"""
FastLOESS Batch Smoothing - Comprehensive Examples

 1. Basic smoothing
 2. Robust smoothing with outliers
 3. Uncertainty quantification (confidence/prediction intervals)
 4. Cross-validation (K-Fold)
 5. Complete diagnostic analysis
 6. Different weight functions (kernels)
 7. Robustness methods comparison
 8. Benchmark
 9. Scaling methods (MAR, MAD, Mean)
10. Boundary policies
11. Zero-weight fallback strategies
12. Polynomial degrees + iterations_used
13. Distance metrics
14. Surface modes and standard errors
15. Additional weight functions
16. LOOCV and auto-converge
17. Interpolation tuning (surface_mode effects)
"""

using Printf

# Handle package loading
using Pkg
project_name = Pkg.project().name
if project_name != "FastLOESS"
    script_dir = @__DIR__
    julia_pkg_dir = joinpath(dirname(script_dir), "julia")
    if !haskey(Pkg.project().dependencies, "FastLOESS")
        Pkg.develop(path = julia_pkg_dir)
    end
end

using FastLOESS

make_linear(n) = (collect(Float64, 0:(n-1)), collect(Float64, 0:(n-1)) .* 2 .+ 1)

# ── Example 1: Basic Smoothing ───────────────────────────────────────────────
function example_1_basic_smoothing()
    println("Example 1: Basic Smoothing")
    x = [1.0, 2.0, 3.0, 4.0, 5.0]
    y = [2.0, 4.1, 5.9, 8.2, 9.8]
    result = fit(Loess(fraction = 0.5, iterations = 3), x, y)
    println("  fraction_used=$(result.fraction_used)")
    println("  Smoothed: [$(join(round.(result.y, digits=3), ", "))]")
    println()
end

# ── Example 2: Robust Smoothing with Outliers ────────────────────────────────
function example_2_robust_with_outliers()
    println("Example 2: Robust Smoothing with Outliers")
    x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
    y = [2.1, 4.0, 5.9, 25.0, 10.1, 12.0, 14.1, 15.9]  # 25.0 is outlier
    result = fit(
        Loess(
            fraction = 0.5,
            iterations = 5,
            robustness_method = "bisquare",
            return_robustness_weights = true,
            return_residuals = true,
        ),
        x,
        y,
    )
    if result.robustness_weights !== nothing
        for (i, w)  enumerate(result.robustness_weights)
            w < 0.5 && @printf("  Outlier at index %d (y=%.1f): weight=%.3f\n", i, y[i], w)
        end
    end
    println("  Smoothed: [$(join(round.(result.y, digits=2), ", "))]")
    println()
end

# ── Example 3: Uncertainty Quantification ───────────────────────────────────
function example_3_uncertainty_quantification()
    println("Example 3: Uncertainty Quantification")
    x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
    y = [2.1, 3.8, 6.2, 7.9, 10.3, 11.8, 14.1, 15.7]
    result = fit(
        Loess(
            fraction = 0.5,
            iterations = 3,
            confidence_intervals = 0.95,
            prediction_intervals = 0.95,
        ),
        x,
        y,
    )
    println("  x  y_smooth  conf_low  conf_high  pred_low  pred_high")
    for i  eachindex(result.y)
        @printf(
            "  %d  %.4f  %.4f  %.4f  %.4f  %.4f\n",
            Int(result.x[i]),
            result.y[i],
            result.confidence_lower[i],
            result.confidence_upper[i],
            result.prediction_lower[i],
            result.prediction_upper[i]
        )
    end
    println()
end

# ── Example 4: Cross-Validation ──────────────────────────────────────────────
function example_4_cross_validation()
    println("Example 4: Cross-Validation for Parameter Selection")
    x = collect(Float64, 1:20)
    y = 2 .* x .+ 1 .+ sin.(x .* 0.5)
    result = fit(
        Loess(
            cv_fractions = [0.2, 0.3, 0.5, 0.7],
            cv_method = "kfold",
            cv_k = 5,
            iterations = 2,
            return_diagnostics = true,
        ),
        x,
        y,
    )
    println("  Selected fraction: $(result.fraction_used)")
    if result.robustness_weights === nothing  # cv_scores stored separately
        scores = [0.0]  # placeholder; use result inspection
    end
    # Note: cv_scores accessible via LoessResult (not yet mapped to Julia struct)
    println()
end

# ── Example 5: Complete Diagnostic Analysis ──────────────────────────────────
function example_5_complete_diagnostics()
    println("Example 5: Complete Diagnostic Analysis")
    x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
    y = [2.1, 3.8, 6.2, 7.9, 10.3, 11.8, 14.1, 15.7]
    result = fit(
        Loess(
            fraction = 0.5,
            iterations = 3,
            confidence_intervals = 0.95,
            prediction_intervals = 0.95,
            return_diagnostics = true,
            return_residuals = true,
            return_robustness_weights = true,
        ),
        x,
        y,
    )
    if result.diagnostics !== nothing
        d = result.diagnostics
        println("  Diagnostics:")
        @printf("    RMSE:        %.6f\n", d.rmse)
        @printf("    MAE:         %.6f\n", d.mae)
        @printf("    R²:          %.6f\n", d.r_squared)
        @printf("    Residual SD: %.6f\n", d.residual_sd)
        !isnan(d.aic) && @printf("    AIC:         %.2f\n", d.aic)
        !isnan(d.aicc) && @printf("    AICc:        %.2f\n", d.aicc)
        !isnan(d.effective_df) && @printf("    Eff. DF:     %.2f\n", d.effective_df)
    end
    @printf("  smoothed[1]: %.5f\n", result.y[1])
    result.residuals !== nothing && @printf("  residuals[1]: %.5f\n", result.residuals[1])
    result.robustness_weights !== nothing &&
        @printf("  rob_weight[1]: %.4f\n", result.robustness_weights[1])
    println()
end

# ── Example 6: Different Weight Functions (Kernels) ──────────────────────────
function example_6_different_kernels()
    println("Example 6: Different Weight Functions (Kernels)")
    x = [1.0, 2.0, 3.0, 4.0, 5.0]
    y = [2.0, 4.1, 5.9, 8.2, 9.8]
    for kernel  ["tricube", "epanechnikov", "gaussian", "biweight"]
        result = fit(Loess(fraction = 0.5, weight_function = kernel), x, y)
        println("  $kernel: [$(join(round.(result.y, digits=3), ", "))]")
    end
    println()
end

# ── Example 7: Robustness Methods Comparison ─────────────────────────────────
function example_7_robustness_methods()
    println("Example 7: Robustness Methods Comparison")
    x = [1.0, 2.0, 3.0, 4.0, 5.0]
    y = [2.0, 4.1, 20.0, 8.2, 9.8]  # 20.0 is an outlier
    for method  ["bisquare", "huber", "talwar"]
        result = fit(
            Loess(
                fraction = 0.5,
                iterations = 5,
                robustness_method = method,
                return_robustness_weights = true,
            ),
            x,
            y,
        )
        println("  $method:")
        println("    Smoothed: [$(join(round.(result.y, digits=2), ", "))]")
        if result.robustness_weights !== nothing
            println(
                "    Weights:  [$(join(round.(result.robustness_weights, digits=3), ", "))]",
            )
        end
    end
    println()
end

# ── Example 8: Benchmark ─────────────────────────────────────────────────────
function example_8_benchmark()
    println("Example 8: Benchmark")
    n = 1000
    x = collect(Float64, 0:(n-1))
    y = sin.(x .* 0.1) .+ cos.(x .* 0.01)
    t0 = time()
    result = fit(Loess(parallel = true), x, y)
    ms = (time() - t0) * 1000
    @printf("  %d points in %.2fms\n", n, ms)
    @printf("  fraction_used=%g, y[1]=%.4f\n", result.fraction_used, result.y[1])
    println()
end

# ── Example 9: Scaling Methods (MAR, MAD, Mean) ──────────────────────────────
function example_9_scaling_methods()
    println("Example 9: Scaling Methods")
    x, y = make_linear(20)
    for method  ["mar", "mad", "mean"]
        result = fit(Loess(fraction = 0.5, scaling_method = method), x, y)
        @printf("  %s: y[1]=%.3f\n", method, result.y[1])
    end
    println()
end

# ── Example 10: Boundary Policies ────────────────────────────────────────────
function example_10_boundary_policies()
    println("Example 10: Boundary Policies")
    x, y = make_linear(30)
    for policy  ["extend", "reflect", "zero", "noboundary"]
        result = fit(Loess(fraction = 0.5, boundary_policy = policy), x, y)
        @printf("  %s: first=%.2f, last=%.2f\n", policy, result.y[1], result.y[end])
    end
    println()
end

# ── Example 11: Zero-Weight Fallback Strategies ───────────────────────────────
function example_11_zero_weight_fallback()
    println("Example 11: Zero-Weight Fallback Strategies")
    x, y = make_linear(20)
    for fb  ["use_local_mean", "return_original", "return_none"]
        result = fit(Loess(fraction = 0.5, zero_weight_fallback = fb), x, y)
        @printf("  %s: y[1]=%.3f\n", fb, result.y[1])
    end
    println()
end

# ── Example 12: Polynomial Degrees + iterations_used ──────────────────────────
function example_12_polynomial_degrees()
    println("Example 12: Polynomial Degrees")
    x, y = make_linear(30)
    for deg  ["constant", "linear", "quadratic", "cubic", "quartic"]
        result = fit(Loess(fraction = 0.5, iterations = 2, degree = deg), x, y)
        @printf(
            "  %s: y[1]=%.3f, iterations_used=%d\n",
            deg,
            result.y[1],
            result.iterations_used
        )
    end
    println()
end

# ── Example 13: Distance Metrics ─────────────────────────────────────────────
function example_13_distance_metrics()
    println("Example 13: Distance Metrics")
    x, y = make_linear(20)
    for metric  ["euclidean", "normalized", "manhattan", "chebyshev"]
        result = fit(Loess(fraction = 0.5, distance_metric = metric), x, y)
        @printf("  %s: y[1]=%.3f\n", metric, result.y[1])
    end
    # Minkowski with custom p via "minkowski:p" string format
    result = fit(Loess(fraction = 0.5, distance_metric = "minkowski:3"), x, y)
    @printf("  minkowski(p=3): y[1]=%.3f\n", result.y[1])
    println()
end

# ── Example 14: Surface Modes and Standard Errors ────────────────────────────
function example_14_surface_modes_and_se()
    println("Example 14: Surface Modes and Standard Errors")
    x, y = make_linear(30)

    # Direct surface — fits every point; SE fields fully populated
    r = fit(
        Loess(
            fraction = 0.5,
            surface_mode = "direct",
            return_se = true,
            confidence_intervals = 0.95,
            prediction_intervals = 0.95,
        ),
        x,
        y,
    )
    println("  surface_mode=direct:")
    println("    confidence_lower non-null: $(r.confidence_lower !== nothing)")
    println("    prediction_lower non-null: $(r.prediction_lower !== nothing)")
    r.standard_errors !== nothing &&
        @printf("    standard_errors[1]: %.4f\n", r.standard_errors[1])
    r.enp !== nothing && @printf("    enp: %.3f\n", r.enp)
    r.trace_hat !== nothing && @printf("    trace_hat: %.3f\n", r.trace_hat)
    r.delta1 !== nothing && @printf("    delta1: %.3f\n", r.delta1)
    r.delta2 !== nothing && @printf("    delta2: %.3f\n", r.delta2)
    r.residual_scale !== nothing && @printf("    residual_scale: %.4f\n", r.residual_scale)
    r.leverage !== nothing && @printf("    leverage[1]: %.4f\n", r.leverage[1])

    # Interpolation surface — faster, approximate
    r2 = fit(Loess(fraction = 0.5, surface_mode = "interpolation", return_se = true), x, y)
    println("  surface_mode=interpolation:")
    @printf("    y[1]: %.3f\n", r2.y[1])
    r2.standard_errors !== nothing &&
        @printf("    standard_errors[1]: %.4f\n", r2.standard_errors[1])
    println()
end

# ── Example 15: Additional Weight Functions (Uniform, Triangle, Cosine) ───────
function example_15_additional_kernels()
    println("Example 15: Additional Weight Functions (Uniform, Triangle, Cosine)")
    x = [1.0, 2.0, 3.0, 4.0, 5.0]
    y = [2.0, 4.1, 5.9, 8.2, 9.8]
    for kernel  ["uniform", "triangle", "cosine"]
        result = fit(Loess(fraction = 0.5, weight_function = kernel), x, y)
        println("  $kernel: [$(join(round.(result.y, digits=3), ", "))]")
    end
    println()
end

# ── Example 16: LOOCV, K-Fold, and Auto-Converge ─────────────────────────────
function example_16_loocv_and_auto_converge()
    println("Example 16: LOOCV, K-Fold, and Auto-Converge")
    x = collect(Float64, 1:20)
    y = 2 .* x .+ 1 .+ sin.(x .* 0.5)

    # Leave-one-out cross-validation
    r_loocv = fit(Loess(cv_fractions = [0.3, 0.5, 0.7], cv_method = "loocv"), x, y)
    @printf("  LOOCV selected fraction: %g\n", r_loocv.fraction_used)

    # K-Fold cross-validation
    r_kfold =
        fit(Loess(cv_fractions = [0.2, 0.4, 0.6], cv_method = "kfold", cv_k = 5), x, y)
    @printf("  KFold(k=5) selected fraction: %g\n", r_kfold.fraction_used)

    # Auto-converge: stop robustness iterations when change < tolerance
    r_ac = fit(Loess(fraction = 0.5, auto_converge = 1e-4), x, y)
    @printf("  auto_converge=1e-4: iterations_used=%d\n", r_ac.iterations_used)
    println()
end

# ── Example 17: Interpolation Tuning (surface_mode effects) ──────────────────
function example_17_interpolation_tuning()
    println("Example 17: Interpolation Tuning (surface_mode effects)")
    n = 50
    x, y = make_linear(n)

    r_interp = fit(Loess(fraction = 0.5, surface_mode = "interpolation"), x, y)
    @printf("  interpolation: y[1]=%.3f, y[end]=%.3f\n", r_interp.y[1], r_interp.y[end])

    r_direct = fit(Loess(fraction = 0.5, surface_mode = "direct"), x, y)
    @printf("  direct:        y[1]=%.3f, y[end]=%.3f\n", r_direct.y[1], r_direct.y[end])

    for frac  [0.2, 0.5, 0.8]
        r = fit(Loess(fraction = frac, surface_mode = "direct"), x, y)
        @printf("  direct fraction=%.1f: y[1]=%.3f\n", frac, r.y[1])
    end

    r_se =
        fit(Loess(fraction = 0.5, surface_mode = "interpolation", return_se = true), x, y)
    r_se.enp !== nothing && @printf("  interpolation+SE enp: %.3f\n", r_se.enp)
    println()
end

# ── Main ──────────────────────────────────────────────────────────────────────
function main()
    println("=" ^ 60)
    println("FastLOESS Batch Smoothing - Comprehensive Examples")
    println("=" ^ 60)
    println()

    example_1_basic_smoothing()
    example_2_robust_with_outliers()
    example_3_uncertainty_quantification()
    example_4_cross_validation()
    example_5_complete_diagnostics()
    example_6_different_kernels()
    example_7_robustness_methods()
    example_8_benchmark()
    example_9_scaling_methods()
    example_10_boundary_policies()
    example_11_zero_weight_fallback()
    example_12_polynomial_degrees()
    example_13_distance_metrics()
    example_14_surface_modes_and_se()
    example_15_additional_kernels()
    example_16_loocv_and_auto_converge()
    example_17_interpolation_tuning()

    println("=== Batch Smoothing Examples Complete ===")
end

main()

Download batch_smoothing.jl


Streaming Smoothing

Process large datasets in memory-efficient chunks.

#!/usr/bin/env julia
"""
FastLOESS Streaming Smoothing - Comprehensive Examples

 1. Basic chunked processing
 2. Chunk size comparison
 3. Overlap strategies
 4. Large dataset processing
 5. Outlier handling in streaming mode
 6. File-based streaming simulation
 7. Benchmark (sequential streaming)
 8. Merge strategies
 9. Advanced streaming options
"""

using Printf

# Handle package loading
using Pkg
project_name = Pkg.project().name
if project_name != "FastLOESS"
    script_dir = @__DIR__
    julia_pkg_dir = joinpath(dirname(script_dir), "julia")
    if !haskey(Pkg.project().dependencies, "FastLOESS")
        Pkg.develop(path = julia_pkg_dir)
    end
end

using FastLOESS

make_linear(n) = (collect(Float64, 0:(n-1)), collect(Float64, 0:(n-1)) .* 2 .+ 1)

"""Feed only full-size chunks; finalize() handles remaining data."""
function collect_chunks(model, x, y, chunk_size, overlap)
    step = chunk_size - overlap
    n = length(x)
    result = nothing
    start = 1
    while start + chunk_size - 1 <= n
        res = process_chunk(
            model,
            x[start:(start+chunk_size-1)],
            y[start:(start+chunk_size-1)],
        )
        if result === nothing
            result = res
        else
            append!(result, res)
        end
        start += step
    end
    fin = finalize(model)
    if result === nothing
        result = fin
    else
        append!(result, fin)
    end
    return result
end

# ── Example 1: Basic Chunked Processing ─────────────────────────────────────
function example_1_basic_chunked_processing()
    println("Example 1: Basic Chunked Processing")
    n = 50
    x, y = make_linear(n)
    chunk_size, overlap = 15, 5
    model = StreamingLoess(
        fraction = 0.5,
        iterations = 2,
        chunk_size = chunk_size,
        overlap = overlap,
        return_residuals = true,
    )
    println("  Dataset: $n pts, chunk=$chunk_size, overlap=$overlap")
    total = 0
    ci = 0
    result = nothing
    start = 1
    while start + chunk_size - 1 <= n
        res = process_chunk(
            model,
            x[start:(start+chunk_size-1)],
            y[start:(start+chunk_size-1)],
        )
        if length(res.x) > 0
            total += length(res.x)
            @printf(
                "  Chunk %d: %d pts (x: %.0f..%.0f)\n",
                ci,
                length(res.x),
                res.x[1],
                res.x[end]
            )
            result = result === nothing ? res : (append!(result, res); result)
        end
        start += chunk_size - overlap
        ci += 1
    end
    fin = finalize(model)
    if length(fin.x) > 0
        total += length(fin.x)
        @printf("  Finalize: %d remaining pts\n", length(fin.x))
    end
    println("  Total: $total/$n")
    println()
end

# ── Example 2: Chunk Size Comparison ─────────────────────────────────────────
function example_2_chunk_size_comparison()
    println("Example 2: Chunk Size Comparison")
    n = 100
    x, y = make_linear(n)
    for (cs, ov, label)  [(20, 5, "Small"), (50, 10, "Medium"), (80, 15, "Large")]
        model =
            StreamingLoess(fraction = 0.5, iterations = 1, chunk_size = cs, overlap = ov)
        chunks = 0;
        total = 0;
        start = 1
        while start + cs - 1 <= n
            res = process_chunk(model, x[start:(start+cs-1)], y[start:(start+cs-1)])
            if length(res.x) > 0
                ;
                chunks += 1;
                total += length(res.x);
            end
            start += cs - ov
        end
        fin = finalize(model)
        if length(fin.x) > 0
            ;
            chunks += 1;
            total += length(fin.x);
        end
        println("  $label (size=$cs, overlap=$ov): chunks=$chunks, total=$total")
    end
    println()
end

# ── Example 3: Overlap Strategies ────────────────────────────────────────────
function example_3_overlap_strategies()
    println("Example 3: Overlap Strategies")
    n = 100
    x, y = make_linear(n)
    cs = 40
    for (overlap, label)  [(0, "No overlap"), (10, "10-pt overlap"), (20, "20-pt overlap")]
        model = StreamingLoess(fraction = 0.5, chunk_size = cs, overlap = overlap)
        total = 0;
        step = cs - overlap;
        start = 1
        while start + cs - 1 <= n
            total +=
                length(process_chunk(model, x[start:(start+cs-1)], y[start:(start+cs-1)]).x)
            start += step
        end
        total += length(finalize(model).x)
        println("  $label: total output=$total")
    end
    println()
end

# ── Example 4: Large Dataset Processing ──────────────────────────────────────
function example_4_large_dataset_processing()
    println("Example 4: Large Dataset Processing")
    n = 10_000
    x = collect(Float64, 0:(n-1))
    y = sin.(x .* 0.01) .+ x .* 0.001
    cs, ov = 500, 50
    model = StreamingLoess(fraction = 0.05, iterations = 2, chunk_size = cs, overlap = ov)
    total = 0;
    step = cs - ov;
    start = 1
    while start + cs - 1 <= n
        total +=
            length(process_chunk(model, x[start:(start+cs-1)], y[start:(start+cs-1)]).x)
        if total > 0 && total % 2000 < step
            println("  Progress: ~$total pts smoothed")
        end
        start += step
    end
    total += length(finalize(model).x)
    println("  Total: $total/$n, memory: constant (chunk=$cs)")
    println()
end

# ── Example 5: Outlier Handling in Streaming Mode ─────────────────────────────
function example_5_outlier_handling()
    println("Example 5: Outlier Handling in Streaming Mode")
    n = 100
    x = collect(Float64, 0:(n-1))
    y = 2 .* x .+ 1 .+ sin.(x .* 0.2) .* 2
    y[[26, 51, 76]] .+= 50  # Outliers (1-indexed)
    for method  ["bisquare", "huber", "talwar"]
        model = StreamingLoess(
            fraction = 0.5,
            iterations = 5,
            robustness_method = method,
            chunk_size = 30,
            overlap = 10,
            return_residuals = true,
        )
        large = 0;
        start = 1
        while start + 29 <= n
            res = process_chunk(model, x[start:(start+29)], y[start:(start+29)])
            if res.residuals !== nothing
                large += count(r -> abs(r) > 10, res.residuals)
            end
            start += 20
        end
        fin = finalize(model)
        if fin.residuals !== nothing
            large += count(r -> abs(r) > 10, fin.residuals)
        end
        println("  $method: pts with |residual|>10: $large")
    end
    println()
end

# ── Example 6: File-Based Streaming Simulation ───────────────────────────────
function example_6_file_simulation()
    println("Example 6: File-Based Streaming Simulation")
    println("  Simulating: input.csv -> Smooth -> output.csv")
    total_lines, cs, ov = 200, 50, 10
    model = StreamingLoess(
        fraction = 0.5,
        iterations = 2,
        chunk_size = cs,
        overlap = ov,
        return_residuals = true,
    )
    out_count = 0;
    ci = 0;
    start_line = 0
    while start_line < total_lines
        end_line = min(start_line + cs, total_lines)
        xc = collect(Float64, start_line:(end_line-1))
        yc = 2 .* xc .+ 1 .+ sin.(xc .* 0.1) .* 3
        println("  Reading chunk $ci (lines $start_line..$(end_line-1))")
        res = process_chunk(model, xc, yc)
        if length(res.x) > 0
            out_count += length(res.x)
            println("    -> Writing $(length(res.x)) smoothed pts (total: $out_count)")
        end
        start_line += cs - ov
        ci += 1
    end
    fin = finalize(model)
    if length(fin.x) > 0
        out_count += length(fin.x)
        println("  Finalizing: $(length(fin.x)) remaining pts")
    end
    println("  Input: $total_lines, Output: $out_count")
    println()
end

# ── Example 7: Benchmark (Sequential Streaming) ───────────────────────────────
function example_7_benchmark()
    println("Example 7: Benchmark (Sequential Streaming)")
    n, cs, ov = 1000, 100, 10
    model = StreamingLoess(fraction = 0.5, iterations = 3, chunk_size = cs, overlap = ov)
    t0 = time()
    total = 0;
    start = 1
    while start + cs - 1 <= n
        xc = collect(Float64, (start-1):(start+cs-2))
        yc = sin.(xc .* 0.1) .+ cos.(xc .* 0.01)
        total += length(process_chunk(model, xc, yc).x)
        start += cs - ov
    end
    total += length(finalize(model).x)
    ms = (time() - t0) * 1000
    @printf("  %d pts in %.2fms (chunk=%d, overlap=%d)\n", total, ms, cs, ov)
    println()
end

# ── Example 8: Merge Strategies ──────────────────────────────────────────────
function example_8_merge_strategies()
    println("Example 8: Merge Strategies")
    n = 50
    x, y = make_linear(n)
    for strategy  ["average", "weighted_average", "take_first", "take_last"]
        model = StreamingLoess(
            fraction = 0.5,
            iterations = 2,
            chunk_size = 20,
            overlap = 5,
            merge_strategy = strategy,
        )
        total = 0;
        start = 1
        while start + 19 <= n
            total +=
                length(process_chunk(model, x[start:(start+19)], y[start:(start+19)]).x)
            start += 15
        end
        total += length(finalize(model).x)
        println("  $strategy: total=$total")
    end
    println()
end

# ── Example 9: Advanced Streaming Options ─────────────────────────────────────
function example_9_advanced_options()
    println("Example 9: Advanced Streaming Options")
    n = 50
    x, y = make_linear(n)
    model = StreamingLoess(
        fraction = 0.5,
        iterations = 2,
        degree = "quadratic",
        scaling_method = "mar",
        boundary_policy = "reflect",
        zero_weight_fallback = "return_original",
        distance_metric = "manhattan",
        surface_mode = "direct",
        return_se = true,
        return_diagnostics = true,
        return_robustness_weights = true,
        auto_converge = 1e-3,
        chunk_size = 20,
        overlap = 5,
    )
    total = 0;
    start = 1
    while start + 19 <= n
        total += length(process_chunk(model, x[start:(start+19)], y[start:(start+19)]).x)
        start += 15
    end
    fin = finalize(model)
    total += length(fin.x)
    println("  total pts: $total")
    if fin.standard_errors !== nothing && !isempty(fin.standard_errors)
        @printf("  standard_errors[1]: %.4f\n", fin.standard_errors[1])
    end
    if fin.diagnostics !== nothing
        @printf("  diagnostics.rmse: %.3f\n", fin.diagnostics.rmse)
        @printf("  diagnostics.r_squared: %.3f\n", fin.diagnostics.r_squared)
        !isnan(fin.diagnostics.aic) &&
            @printf("  diagnostics.aic: %.3f\n", fin.diagnostics.aic)
    end
    if fin.robustness_weights !== nothing && !isempty(fin.robustness_weights)
        @printf("  robustness_weights[1]: %.4f\n", fin.robustness_weights[1])
    end
    println()
end

# ── Main ──────────────────────────────────────────────────────────────────────
function main()
    println("=" ^ 60)
    println("FastLOESS Streaming Smoothing - Comprehensive Examples")
    println("=" ^ 60)
    println()

    example_1_basic_chunked_processing()
    example_2_chunk_size_comparison()
    example_3_overlap_strategies()
    example_4_large_dataset_processing()
    example_5_outlier_handling()
    example_6_file_simulation()
    example_7_benchmark()
    example_8_merge_strategies()
    example_9_advanced_options()

    println("=== Streaming Smoothing Examples Complete ===")
end

main()

Download streaming_smoothing.jl


Online Smoothing

Real-time smoothing with sliding window for streaming data.

#!/usr/bin/env julia
"""
FastLOESS Online Smoothing - Comprehensive Examples

 1. Basic incremental processing
 2. Real-time sensor data simulation
 3. Outlier handling in online mode
 4. Window size comparison
 5. Memory-bounded processing (embedded systems)
 6. Sliding window behavior
 7. Benchmark (sequential online)
 8. Update modes (Full vs Incremental) and min_points
 9. Advanced online options
"""

using Printf

# Handle package loading
using Pkg
project_name = Pkg.project().name
if project_name != "FastLOESS"
    script_dir = @__DIR__
    julia_pkg_dir = joinpath(dirname(script_dir), "julia")
    if !haskey(Pkg.project().dependencies, "FastLOESS")
        Pkg.develop(path = julia_pkg_dir)
    end
end

using FastLOESS

# Helper: feed all (x, y) pairs through add_point; return vector of smoothed values (NaN when None).
function add_all_points(model, x, y)
    [
        let r = add_point(model, x[i], y[i]);
            r !== nothing ? r.smoothed : NaN
        end for i  eachindex(x)
    ]
end

# ── Example 1: Basic Incremental Processing ──────────────────────────────────
function example_1_basic_streaming()
    println("Example 1: Basic Incremental Processing")
    x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
    y = [3.1, 5.0, 7.2, 8.9, 11.1, 13.0, 15.2, 16.8, 19.1, 21.0]
    model = OnlineLoess(fraction = 0.5, iterations = 2, window_capacity = 5)
    smoothed = add_all_points(model, x, y)
    @printf("  %8s %12s %12s\n", "X", "Y_obs", "Y_smooth")
    for i  eachindex(x)
        sv = isnan(smoothed[i]) ? "  (buffering)" : @sprintf("%12.2f", smoothed[i])
        @printf("  %8.2f %12.2f %s\n", x[i], y[i], sv)
    end
    println()
end

# ── Example 2: Real-Time Sensor Data Simulation ───────────────────────────────
function example_2_sensor_data_simulation()
    println("Example 2: Real-Time Sensor Data Simulation")
    println("  Simulating temperature sensor with noise...")
    hours = collect(Float64, 0:23)
    temp = 20 .+ 5 .* sin.(hours .* π ./ 12) .+ (mod.(hours .* 7, 11)) .* 0.3 .- 1.5
    model = OnlineLoess(
        fraction = 0.4,
        iterations = 3,
        robustness_method = "bisquare",
        window_capacity = 12,
    )
    smoothed = add_all_points(model, hours, temp)
    @printf("  %6s %12s %12s\n", "Hour", "Raw", "Smoothed")
    for i  eachindex(hours)
        sv = isnan(smoothed[i]) ? "  (warming up)" : @sprintf("%10.2f°C", smoothed[i])
        @printf("  %6.0f %10.2f°C %s\n", hours[i], temp[i], sv)
    end
    println()
end

# ── Example 3: Outlier Handling in Online Mode ────────────────────────────────
function example_3_outlier_handling()
    println("Example 3: Outlier Handling in Online Mode")
    x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
    y = [2.0, 4.1, 5.9, 25.0, 10.1, 12.0, 14.1, 50.0, 18.0, 20.1]
    for method  ["bisquare", "talwar"]
        model = OnlineLoess(
            fraction = 0.5,
            iterations = 5,
            robustness_method = method,
            window_capacity = 6,
        )
        smoothed = filter(!isnan, add_all_points(model, x, y))
        println("  $method: [$(join(round.(smoothed, digits=1), ", "))]")
    end
    println()
end

# ── Example 4: Window Size Comparison ────────────────────────────────────────
function example_4_window_size_comparison()
    println("Example 4: Window Size Comparison")
    x = collect(Float64, 1:20)
    y = 2 .* x .+ sin.(x .* 0.5) .* 3
    for w  [5, 10, 15]
        model = OnlineLoess(fraction = 0.5, iterations = 2, window_capacity = w)
        smoothed = filter(!isnan, add_all_points(model, x, y))
        last5 = smoothed[(end-4):end]
        println("  window_capacity=$w: last 5 = [$(join(round.(last5, digits=2), ", "))]")
    end
    println()
end

# ── Example 5: Memory-Bounded Processing ──────────────────────────────────────
function example_5_memory_bounded_processing()
    println("Example 5: Memory-Bounded Processing (Embedded Systems)")
    total = 1000
    x = collect(Float64, 0:(total-1))
    y = 2 .* x .+ sin.(x .* 0.1) .* 5 .+ (mod.(0:(total-1), 7) .- 3) .* 0.5
    model = OnlineLoess(fraction = 0.3, iterations = 1, window_capacity = 20)
    smoothed = filter(!isnan, add_all_points(model, x, y))
    n_out = length(smoothed)
    for milestone  [200, 400, 600, 800, 1000]
        milestone <= n_out && @printf(
            "  Processed: %4d pts | smoothed=%.2f\n",
            milestone,
            smoothed[milestone]
        )
    end
    @printf("  Total: %d, final smoothed: %.2f\n", n_out, smoothed[end])
    println("  Memory: constant (window=20)")
    println()
end

# ── Example 6: Sliding Window Behavior ───────────────────────────────────────
function example_6_sliding_window_behavior()
    println("Example 6: Sliding Window Behavior")
    x_all = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
    y_all = [2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0]
    model = OnlineLoess(fraction = 0.6, iterations = 0, window_capacity = 4)
    @printf("  %4s %4s %6s %10s %-22s\n", "Pt", "X", "Y", "Smoothed", "Status")
    for i  eachindex(x_all)
        r = add_point(model, x_all[i], y_all[i])
        if r !== nothing
            @printf(
                "  %4d %4.0f %6.0f %10.2f %-22s\n",
                i,
                x_all[i],
                y_all[i],
                r.smoothed,
                "Window full (sliding)"
            )
        else
            @printf(
                "  %4d %4.0f %6.0f %10s %-22s\n",
                i,
                x_all[i],
                y_all[i],
                "-",
                "Filling ($i/4)"
            )
        end
    end
    println("  Output starts after window fills (4 pts), then slides.")
    println()
end

# ── Example 7: Benchmark (Sequential Online) ──────────────────────────────────
function example_7_benchmark()
    println("Example 7: Benchmark (Sequential Online)")
    n = 1000
    x = collect(Float64, 0:(n-1))
    y = sin.(x .* 0.1) .+ cos.(x .* 0.01)
    model = OnlineLoess(fraction = 0.5, iterations = 3, window_capacity = 10)
    t0 = time()
    smoothed = filter(!isnan, add_all_points(model, x, y))
    ms = (time() - t0) * 1000
    @printf("  %d pts processed in %.2fms (window_capacity=10)\n", length(smoothed), ms)
    println()
end

# ── Example 8: Update Modes (Full vs Incremental) and min_points ───────────────
function example_8_update_modes()
    println("Example 8: Update Modes (Full vs Incremental) and min_points")
    x = collect(Float64, 0:29)
    y = 2 .* x .+ 1
    for mode  ["full", "incremental"]
        model = OnlineLoess(
            fraction = 0.5,
            iterations = 2,
            update_mode = mode,
            min_points = 5,
            window_capacity = 15,
        )
        smoothed = filter(!isnan, add_all_points(model, x, y))
        println("  $mode: $(length(smoothed)) pts emitted (out of $(length(x)))")
    end
    model =
        OnlineLoess(fraction = 0.5, iterations = 2, window_capacity = 10, min_points = 3)
    smoothed = filter(!isnan, add_all_points(model, x, y))
    @printf("  last smoothed: %.3f\n", smoothed[end])
    println()
end

# ── Example 9: Advanced Online Options ────────────────────────────────────────
function example_9_advanced_online_options()
    println("Example 9: Advanced Online Options")
    x = collect(Float64, 0:29)
    y = 2 .* x .+ 1
    model = OnlineLoess(
        fraction = 0.5,
        iterations = 2,
        degree = "quadratic",
        scaling_method = "mar",
        boundary_policy = "reflect",
        zero_weight_fallback = "return_original",
        distance_metric = "chebyshev",
        auto_converge = 1e-3,
        return_robustness_weights = true,
        min_points = 5,
        window_capacity = 15,
    )
    smoothed = filter(!isnan, add_all_points(model, x, y))
    println("  emitted: $(length(smoothed))")
    length(smoothed) > 0 && @printf("  last smoothed: %.3f\n", smoothed[end])
    println()
end

# ── Main ──────────────────────────────────────────────────────────────────────
function main()
    println("=" ^ 60)
    println("FastLOESS Online Smoothing - Comprehensive Examples")
    println("=" ^ 60)
    println()

    example_1_basic_streaming()
    example_2_sensor_data_simulation()
    example_3_outlier_handling()
    example_4_window_size_comparison()
    example_5_memory_bounded_processing()
    example_6_sliding_window_behavior()
    example_7_benchmark()
    example_8_update_modes()
    example_9_advanced_online_options()

    println("=== Online Smoothing Examples Complete ===")
end

main()

Download online_smoothing.jl


Installation

using Pkg
Pkg.develop(path="bindings/julia/julia")

Running the Examples

julia --project=bindings/julia/julia examples/julia/batch_smoothing.jl
julia --project=bindings/julia/julia examples/julia/streaming_smoothing.jl
julia --project=bindings/julia/julia examples/julia/online_smoothing.jl

Quick Start

using FastLOESS

# Generate sample data
x = collect(0.0:0.1:10.0)
y = sin.(x) .+ 0.3 .* randn(length(x))

# Basic smoothing
model = Loess(fraction=0.3)
result = fit(model, x, y)
println("Smoothed values: ", result.y[1:5])

# With options
result2 = fit(Loess(
    fraction=0.3,
    iterations=3,
    confidence_intervals=0.95,
    return_diagnostics=true
), x, y)

println("R²: ", result2.diagnostics.r_squared)

# Access confidence intervals
lower = result2.confidence_lower
upper = result2.confidence_upper

Features

The Julia bindings provide:

  • Native Julia types - Uses Julia arrays directly
  • C FFI integration - Efficient bindings via ccall
  • Multiple dispatch - Works with Float32 and Float64
  • Full parameter access - All LOESS options available