Skip to main content
. 2026 Sep 19;26(18):5931. doi: 10.3390/s26185931
Algorithm A1 Synthetic anomaly injection
Require: Test values X∈RN×F; train+val values Xtv and alive mask Mtv; alive mask M; period Tp; frequency freq; severity sev; correlation threshold γ; max partners pmax; cooldown parameter C
Ensure: Perturbed series X˜, window-level labels y
1: X˜←X; O← False                          ▹occupancy mask
2: nf←Q99(Xtv[Mtv=1])−Q1(Xtv[Mtv=1]) for each feature f  ▹ global per-feature scale, train+val only
3: R← pairwise absolute correlation matrix of X over non-constant features
4: P← features with strong lag-Tp autocorrelation; for each f∈P, locate local peaks/troughs (donor candidates)
5: k←⌊freq·N/3⌋; set target counts {kcoll,kctx,kpt} per type
6: Lc←12 (collective length), Lx←3 (contextual length)
7: function Partners(f)
8:      return up to pmax features g with Rf,g≥γ, ranked by correlation
9: end function
10: function TryCollective
11:      Sample start s, feature f; let e←s+Lc
12:      if region [s,e] free and f alive then
13:            Cycle mode ∈{shift,varianceburst,frozen} (round-robin, no repeats until all used)
14:            Perturb X˜[s:e,f] by magnitude sev·nf per mode; repeat on each feature in Partners(f) using its own ng
15:            y[s:e]←1; mark [s−C,e+C] occupied; return success
16:      end if
17: end function
18: function TryContextual
19:      Draw next unused (feature f∈P, extremum c) pair; let [s,e]←[c−1,c+2]
20:      if region free and a same-feature donor extremum d of opposite phase exists with |d−c|≥2Lx and correlation(X˜[s:e,f],X[d−1:d+2,f])≤0.85 then
21:            Replace X˜[s:e,f] with donor window X[d−1:d+2,f]; repeat for each partner in Partners(f) using its matching-phase donor
22:            y[s:e]←1; mark [s−C,e+C] occupied; return success
23:      end if
24: end function
25: function TryPoint
26:      Sample timestamp t, feature f
27:      if M[t,f]=1 and t free then
28:            Cycle mode ∈{spike,drop} (round-robin); set X˜[t,f]←X˜[t−1,f]±sev·nf; repeat on each partner in Partners(f)
29:            y[t]←1; mark [t−C,t+C] occupied; return success
30:      end if
31: end function
32: Round-robin scheduling: while any active type is below its target count and below a failure-streak budget, cycle through {collective, contextual, point} in turn, attempting one placement per active type per pass; deactivate a type once its target count is reached or its failure streak is exceeded
33: Assign each raw anomalous timestep as the positive label of its corresponding window; under this convention, window-level and point-level labels coincide one-to-one
34: return X˜,y