SonataSmooth.Tune
3.1.5
dotnet add package SonataSmooth.Tune --version 3.1.5
NuGet\Install-Package SonataSmooth.Tune -Version 3.1.5
<PackageReference Include="SonataSmooth.Tune" Version="3.1.5" />
<PackageVersion Include="SonataSmooth.Tune" Version="3.1.5" />
<PackageReference Include="SonataSmooth.Tune" />
paket add SonataSmooth.Tune --version 3.1.5
#r "nuget: SonataSmooth.Tune, 3.1.5"
#:package SonataSmooth.Tune@3.1.5
#addin nuget:?package=SonataSmooth.Tune&version=3.1.5
#tool nuget:?package=SonataSmooth.Tune&version=3.1.5
SonataSmooth.Tune
High‑performance 1D numeric signal smoothing & export toolkit for .NET (C#).
Implements Rectangular (Moving Average), Binomial (Pascal) Average, Weighted Median (Binomial weights), Gaussian, and Savitzky-Golay smoothing with configurable boundary handling and optional parallelization. Includes CSV and Excel (COM) export helpers that materialize multiple smoothing "voices" side‑by‑side for inspection or charting.
Target : .NET Standard 2.0 (core algorithms & CSV export)
Optional Excel COM automation sections use conditional compilation (#if NET48
) or late binding (dynamic COM) when available.
Contents
- Features
- Installation
- Quick Start
- Concepts & Design Notes
- Boundary Handling
- Implemented Filters
- Performance Characteristics
- CSV Header Ordering Note
- API Reference
- Enum:
BoundaryMode
- Core static class:
SmoothingConductor
ApplySmoothing
GetValueWithBoundary
CalcBinomialCoefficients
ComputeGaussianCoefficients
ComputeSavitzkyGolayCoefficients
ValidateSmoothingParameters
- Validation helper :
ScoreConformanceChecker
- CSV / Excel export helpers (
ExportCsvAsync
,ExportCsvAsyncFromResults
,ExportExcelAsync
)
- Additional CSV tuning parameters :
- progressCheckInterval (int, default 1): Throttles how often progress is recomputed / reported (every N rows).
- customFlushLineThreshold (int?): Overrides the adaptive buffered write flush batch size; null keeps adaptive logic.
- Data containers:
SmoothingScore
,SmoothingNotation
- CSV export types:
CsvScoreRequest
,CsvExportResult
,CsvScoreWriter
- Excel export types:
ExcelScoreRequest
,ExcelScoreWriter
,ExcelInteropNotAvailableException
- Enum:
- Error & Exception Reference
- Usage Examples
- Best Practices
- Thread Safety
- Limitations & Known Inconsistencies
- License (MIT)
Features
- Compute up to five smoothing variants in a single pass over the source data.
- Window-based convolution / order polynomial fitting (Savitzky-Golay) with user-specified radius.
- Weighted median using binomial coefficients for robust noise suppression.
- Automatic parallel execution threshold (
n ≥ 2000
) for CPU-bound steps. - Culture-invariant numeric formatting for export.
- Large dataset CSV partitioning honoring Excel row limit (1,048,576).
- Efficient buffered CSV writer with adaptive flush strategy.
- Excel export :
- Full multi-series line chart generation.
- Multi-column continuation for > 1,048,573 rows (per-column fill strategy).
- Document properties + playful meta "phrases" (retained).
- Late binding fallback when strong interop PIAs not available (non-
NET48
). - Boundary labels in Excel : high-level
ExcelScoreWriter
uses abbreviated labels ("Symmetric", "Replicate", "ZeroPad"); the core SmoothingConductor Excel export uses extended forms ("Symmetric (Mirror)", etc.) - Worksheet header note :
SmoothingConductor.ExportExcelAsync
writes "Subject" and "Comments" rows into the worksheet;ExcelScoreWriter.ExportAsync
stores these only as document properties (not repeated as sheet rows).
- Configurable boundary modes: Symmetric (mirror), Replicate (clamp), ZeroPad (explicit zeros), Adaptive (full in‑range sliding window; asymmetric near edges; no synthetic samples).
Installation
NuGet (preferred) : dotnet add package SonataSmooth.Tune
Package Manager : Install-Package SonataSmooth.Tune
Quick Start
using SonataSmooth.Tune;
double[] data = { 1, 2, 3, 10, 9, 5, 4, 3, 2 };
int radius = 2; // Smoothing window size calculated from radius: (2 * radius) + 1 = 5
int polyOrder = 2; // Degree of the polynomial used in Savitzky-Golay smoothing
var (rect, binomAvg, median, gauss, sg) = SmoothingConductor.ApplySmoothing(
data,
r: radius,
polyOrder: polyOrder,
boundaryMode: BoundaryMode.Symmetric,
doRect: true,
doAvg: true,
doMed: true,
doGauss: true,
doSG: true
);
// (Optional) Validate parameters first using the tuple helper
using SonataSmooth.Tune.Export;
var (ok, validationError) = ScoreConformanceChecker.Validate(
dataCount: data.Length,
r: radius,
polyOrder: polyOrder,
useSG: true // set to false if you disable SG
);
if (!ok)
{
Console.WriteLine(validationError);
return; // Abort before running smoothing/export
}
CSV export (computed internally) :
using SonataSmooth.Tune.Export;
var req = new CsvScoreRequest
{
Title = "Demo Dataset",
BaseFilePath = @"C:\Temp\demo.csv",
InitialData = data,
Radius = radius,
PolyOrder = polyOrder,
BoundaryMode = BoundaryMode.Symmetric,
Flags = new SmoothingNotation
{
Rectangular = true,
BinomialAverage = true,
BinomialMedian = true,
Gaussian = true,
SavitzkyGolay = true
}
};
var result = await CsvScoreWriter.ExportAsync(req);
Note : When using CsvScoreWriter.ExportAsync the "Boundary Method" header uses abbreviated labels ("Symmetric", "Replicate", "ZeroPad"). The lower-level SmoothingConductor.ExportCsvAsync / ExportCsvAsyncFromResults use extended labels ("Symmetric (Mirror)", "Replicate (Nearest)", "Zero Padding").
CSV Header Ordering Note
High-level CSV export (CsvScoreWriter.ExportAsync
) writes header metadata in this order:
- Kernel Radius
- Kernel Width
- Boundary Method
- Polynomial Order (only when Savitzky–Golay enabled)
- Derivative Order (only when Savitzky–Golay enabled and
DerivOrder > 0
)
Lower-level conductor exports (SmoothingConductor.ExportCsvAsync
/ ExportCsvAsyncFromResults
) place polynomial (and derivative, if present) lines before the boundary method line:
- Kernel Radius
- Kernel Width
- Polynomial Order (if SG)
- Derivative Order (if SG & d > 0)
- Boundary Method
This divergence is intentional for legacy compatibility. If you parse headers automatically, normalize by key name rather than relying on positional order.
Savitzky–Golay Derivative Order (d)
This library supports Savitzky–Golay derivative filters in addition to 0th‑order smoothing.
- Core APIs:
- SmoothingConductor.ComputeSavitzkyGolayCoefficients(windowSize, polyOrder, derivativeOrder, delta)
- SmoothingConductor.ApplySGDerivative(input, r, polyOrder, derivativeOrder, delta, boundaryMode)
- Request DTOs:
- CsvScoreRequest.DerivOrder (int, default 0)
- ExcelScoreRequest.DerivOrder (int, default 0)
Behavior:
- d = 0 yields classic smoothing (coefficients normalized to sum = 1).
- d ≥ 1 yields the d‑th derivative estimate at the window center; output is scaled by d! / Δ^d.
- Exports:
- When Flags.SavitzkyGolay is true and DerivOrder > 0, the “Savitzky–Golay Filtering” column contains the derivative series (not the smoothed series).
- CSV/Excel headers include “Derivative Order : d”. CSV/Excel writers assume Δ = 1.0 for exported derivatives.
Constraints:
- Radius r ≥ 0; windowSize = 2r + 1 must fit in the dataset length.
- 0 ≤ derivativeOrder ≤ polyOrder
- 0 ≤ polyOrder < windowSize
- delta > 0 (only in low‑level APIs; export writers use 1.0)
Notes:
- ScoreConformanceChecker.Validate does not take DerivOrder. Derivative constraints are validated by CsvScoreWriter/ExcelScoreWriter and by SmoothingConductor at execution time.
- For non‑unit sample spacing (Δ ≠ 1), call SmoothingConductor.ApplySGDerivative directly with your Δ and then export via SmoothingConductor.ExportCsvAsyncFromResults.
Example: First derivative (d = 1)
var d1 = SmoothingConductor.ApplySGDerivative(
input: samples,
r: 4,
polyOrder: 3,
derivativeOrder: 1,
delta: 1.0,
boundaryMode: BoundaryMode.Symmetric
);
// CSV export with derivative (Δ = 1.0)
var csvReq = new SonataSmooth.Tune.Export.CsvScoreRequest
{
Title = "Run A (d=1)",
BaseFilePath = @"C:\out\runA_deriv.csv",
InitialData = samples,
Radius = 4,
PolyOrder = 3,
BoundaryMode = BoundaryMode.Symmetric,
Flags = new SonataSmooth.Tune.Export.SmoothingNotation
{
SavitzkyGolay = true
},
DerivOrder = 1
};
var csvResult = await SonataSmooth.Tune.Export.CsvScoreWriter.ExportAsync(csvReq);
// Excel export with derivative (Δ = 1.0)
var xlsReq = new SonataSmooth.Tune.Export.ExcelScoreRequest
{
DatasetTitle = "Signal 42 (d=1)",
InitialData = samples,
Radius = 4,
PolyOrder = 3,
BoundaryMode = BoundaryMode.Symmetric,
Flags = new SonataSmooth.Tune.Export.SmoothingNotation
{
SavitzkyGolay = true
},
DerivOrder = 1
};
await SonataSmooth.Tune.Export.ExcelScoreWriter.ExportAsync(xlsReq);
Note (Adaptive + Derivatives) :
Adaptive boundary handling applies equally to derivative kernels (via ApplySGDerivative
) : the per-position asymmetric fit is still used; no special derivative-only padding is introduced.
Concepts & Design Notes
Concept | Note |
---|---|
Radius | Half-width of kernel. Window size = 2 * r + 1 (must be odd, > 0). |
One-pass allocation | Arrays allocated once; each enabled filter computed per index. |
Parallelization | Parallel.For engaged when n >= 2000 . |
Weighted Median | Re-computes local window list + sort per index (O(w log w)); heavier than simple linear filters. |
Gaussian σ | Chosen as (2r + 1)/6 for approximate coverage of ±3σ across the window. |
Savitzky-Golay | Normalized to unit DC gain (coefficients sum = 1). |
Binomial limit | Length ≤ 63 to prevent overflow (64-bit safety). |
Boundary Handling
BoundaryMode
:
Symmetric
: Mirror index (reflective). Example: index -1 → element 0 mirrored (implemented as-idx - 1
mapping).Replicate
: Clamp to nearest endpoint (edge value continuation).ZeroPad
: Outside indices treated as 0.
Historical Note: Earlier UI tooltips referenced “Adaptive (Local Poly + Median)” implying SG-only behavior. Current implementation applies Adaptive sliding uniformly to all enabled filters.
Adaptive Mode
Adaptive keeps the nominal window length (2 * r + 1) but slides the window fully inside the valid data range for every index:
- No mirrored, clamped, or zero-padded synthetic samples are introduced.
- For Rectangular, Binomial Average, Weighted Median, and Gaussian filters: an in‑range (possibly asymmetric) block is used directly.
- For Savitzky–Golay: per-position asymmetric coefficients are computed (cached) for (left,right) around the logical center.
- Benefits: avoids artificial edge energy inflation/attenuation.
- Trade‑off: near edges the “center” of the polynomial fit is no longer geometrically centered relative to the original index (phase / alignment shift).
- Implementation detail: loops bypass
GetValueWithBoundary
whenAdaptive
to gather a shifted real-sample window.
Use Symmetric when strict geometric centering at edges is more important than removing padding artifacts.
Note : Adaptive boundary handling applies equally to derivative kernels; per-position asymmetric fits are used for all supported filters.
Implemented Filters (Brief)
Filter | Characteristic | Complexity per sample |
---|---|---|
Rectangular Average | Uniform weights | O(w) |
Binomial Average | Pascal row weights, smoother than uniform | O(w) |
Weighted Median | Robust to spikes, preserves edges | O(w log w) |
Gaussian | Pre-normalized kernel | O(w) |
Savitzky-Golay | Local polynomial least squares (smoothing 0th, derivatives d ≥ 1) | O(w) after precompute |
w = 2r + 1
where r
is the kernel radius.
Performance Characteristics
- Time : Dominated by selected filters; enabling all includes one sorting per sample (median).
- Memory : 5 output arrays ×
n
doubles (40n bytes) if all enabled. - Parallel : Gains most when median disabled or window moderate (sorting cost can reduce scaling).
- CSV Export : Streaming + buffered StringBuilder; partitioning to prevent Excel row overflow.
API Reference
Enum: BoundaryMode
public enum BoundaryMode
{
Symmetric, // Mirror : Reflect indices across boundaries (e.g., [3, 2, 1, 0, 1, 2, 3])
Replicate, // Clamp : Extend edge values beyond boundaries
ZeroPad, // Pad with zeros : Use zero-padding for out-of-bound indices
Adaptive
}
Class: SmoothingConductor
(static)
ApplySmoothing
public static (
double[] Rect,
double[] Binom,
double[] Median,
double[] Gauss,
double[] SG
) ApplySmoothing(
double[] input,
int r,
int polyOrder,
BoundaryMode boundaryMode,
bool doRect,
bool doAvg,
bool doMed,
bool doGauss,
bool doSG
)
Parameters:
input
(required) : Source sequence.r
: Kernel radius ≥ 0.polyOrder
: Used only ifdoSG == true
. Must be< windowSize
.boundaryMode
: SeeBoundaryMode
.doRect
...doSG
: Flags enabling each smoothing.
Returns: Tuple in fixed order : (Rectangular, BinomialAverage, WeightedMedian, Gaussian, SavitzkyGolay). Disabled filters still allocate arrays (filled with 0) for positional consistency.
Exceptions:
ArgumentNullException
(input
)ArgumentOutOfRangeException
(r < 0
)- From subroutines (e.g., Savitzky-Golay coefficient generation constraints).
GetValueWithBoundary
public static double GetValueWithBoundary(
double[] data,
int idx,
BoundaryMode mode
)
Resolves and returns the value at a logical index using the selected boundary handling policy (mirror, clamp, or zero pad). No smoothing is performed here; this is an index resolution helper used by the filters.
ComputeGaussianCoefficients
public static double[] ComputeGaussianCoefficients(
int length,
double sigma
)
Constraints :
length
≥ 1 (typically odd to align with 2r+1 windows)sigma
> 0
Returns a symmetric Gaussian weight array normalized so the sum ≈ 1.
Exceptions :
- ArgumentException (length < 1 or sigma ≤ 0)
- InvalidOperationException (numerical anomaly resulting in non-positive sum)
ComputeSavitzkyGolayCoefficients
public static double[] ComputeSavitzkyGolayCoefficients(
int windowSize,
int polyOrder
)
Constraints :
windowSize
> 0 and odd.polyOrder >= 0 && polyOrder < windowSize
. Produces normalized smoothing (0th derivative) coefficients.
ValidateSmoothingParameters
public static bool ValidateSmoothingParameters(
int dataCount,
int r,
int polyOrder,
bool useSG,
out string error
)
Checks :
(2r + 1) ≤ dataCount
- If
useSG
,polyOrder < (2r + 1)
Returnsfalse
with descriptiveerror
block if invalid.
Validation Helper: ScoreConformanceChecker
A tuple-return wrapper around SmoothingConductor.ValidateSmoothingParameters
:
var (success, error) = ScoreConformanceChecker.Validate(
dataCount: input.Length,
r: r,
polyOrder: polyOrder,
useSG: doSG
);
if (!success)
{
// Abort early – error contains multi-line diagnostic
Console.WriteLine(error);
return;
}
**Rules enforced (delegated) 😗*
r >= 0
(2 * r + 1) <= dataCount
- If
useSG
:polyOrder < (2 * r + 1)
Use this for cleaner guard clauses (no out string
).
Note : The wrapper now enforces a non‑negative kernel radius (
r >= 0
) in addition to the existing rules.
Caution : Callers no longer need to pre‑checkr >= 0
before invoking this validator, as the check is performed internally.
ExportCsvAsync / ExportCsvAsyncFromResults
High-level CSV generation with partitioning (honors Excel max row limit).
Two overload paths:
ExportCsvAsync
: Recomputes smoothing internally.ExportCsvAsyncFromResults
: Accepts already-computed arrays to avoid recomputation cost.
Notable optional parameters:
progress
(Action<int>
) : Reports rough percent (resets to 0 at completion).progressCheckInterval
: Throttle frequency (default 1 = every line).customFlushLineThreshold
: Controls buffered flush size (auto if null).
ExportExcelAsync
Creates a live Excel instance (requires Microsoft Excel installed & COM available).
Populates per-filter columns (with multi-column continuation for very large arrays) and builds a composite line chart.
Releases COM RCWs after making Excel visible (workbook remains open to user).
Exceptions surfaced via showMessage
callback; some internal catch blocks suppress to keep UI responsive.
Data Container : SmoothingNotation
public sealed class SmoothingNotation
{
public bool Rectangular { get; set; }
public bool BinomialAverage { get; set; }
public bool BinomialMedian { get; set; }
public bool Gaussian { get; set; }
public bool SavitzkyGolay { get; set; }
public bool Any =>
Rectangular ||
BinomialAverage ||
BinomialMedian ||
Gaussian ||
SavitzkyGolay;
}
Utility flag bundle passed to export requests.
Data Container : SmoothingScore
public sealed class SmoothingScore
{
public double[] Initial { get; set; }
public double[] Rect { get; set; }
public double[] BinomAvg { get; set; }
public double[] BinomMed { get; set; }
public double[] Gauss { get; set; }
public double[] SavitzkyGolay { get; set; }
public int Length => Initial?.Length ?? 0;
}
(Not currently returned by core API; available for potential aggregation wrappers.)
CSV Export Types
CsvScoreRequest
public sealed class CsvScoreRequest
{
public string Title { get; set; }
public string BaseFilePath { get; set; }
public double[] InitialData { get; set; }
public int Radius { get; set; }
public int PolyOrder { get; set; }
public int DerivOrder { get; set; } // 0 = smoothing, d > 0 = d-th derivative (only used when Flags.SavitzkyGolay == true)
public BoundaryMode BoundaryMode { get; set; }
public SmoothingNotation Flags { get; set; }
// Optional post-processing flag for UI actions (e.g., auto-open file)
public bool OpenAfterExport { get; set; }
}
CsvExportResult
public sealed class CsvExportResult
{
public List<string> GeneratedFiles { get; } = new List<string>();
}
CsvScoreWriter
public static class CsvScoreWriter
{
public static Task<CsvExportResult> ExportAsync(
CsvScoreRequest request,
IProgress<int> progress = null,
CancellationToken cancellationToken = default
)
}
Behavior :
- Validates parameters via a checker (
ScoreConformanceChecker.Validate
in consuming project). - Splits output into parts if row limit exceeded.
- Column order : Initial Dataset + (enabled filters in consistent descriptive naming).
- Progress : 0 – 100 based on rows processed. Resets to 0 at completion (intentionally mirrors legacy semantics).
- Cancellation : Cooperative via
CancellationToken.ThrowIfCancellationRequested()
inside loop.
Excel Export Types
ExcelScoreRequest
public sealed class ExcelScoreRequest
{
public string DatasetTitle { get; set; }
public double[] InitialData { get; set; }
public int Radius { get; set; }
public int PolyOrder { get; set; }
public int DerivOrder { get; set; } // 0 = smoothing, d > 0 = d-th derivative (only used when Flags.SavitzkyGolay == true)
public BoundaryMode BoundaryMode { get; set; }
public SmoothingNotation Flags { get; set; }
}
ExcelScoreWriter
public static class ExcelScoreWriter
{
public static Task ExportAsync(
ExcelScoreRequest request,
IProgress<int> progress = null
);
}
Notes:
- Two conditional implementations:
#if NET48
strong-typed reference to Excel PIA (method signature usesExcelExportRequest
in code region – naming mismatch withExcelScoreRequest
; see "Limitations & Known Inconsistencies").- Else : dynamic late binding (
Type.GetTypeFromProgID("Excel.Application")
), throwsExcelInteropNotAvailableException
if unavailable.
ExcelInteropNotAvailableException
Thrown when COM activation cannot proceed (Excel missing / ProgID failure).
Error & Exception Reference (Selected)
Source | Condition | Exception |
---|---|---|
ApplySmoothing |
input == null |
ArgumentNullException |
r < 0 |
ArgumentOutOfRangeException | |
CalcBinomialCoefficients |
length < 1 | ArgumentException |
length > 63 | ArgumentOutOfRangeException | |
ComputeSavitzkyGolayCoefficients |
even window or invalid poly order | ArgumentException |
Matrix inversion | singular / ill-conditioned | InvalidOperationException |
CSV export | InitialData null |
ArgumentNullException |
CSV export | data length 0 | InvalidOperationException |
CSV export | cancellation requested (token signaled) | OperationCanceledException |
Excel late binding | Excel not installed | ExcelInteropNotAvailableException |
Excel export | no enabled sections | InvalidOperationException |
Usage Examples
1. Savitzky-Golay Only
var (_, _, _, _, sg) = SmoothingConductor.ApplySmoothing(
input: signal,
r: 4,
polyOrder: 3,
boundaryMode: BoundaryMode.Replicate,
doRect: false,
doAvg: false,
doMed: false,
doGauss: false,
doSG: true
);
2. Precompute & Export CSV Without Recalculation
int r = 3;
int poly = 2;
// Execute a range of smoothing algorithms on the input data
var (rect, avg, med, gauss, sg) = SmoothingConductor.ApplySmoothing(
data,
r,
poly,
BoundaryMode.Symmetric,
doRect: true,
doAvg: true,
doMed: true,
doGauss: true,
doSG: true
);
// Write smoothing results to a CSV file
await SmoothingConductor.ExportCsvAsyncFromResults(
filePath: @"C:\out\multi.csv",
title: "Precomputed Export",
kernelRadius: r,
polyOrder: poly,
boundaryMode: BoundaryMode.Symmetric,
doRect: true,
doAvg: true,
doMed: true,
doGauss: true,
doSG: true,
initialData: data,
rectAvg: rect,
binomAvg: avg,
binomMed: med,
gaussFilt: gauss,
sgFilt: sg,
progress: p => Console.WriteLine($"CSV {p}%")
);
Important : ExportCsvAsyncFromResults does not internally validate that supplied smoothing arrays match initialData.Length. All arrays must be length-aligned; otherwise an index exception will occur during streaming.
3. Excel Export (Late Binding Mode)
var req = new ExcelScoreRequest
{
DatasetTitle = "Signal Run 42",
InitialData = data,
Radius = 5,
PolyOrder = 3,
BoundaryMode = BoundaryMode.Symmetric,
Flags = new SmoothingNotation
{
Rectangular = true,
BinomialAverage = true,
BinomialMedian = false,
Gaussian = true,
SavitzkyGolay = true
}
};
await ExcelScoreWriter.ExportAsync(
req,
new Progress<int>(p => Console.WriteLine($"Excel {p}%"))
);
Export Header / Label Differences
Aspect | CsvScoreWriter | ExcelScoreWriter | SmoothingConductor ExportCsv / ExportExcel |
---|---|---|---|
Boundary labels | Short (“Symmetric”, “Replicate”, “ZeroPad”, “Adaptive”) | Short | Extended (“Symmetric (Mirror)”, “Replicate (Nearest)”, “Zero Padding”, “Adaptive”) |
Derivative line | “Derivative Order : d” when SG & DerivOrder > 0 | Same (row after Polynomial Order) | Not emitted (always smoothing) |
Subject / Comments rows | Not written | Stored as document properties only | Written explicitly as worksheet rows (Subject, Comments) |
Progress Semantics
Operation | Completion Behavior |
---|---|
CsvScoreWriter.ExportAsync / ExportCsvAsync* | Resets to 0 after finishing |
SmoothingConductor.ExportExcelAsync | Ends at 100% (no reset) |
ExcelScoreWriter.ExportAsync | May reach 100% during data fill then resets to 0 after chart creation |
Best Practices
- Keep radius modest (
3 – 9
) for interactive scenarios; large radii escalate median cost. - Validate parameters before UI commit using
ValidateSmoothingParameters
. - Reuse precomputed results when exporting multiple times (CSV or Excel) to avoid repeated smoothing.
- Use
BoundaryMode.Symmetric
for most natural edge continuity unless edge clamping desired. - Consider disabling median for extremely large datasets if throughput is critical.
- Use
ScoreConformanceChecker.Validate
for concise parameter guards instead of calling the out‑param form directly.
Note :
ValidateSmoothingParameters
now enforces a non‑negative kernel radius (r ≥ 0
) in addition to existing rules. Callers no longer need to pre‑check for negative radius values before invoking the validator.
Thread Safety
- Static methods are stateless; safe for concurrent calls.
- Do not reuse output arrays between concurrent operations.
- Excel export methods are inherently single-threaded due to COM constraints.
Limitations & Known Inconsistencies
Item | Detail |
---|---|
Naming discrepancy | README earlier referenced SmoothingTuner ; current implementation exposes SmoothingConductor . Update code or aliases if backward compatibility needed. |
Excel #if NET48 signature |
Strong-typed branch references ExcelExportRequest (not provided here) while public late-binding branch uses ExcelScoreRequest . Harmonize names to reduce confusion. |
Weighted median performance | O(n * w log w) cost may dominate for large windows; consider optional alternative (e.g., running selection algorithms) if needed. |
Progress reset | Exports intentionally report 0 at completion mirroring legacy UI expectations. |
Localization | Export uses invariant numeric format; headers partially English (intentionally stable for machine parsing). |
Large matrices | Savitzky-Golay inversion may throw if matrix ill-conditioned for extreme parameter combinations. |
Excel boundary label variance | High-level ExcelScoreWriter uses abbreviated labels; core SmoothingConductor Excel export uses extended labels. |
License
MIT License. Include the full text in distribution (see root LICENSE if present).
Changelog
- Added Savitzky–Golay derivative support :
- New APIs : SmoothingConductor.ApplySGDerivative(...) and ComputeSavitzkyGolayCoefficients(windowSize, polyOrder, derivativeOrder, delta).
- New DTO fields : CsvScoreRequest.DerivOrder, ExcelScoreRequest.DerivOrder (0 = smoothing).
- CSV/Excel : if DerivOrder > 0, the SG column/series is the derivative; header shows "Derivative Order : d" (Δ = 1.0).
- Validation : SmoothingConductor.ValidateSmoothingParameters enforces r ≥ 0.
- CSV export : part-size computation includes the derivative header line only when applicable; progress semantics clarified.
- Excel export : derivative header line emitted; multi-area range construction optimized to reduce COM interop churn.
- Docs : Updated README, API_Documentation.xml, and SonataSmooth_API_Reference.md; standardized csharp code fences; fixed Windows path examples.
- Backward compatibility : no breaking changes; existing smoothing overloads and tuple order unchanged.
Disclaimer
This library focuses on clarity and predictable numeric stability over hyper-optimized micro-ops. Benchmark with your dataset before large-scale batch deployment.
Happy smoothing.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Office.Interop.Excel (>= 15.0.4795.1001)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
3.1.5 | 45 | 9/17/2025 |
- Applied symmetric trimming to Rect / Binom / Median / Gauss filters in Adaptive mode to eliminate edge phase bias, while adding NaN / Infinity handling and boundary safety checks to improve stability and accuracy.
- Added support for saving files in Excel format.
- Minor bugs fixed.