Rectangular부터 Savitzky-Golay까지 6가지 1D 스무딩 필터의 수학적 원리, α 블렌딩, 경계 처리, 그리고 인터랙티브 시뮬레이터를 코드·다이어그램과 함께 완전 정리합니다.
SonataSmooth.Tune은 1차원 수치 시퀀스에 대해 6가지 스무딩 필터를 단일 순회(single traversal)로 병렬 적용할 수 있는 .NET Standard 2.0 라이브러리입니다.
입력 배열의 비정상 값을 0.0으로 치환하여 모든 필터의 안정성을 보장합니다.
Binomial: CalcBinomialCoefficients(W) · Gaussian: ComputeGaussianCoefficients(W, σ) · SG: HouseholderQR
데이터 길이가 2,000 이상이면 행 단위 자동 병렬 처리를 활성화합니다.
단일 순회에서 활성화된 모든 필터의 결과를 동시에 계산합니다.
y[i] = α·filtered + (1−α)·original — Rect, SG 제외한 필터에 적용됩니다.
SonataSmooth는 1차원 데이터 스무딩 및 노이즈 제거에 특화되어 있습니다. 단일 차원 데이터셋에 한정되지만, 순차적 수치 신호의 전처리 또는 정제가 필요한 다양한 분야에 폭넓게 적용할 수 있습니다.
| 필터 | 유형 | 복잡도/점 | α 블렌딩 | 강점 |
|---|---|---|---|---|
| Rectangular | 선형 | O(W) | ✗ | 최소 계산 비용 |
| Binomial Avg | 선형 | O(W) | ✓ | 부드러운 가중, 효율적 |
| Binom. Median | 비선형 | O(W log W) | ✓ | 이상치 저항 |
| Gauss. Median | 비선형 | O(W log W) | ✓ | 가우시안 지역성 + 이상치 저항 |
| Gaussian | 선형 | O(W) | ✓ | 형태 보존, 고주파 노이즈 제거 |
| Savitzky-Golay | 선형 | O(W) | ✗ | 피크 높이 · 도함수 구조 보존 |
다양한 신호 패턴에 대해 6가지 필터가 어떤 성능을 보이는지 한눈에 비교합니다. 각 셀은 해당 조합의 처리 성능 등급을 나타냅니다.
| 신호 패턴 | Rect. | Binom. Avg | Binom. Med | Gauss. Med | Gaussian | S-G |
|---|---|---|---|---|---|---|
| 간헐적 랜덤 노이즈 | 적정 | 양호 | 우수 | ★ 탁월 | 양호 | 우수 |
| 빈번한 랜덤 노이즈 | 미흡 | 적정 | ★ 탁월 | 적정 | 적정 | 적정 |
| 완만한 대형 추세 변화 | 미흡 | 양호 | 양호 | 양호 | 양호 | ★ 탁월 |
| 간헐적 급격한 스파이크 | 미흡 | 적정 | ★ 탁월 | 우수 | 적정 | 적정 |
| 빈번한 / 연속 급격한 스파이크 | 미흡 | 적정 | 적정 | ★ 탁월 | 적정 | 적정 |
| 규칙적인 대진폭 파형 | 미흡 | 적정 | 적정 | 양호 | 적정 | ★ 탁월 |
| 계단 변화 (갑작스런 레벨 전환) | 미흡 | 적정 | ★ 탁월 | 우수 | 적정 | 적정 |
| 복합 주파수 진동 | 미흡 | 양호 | 적정 | 양호 | 양호 | ★ 탁월 |
| 주기적 고주파 노이즈 (일정 톤) | ★ 탁월 | 적정 | 적정 | 양호 | 양호 | 양호 |
| 느린 기저선 표류 + 미세 지터 | 양호 | 양호 | ★ 탁월 | 우수 | 양호 | 우수 |
| 부드러운 곡선 + 완만한 노이즈의 자연 신호 | 적정 | 양호 | 양호 | ★ 탁월 | ★ 탁월 | 우수 |
| 안정된 주기 신호 + 중간 강도 고주파 노이즈 | 적정 | ★ 탁월 | 적정 | 양호 | 양호 | 양호 |
단순하지만 일정한 고주파 노이즈 억제에 효과적입니다. 계산 비용이 가장 낮아 빠른 처리가 필요한 상황에 적합합니다.
균형 잡힌 중간 지대. 특히 중간 강도 노이즈가 포함된 주기 신호에서 강점을 발휘합니다.
다양한 데이터셋과 지표에서 가장 높은 종합 성능을 보여주는 필터. 간헐적 · 빈번한 스파이크, 빈번한 노이즈, 계단 변화 처리에 탁월하여 종합 최강자에 해당하지만, 연속 스파이크에서는 일관성이 다소 낮습니다.
가우시안의 부드러움과 중앙값의 강건함을 결합한 하이브리드 필터. 간헐적 스파이크와 부드러운 곡선 보존에 뛰어나며, 범용성이 높은 대안입니다.
부드러운 곡선과 자연 신호 흐름을 잘 재현하지만, 급격한 변화나 극단적 이상치에는 취약합니다.
파형, 추세, 복합 주파수 보존에 탁월. 과학 데이터 및 부드러운 곡선 분석에 이상적입니다.
종합 결론 : Binomial Median 필터링이 다양한 신호 유형과 평가 지표 전반에 걸쳐 가장 높은 종합 성능을 보여줍니다. Gaussian Median (GWMF)은 특히 간헐적 스파이크와 노이즈가 섞인 부드러운 곡선 시나리오에서 강력한 범용 대안이며, 나머지 필터들은 각자의 특정 상황에서 고유한 강점을 유지합니다.
| 매개변수 | 타입 | 범위 | 설명 |
|---|---|---|---|
r (radius) | int | ≥ 0 | 커널 반경. 윈도우 크기 W = 2r + 1 |
polyOrder | int | 0 ≤ p < W | SG 다항식 차수 |
boundaryMode | enum | 4종 | Symmetric · Replicate · ZeroPad · Adaptive |
alpha | double | [0, 1] | 블렌딩 계수. Rect, SG 제외 필터에 적용 |
sigmaFactor | double? | > 0 | σ = W / sigmaFactor. 기본 6.0 |
노이즈가 포함된 신호에 필터를 동시 적용한 결과를 미리 확인합니다.
가장 단순한 선형 평활화 필터. 윈도우 내 모든 샘플에 동일한 가중치를 부여하여 산술 평균을 계산합니다.
가중치 벡터:
부엽(side lobe)이 높아 Gibbs 현상(ringing)을 유발할 수 있습니다. 이것이 Binomial · Gaussian 등 테이퍼링 윈도우가 선호되는 이유입니다.
// SmoothingConductor.cs double invRectDiv = 1.0 / windowSize; // = 1/W double sum = 0.0; for (int k = -r; k <= r; k++) sum += Sample(i + k); rect[i] = sum * invRectDiv;
파스칼 삼각형의 행(이항 계수)을 가중치로 사용하는 가중 이동 평균입니다.
이항 계수를 가중치로 사용하여 가중 중앙값을 구합니다. 평균(Average)과 달리 극단값(이상치, spike)에 강건하고 신호의 엣지·피크 구조를 보존하는 비선형 필터입니다. Binomial Average와 동일한 가중치를 사용하되 출력 방법만 다릅니다.
가중치 벡터는 Binomial Average와 동일합니다:
일반 중앙값(unweighted median)은 모든 샘플에 동등한 가중치를 부여합니다. 가중 중앙값은 중앙에 가까운 샘플에 높은 투표권을 부여하여, 원본 신호(중앙 근처)의 영향력을 극단값보다 우선합니다.
Binomial Average와 Binomial Weighted Median은 동일한 가중치를 사용하되, 출력 계산 방식만 다릅니다. 이 한 가지 차이가 이상치(noise spike) 처리 능력을 근본적으로 바꿉니다.
예 : [100, 102, 99, 240, 101], w=[1,4,6,4,1]
= (100+408+594+960+101) / 16 = 135.2 ← 이상치에 끌림
정렬 : 99(w=6), 100(w=1), 101(w=1), 102(w=4), 240(w=4)
누적 : 6, 7, 8, 12, 16 → T/2=8, even → accum==8 at 101 → TieBreak (101+102)/2 = 101.5 ← 이상치 무시
인덱스 i를 중심으로 반경 r의 윈도우 [i−r, i+r]에서 W = 2r+1개의 샘플과 이항 가중치를 수집합니다. BoundaryMode에 따라 경계 밖 샘플 처리가 달라집니다.
(값, 가중치) 쌍을 값 기준으로 정렬합니다. 정렬 후 가중치 누적이 의미를 갖습니다. 1D에서는 배열이 작으므로(W ≤ 51) Array.Sort의 IntroSort가 효율적입니다.
accum > T/2
정렬된 순서대로 가중치를 누적하며 전체 합(T)의 절반을 초과(strictly greater)하는 첫 위치를 찾습니다. 이 값이 가중 중앙값입니다. 이항 계수는 정수값이므로 부동소수점 오차가 없습니다.
accum == T/2이면 두 값 평균
누적합이 정확히 T/2와 같으면(짝수 가중치 합), 현재 값과 다음 값의 산술 평균을 반환합니다. 이항 계수의 합 = 2^(W−1)이므로, W가 홀수(일반적)이면 합이 2의 거듭제곱 → 짝수 → TieBreak 가능성 있음.
y[i] = α · WMed + (1−α) · x[i] — α=1이면 완전 필터, α=0이면 원본 유지. 0 < α < 1에서 원본과 필터 결과의 혼합.
// SmoothingConductor.cs — Binomial Weighted Median 핵심 코드 double[] binom = CalcBinomialCoefficients(windowSize); // 1. 윈도우 내 (값, 가중치) 수집 var pairs = new List<(double val, double w)>(); for (int k = -r; k <= r; k++) { double v = Sample(i + k); // BoundaryMode 적용 pairs.Add((v, binom[k + r])); } // 2. 값 기준 정렬 pairs.Sort((a, b) => a.val.CompareTo(b.val)); // 3. 가중 누적합 탐색 double total = pairs.Sum(p => p.w); double half = total / 2.0; bool even = (total % 2) == 0; double accum = 0; for (int j = 0; j < pairs.Count; j++) { accum += pairs[j].w; if (accum > half) { // 4a. 초과 → 즉시 반환 med = pairs[j].val; break; } if (even && accum == half) { // 4b. TieBreak → 두 값 평균 med = (pairs[j].val + pairs[j+1].val) / 2.0; break; } } // 5. α 블렌딩 result[i] = alpha * med + (1 - alpha) * input[i];
이항 계수의 합 T = 2^(W−1)은 항상 짝수(W ≥ 2)입니다. 따라서 가중 누적합이 정확히 T/2에 도달할 수 있으며, 이 경우 두 인접 값의 평균을 반환합니다.
| r | W | 이항 계수 | 합 T | T/2 | TieBreak 가능 |
|---|---|---|---|---|---|
| 1 | 3 | [1, 2, 1] | 4 | 2 | ✓ 예: accum = 1+1 = 2 = T/2 |
| 2 | 5 | [1, 4, 6, 4, 1] | 16 | 8 | ✓ 예: accum = 1+4+... = 8 |
| 3 | 7 | [1, 6, 15, 20, 15, 6, 1] | 64 | 32 | ✓ |
accum >= half(이상)을 사용하고 별도 짝수 처리가 없습니다.
가중 중앙값이 이상치(spike)에 강건한 이유를 수학적으로 분석합니다.
중앙 가중치가 전체의 50% 미만이면, 중앙에 이상치가 있어도 주변 정상 샘플들이 과반을 차지하여 이상치를 "outvote"합니다.
| r | 중앙 가중치 | 중앙 비율 | Breakdown Point | 의미 |
|---|---|---|---|---|
| 1 | 2 / 4 | 50.0% | 50.0% | 경계 — 중앙 1개만 오염되면 유효 |
| 2 | 6 / 16 | 37.5% | 62.5% | 중앙+인접 2개 오염까지 유효 |
| 3 | 20 / 64 | 31.3% | 68.8% | 높은 이상치 내성 |
| 5 | 252 / 1024 | 24.6% | 75.4% | 매우 높은 이상치 내성 |
Adaptive 모드에서는 경계에서 윈도우가 축소되며, 축소된 크기에 맞는 새로운 이항 계수가 생성됩니다.
// Adaptive 분기 int left = Math.Min(r, i); int right = Math.Min(r, n - 1 - i); int W_local = left + right + 1; // 축소된 윈도우용 새 이항 계수 double[] localBinom = CalcBinomialCoefficients(W_local); // 예: i=0, r=2 → left=0, right=2, W=3 → [1,2,1] // 원본 r=2: [1,4,6,4,1] 의 부분이 아닌 완전히 새로운 계수! var vals = new double[W_local]; for (int p = 0; p < W_local; p++) vals[p] = input[i - left + p]; filtered = WeightedMedianBinom(vals, localBinom);
Spike 옵션을 변경하여 이상치에 대한 필터의 강건성을 확인하세요. α를 조절하여 원본과의 블렌딩 효과를 관찰합니다.
Binomial Median과 동일한 가중 중앙값 알고리즘에 가우시안 가중치를 사용합니다. sigmaFactor로 σ를 정밀 조절하여 커널의 감쇠 강도를 제어할 수 있습니다.
정규화 후 합=1이 됩니다. sigmaFactor가 클수록 σ가 작아져 중앙에 집중하고, 작을수록 σ가 커져 넓게 분산됩니다.
// Binomial Median과의 유일한 차이: 가중치 생성 함수 double[] weights = useGaussianWeights ? ComputeGaussianCoefficients(windowSize, windowSize / sigmaFactor) : CalcBinomialCoefficients(windowSize); // 이후 정렬 + 누적 탐색 로직은 완전히 동일 // 단, 임계값 비교 연산자만 다름: // Binomial : accum > half (strictly greater) // Gaussian : accum >= half (greater or equal)
> vs >=Binomial의 가중치는 정수값이므로 누적합이 정확히 T/2와 일치할 수 있어, accum > half(초과)와 accum == half(TieBreak)를 분리합니다.
Gaussian의 가중치는 실수값(exp 결과)이므로 정확한 T/2 일치가 사실상 불가능합니다. 따라서 accum >= half(이상)만 사용하고 별도 짝수 처리(TieBreak)가 없습니다.
if (accum > half) → 반환 if (even && accum == half) → 평균
if (accum >= half) → 반환 // TieBreak 없음
sigmaFactor(σF)는 가우시안 커널의 유효 범위를 결정합니다. 동일한 r에서 σF를 바꾸면 가중치 분포 형태가 크게 달라집니다.
| σF | σ (r=3) | 중앙 가중치 | 가장자리 가중치 | 특성 |
|---|---|---|---|---|
| 3 (넓음) | 2.33 | ~0.20 | ~0.09 | 모든 샘플 비슷한 비중 → 단순 중앙값에 가까움 |
| 6 (기본) | 1.17 | ~0.34 | ~0.013 | 중앙 집중 + 먼 샘플 무시 → 균형 |
| 12 (좁음) | 0.58 | ~0.68 | ~10⁻⁶ | 중앙 거의 단독 → 원본에 가까움 |
Adaptive 모드에서는 축소된 윈도우에 맞게 σ도 비례 축소됩니다. Binomial의 Dictionary 캐싱과 달리 매번 exp() 계산이 필요합니다.
// Gaussian Median — Adaptive 분기 int left = Math.Max(0, i - r); int right = Math.Min(n - 1, i + r); int W_local = right - left + 1; // σ를 축소된 윈도우에 비례하여 재계산 double sigmaLocal = W_local / sigmaFactor; double[] gLocal = ComputeGaussianCoefficients(W_local, sigmaLocal); // ↑ 매번 exp() O(W_local) 호출 — Binomial의 캐싱 대비 느림
σ Factor를 조절하여 가우시안 폭이 중앙값 결과에 미치는 영향을 관찰하세요.
두 필터는 동일한 Weighted Median 알고리즘을 공유하되, 가중치 생성 방식이 다릅니다. 이 한 가지 차이가 결과물과 사용 시나리오에서 구체적으로 어떤 차이를 만드는지 깊이 분석합니다.
동일한 r에서 두 필터의 1D 가중치를 시각적으로 비교합니다.
| 항목 | Binomial Weighted Median | Gaussian Weighted Median |
|---|---|---|
| 가중치 생성 | C(W−1,k) 점화식 O(W) — 정수값 double | exp(−x²/2σ²) O(W) — 실수값 근사 |
| σ 파라미터 | 없음 — r에 의해 분포 자동 결정 | σ = W / sigmaFactor — σF로 분포 형태 조절 |
| 임계값 비교 | accum > half (strictly greater) | accum >= half (greater or equal) |
| TieBreak (짝수 처리) | accum == half → 두 값 평균 | 해당 없음 (실수 가중치, 정확한 일치 불가) |
| 캐싱 | CalcBinomialCoefficients 재사용 가능 | ComputeGaussianCoefficients 매번 계산 |
| Adaptive 경계 | CalcBinomialCoefficients(W_local) 로컬 생성 | ComputeGaussianCoefficients(W_local, σ_local) 재계산 |
| α 블렌딩 | ✓ | ✓ |
| 수치 정밀도 | 정수값 double — 누적 오차 없음 | exp() 근사 — 미세 누적 오차 가능 |
Weighted Median이 이상치를 제거하려면 중앙 가중치가 50% 미만이어야 합니다. 50% 이상이면 중앙 샘플 하나가 과반을 차지하여 이상치가 그대로 통과됩니다.
| r | W | Binomial 중앙 % | 노이즈 제거 | Gaussian 중앙 % (σF=6) | 노이즈 제거 |
|---|---|---|---|---|---|
| 1 | 3 | 50.0% | ✓ 경계 | 78.7% | ✗ 필터 무효화 |
| 2 | 5 | 37.5% | ✓ | 47.9% | ✓ |
| 3 | 7 | 31.3% | ✓ | 34.3% | ✓ |
| 5 | 11 | 24.6% | ✓ | 21.8% | ✓ |
| 10 | 21 | 17.6% | ✓ | 11.4% | ✓ |
σ를 일치시킨 조건에서도 Binomial WM이 미세하게 우위인 수학적 근거가 4가지 있습니다.
Binomial B(2r, 0.5)의 첨도 κ = 3 − 1/r은 Gaussian의 κ=3보다 항상 작습니다 (Platykurtic). 이는 가중치가 더 고르게 분산됨을 의미하여 유효 샘플 수(n_eff)가 높아지고 추정 분산이 감소합니다.
이항 계수는 정수값 double(1.0, 4.0, 6.0 등)로 IEEE 754에서 정확히 표현됩니다. 가중치 누적 연산에서 오차가 없습니다. Gaussian의 exp() 결과는 무리수 근사이므로 미세한 누적 오차가 발생합니다.
Binomial 분포의 정의역 = [0, W−1]로 윈도우와 정확히 일치합니다. Gaussian은 이론적으로 무한 꼬리를 가지며 윈도우 경계에서 강제 절단(truncation) 후 재정규화합니다. 이 재정규화는 원래 분포 형태를 미세하게 변형시킵니다.
σ를 일치시켜도 Platykurtic인 Binomial은 중앙 가중치가 항상 Gaussian보다 낮습니다. 이는 이상치가 중앙에 위치할 때 주변 샘플들이 더 쉽게 "outvote"할 수 있음을 의미합니다.
| 상황 | Binomial Median 추천 | Gaussian Median 추천 |
|---|---|---|
| 소형 커널 r=1 (기본 σF=6) | ✓ 명백히 우위 | ✗ 필터 무효화 — σF 재조율 필수 |
| 소형 커널 r=2 | ✓ 미세 우위 (중앙 37.5%) | △ 정상 동작 (중앙 47.9%) |
| Salt-Pepper 이상치 제거 | ✓ 모든 r에서 안정 | r≥2부터 정상 동작 |
| 배치 처리 (동일 r 반복) | ✓ 캐시 재사용 효과 | 매번 exp() 재계산 |
| 신호 특성에 맞는 정밀 튜닝 | r만 조절 — 유연성 낮음 | ✓ σF로 세밀 조율 |
| 파라미터 없이 빠른 적용 | ✓ r만 설정, 즉시 안전 | σF 조율 필요 |
| 결론 | Binomial은 파라미터 없이 안전하고 빠른 기본 선택. Gaussian은 σF 튜닝으로 정밀 제어가 필요한 전문가 용도. | |
반경을 변경하며 두 필터의 결과 차이를 직접 확인하세요. 이상치(spike) 포함 신호에서 차이가 뚜렷해집니다.
이산 가우시안 커널과의 컨볼루션을 통한 선형 평활화 필터입니다. 중앙 샘플에 가장 높은 가중치를 부여하며, σ(시그마)로 감쇠 속도를 제어합니다. Rectangular보다 부드러운 주파수 응답을 가집니다.
정규화 후 Σĝ = 1이므로 DC 성분(상수 신호)이 완벽히 보존됩니다. Binomial과 동일한 성질이지만, σ 파라미터로 분포 폭을 자유롭게 조절할 수 있습니다.
가우시안의 푸리에 변환은 다시 가우시안입니다 (자기 유사성). 부엽(side lobe)이 없는 이상적인 저역 통과 필터에 가까우며, Rectangular의 sinc 응답과 대비됩니다.
부엽이 높아 Gibbs 현상(ringing) 유발. 급격한 전이(step)에서 링잉 아티팩트 발생.
부엽 없음. 부드러운 전이. σ가 클수록 더 강한 저역 통과. 이상적인 LPF에 가장 근접.
sigmaFactor(σF)는 σ = W / σF로 정의됩니다. 동일한 r에서 σF에 따라 커널 형태가 크게 달라집니다.
| σF | σ (r=5) | 중앙 가중치 | 가장자리 가중치 | 특성 |
|---|---|---|---|---|
| 3 (넓음) | 3.67 | ~0.13 | ~0.05 | 거의 균일 → Rectangular에 수렴 |
| 6 (기본) | 1.83 | ~0.22 | ~0.005 | 표준 Gaussian 스무딩 — 균형적 감쇠 |
| 12 (좁음) | 0.92 | ~0.44 | ~10⁻⁷ | 중앙 극도 집중 → 원본에 가까움 |
// SmoothingConductor.cs — Gaussian Convolution double sigma = windowSize / sigmaFactor; double[] gCoeffs = ComputeGaussianCoefficients(windowSize, sigma); // ↑ 이미 정규화됨 (합 = 1) // 내부 루프 : 가중 합산 double sum = 0; for (int k = -r; k <= r; k++) sum += gCoeffs[k + r] * Sample(i + k); // α 블렌딩 적용 result[i] = alpha * sum + (1 - alpha) * input[i]; // Adaptive 모드 : 축소 윈도우에 맞게 σ 재계산 if (boundary == Adaptive) { double sigmaLocal = W_local / sigmaFactor; var gLocal = ComputeGaussianCoefficients(W_local, sigmaLocal); }
σ Factor를 조절하여 커널 폭이 결과에 미치는 영향을 확인하세요.
윈도우 내 데이터에 m차 다항식을 최소제곱법으로 피팅하고, 피팅된 다항식의 중앙값을 출력합니다. 피크 높이·도함수 구조·신호 형태를 보존하는 유일한 필터입니다.
각 행은 윈도우 내 위치, 각 열은 다항식 차수에 해당합니다. 예를 들어 r=2, m=2이면:
QR 분해로 유사역행렬(pseudo-inverse)의 0번째 행을 추출합니다. 이 행이 컨볼루션 계수 h입니다. 정규화 후 합=1이 됩니다.
SG 계수에는 음수가 나타납니다. 이는 수학적 필연이며, 엣지 보존의 핵심 메커니즘입니다.
양 끝의 음수 계수는 신호의 2차 도함수(곡률) 정보를 포함합니다. 이 구조가 피크 높이를 보존하면서도 노이즈를 제거할 수 있게 합니다. 다른 모든 필터(Rectangular, Binomial, Gaussian)는 양수 계수만 가지므로 피크를 반드시 감쇠시킵니다.
| polyOrder (m) | 피팅 다항식 | 보존 특성 | 스무딩 강도 |
|---|---|---|---|
| 0 | 상수 (y = a₀) | 평균값만 | 최대 — Rectangular과 동일 |
| 1 | 직선 (y = a₀ + a₁x) | 추세(기울기) | 강함 |
| 2 (기본) | 포물선 (y = a₀+a₁x+a₂x²) | 피크 높이 + 곡률 | 보통 — 가장 범용적 |
| 3 | 3차 다항식 | 변곡점 | 약함 |
| 4+ | 고차 다항식 | 세밀한 구조 | 매우 약함 — 과적합 위험 |
경계에서는 비대칭 윈도우에 맞는 새로운 설계 행렬 A'를 구성하고 QR 분해를 다시 수행합니다. 이로써 경계에서도 다항식 피팅의 정확성이 보장됩니다.
// Adaptive SG — 비대칭 계수 생성 var sides = GetAdaptiveSides(i, r, n); var coeffs = ComputeSGAsymmetric(sides.left, sides.right, polyOrder); // ↑ 매번 QR 분해 → O(W · m²) — 가장 비용이 높은 경계 처리 double sum = 0; for (int k = -sides.left; k <= sides.right; k++) sum += coeffs[k + sides.left] * input[i + k]; result[i] = sum; // α 블렌딩 미적용 — 다항 피팅 특성 보존 우선
Poly Order를 변경하여 스무딩 강도와 피크 보존의 trade-off를 확인하세요.
커널이 데이터 경계를 넘어설 때 존재하지 않는 샘플을 어떻게 처리하는지 결정합니다. 4가지 모드가 모든 6개 필터에 공통 적용됩니다.
| 모드 | 경계 시각화 (data = [1,2,3,4,5]) | 특성 | 적합한 상황 |
|---|---|---|---|
| Symmetric | … 3 2 1 | 1 2 3 4 5 | 5 4 3 … | 1차 도함수 연속 | 일반적인 신호 처리 (DSP 표준) |
| Replicate | … 1 1 1 | 1 2 3 4 5 | 5 5 5 … | 경계 평탄화 | 에지 값을 유지해야 할 때 |
| ZeroPad | … 0 0 0 | 1 2 3 4 5 | 0 0 0 … | 경계 에너지 감쇠 | 데이터 외부 = 0인 시나리오 |
| Adaptive | [1 2 3] → [2 3 4] → [3 4 5] → … | 합성 샘플 없음 | 실제 데이터만 사용해야 할 때 |
// GetValueWithBoundary() — Symmetric / Replicate / ZeroPad 경계 처리 // Symmetric: 경계에서 반사 if (idx < 0) idx = -idx - 1; // -1 → 0, -2 → 1 if (idx >= n) idx = 2*n - idx - 1; // n → n-1, n+1 → n-2 // Replicate: 경계값 복제 if (idx < 0) idx = 0; if (idx >= n) idx = n - 1; // ZeroPad: 경계 밖 = 0 if (idx < 0 || idx >= n) return 0.0; // GetAdaptiveSides() — SG 전용 윈도우 크기 보존 보상 // (Rect, Binomial, Gaussian은 자체 인라인 Math.Min 축소 사용) var (left, right) = GetAdaptiveSides(i, r, n); // left = min(r, i) // right = W - 1 - left (maxRight 보상 적용)
왼쪽으로 가용한 샘플 수 계산. 인덱스 i가 r보다 작으면 왼쪽이 축소됩니다.
보상 메커니즘: 왼쪽이 줄어든 만큼 오른쪽이 늘어나 총 윈도우 크기 W를 유지합니다.
right > (n−1−i)이면 extra = right − maxRight를 계산하고, right = maxRight, left = min(i, left + extra)로 초과분을 왼쪽으로 재분배합니다. 이 보상으로 W가 가능한 한 유지됩니다.
left = min(left, i), right = min(right, n−1−i)로 최종 안전 제한을 적용합니다.
GetAdaptiveSides()를 사용하여 윈도우 크기 W를 보존(보상 재분배)합니다. 다항식 피팅에 최소 W개의 데이터 포인트가 필요하기 때문입니다.Math.Min(r, i) / Math.Min(r, n−1−i)로 양쪽을 독립 축소합니다. W_local = left + right + 1이 원래 W보다 작아질 수 있으며, 보상 재분배 없이 축소된 크기에 맞는 새 계수를 생성합니다.Math.Max(0, i−r) / Math.Min(n−1, i+r)로 절대 인덱스 범위를 직접 제한합니다.
반경을 늘려 경계 처리의 영향이 커지는 것을 확인하세요.
중심 인덱스(i)와 반경(r)을 변경하며, 각 경계 모드가 범위 밖 인덱스를 어떤 값으로 합성하는지 셀 단위로 비교합니다. 색상 셀 = 합성(가상) 샘플. 하단의 전체 인덱스 개요에서 Rectangular 필터 결과도 확인하세요.
SmoothingConductor.ApplySmoothing과 동일한 JavaScript 구현으로 필터링 결과를 확인합니다.
데이터 길이: 0개
SonataSmooth 메인 애플리케이션 소스, .NET Standard 2.0 기반 스무딩 라이브러리 NuGet 패키지, 그리고 라이브러리 기능을 직접 실험해볼 수 있는 실습용 Etude 애플리케이션을 아래 링크에서 확인하실 수 있습니다.
SonataSmooth의 메인 소스 코드 저장소입니다. C# .NET Windows Forms 기반으로 제작된 수치 데이터 노이즈 제거 및 평활화 애플리케이션으로, 수동 입력, 클립보드 붙여넣기, 드래그 앤 드롭 등 다양한 입력 방식과 강력한 유효성 검사를 지원합니다.
SonataSmooth은 "Sonata"와 "Smooth"의 합성어입니다. 소나타(Sonata)는 서로 다른 악장(악장 = 알고리즘)이 하나의 조화로운 전체로 어우러지는 음악 형식으로, 여러 스뭔딩 알고리즘이 협주(concert)하여 함께 작동한다는 철학을 담고 있습니다.
대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.
.NET Standard 2.0을 대상으로 하는 고성능 1D 수치 신호 평활화 & 내보내기 툴킷 NuGet 패키지입니다. Rectangular (Moving Average), Binomial (Pascal), Weighted Median (Binomial Weights), Gaussian Weighted Median (GWMF), Gaussian, Savitzky-Golay 스무딩을 경계 처리 옵션과 병렬화 설정과 함께 제공하며, CSV 및 Excel (COM) 내보내기 헬퍼로 여러 스무딩 결과를 나란히 비교 · 차트화할 수 있습니다.
대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.
using SonataSmooth.Tune; double[] data = LoadYourData(); var (rect, binom, median, gaussMed, gauss, sg) = SmoothingConductor.ApplySmoothing( data, r: 5, polyOrder: 2, boundaryMode: BoundaryMode.Symmetric, doRect: true, doAvg: true, doMed: false, doGaussMed: false, doGauss: true, doSG: true, alpha: 1.0, sigmaFactor: 6.0);
SonataSmooth.Tune 라이브러리의 기능을 직접 체험하고 학습할 수 있는 실습용 동반 애플리케이션입니다. 음악에서 에튀드(Étude)가 최종 작품을 위한 준비 연습곡이듯, 이 저장소는 본격적인 데이터 처리 애플리케이션을 구현하기 전에 SonataSmooth.Tune의 다양한 스무딩 알고리즘을 실험하고 이해하기 위한 스케치이자 학습 공간입니다.
SonataSmooth.Tune은 데이터를 악기 조율하듯 정밀하게 다듬는 C# / .NET 스뭔딩 라이브러리이며, SonataSmooth.Tune.Etude는 그 라이브러리를 위한 연습곡(Étude) - 완성된 작품에 앞서 기법을 탐구하고 숙달하는 실습 공간입니다.
대부분의 컴포넌트는 MIT 라이선스 적용. 단, Pascal's Triangle 계수 기반 Binomial Weighted Median 필터는 특허 출원 중(patent-pending)으로, 비상업적 연구 · 교육 · 개인 프로젝트에는 무료로 사용 가능하나 상업적 사용 · 재배포 · 제품 통합은 특허 보유자의 사전 서면 동의가 필요합니다.