SonataSmooth.Tune
3.3.0
See the version list below for details.
dotnet add package SonataSmooth.Tune --version 3.3.0
NuGet\Install-Package SonataSmooth.Tune -Version 3.3.0
<PackageReference Include="SonataSmooth.Tune" Version="3.3.0" />
<PackageVersion Include="SonataSmooth.Tune" Version="3.3.0" />
<PackageReference Include="SonataSmooth.Tune" />
paket add SonataSmooth.Tune --version 3.3.0
#r "nuget: SonataSmooth.Tune, 3.3.0"
#:package SonataSmooth.Tune@3.3.0
#addin nuget:?package=SonataSmooth.Tune&version=3.3.0
#tool nuget:?package=SonataSmooth.Tune&version=3.3.0
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)
- Changelog
- Disclaimer
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.5.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.
- No changes to API behavior. Documentation formatting improved for clarity.
- Minor bugs fixed.