dspx 0.1.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.github/workflows/ci.yml +185 -0
  2. package/.vscode/c_cpp_properties.json +17 -0
  3. package/.vscode/settings.json +68 -0
  4. package/.vscode/tasks.json +28 -0
  5. package/DISCLAIMER.md +32 -0
  6. package/LICENSE +21 -0
  7. package/README.md +1803 -0
  8. package/ROADMAP.md +192 -0
  9. package/TECHNICAL_DEBT.md +165 -0
  10. package/binding.gyp +65 -0
  11. package/docs/ADVANCED_LOGGER_FEATURES.md +598 -0
  12. package/docs/AUTHENTICATION_SECURITY.md +396 -0
  13. package/docs/BACKEND_IMPROVEMENTS.md +399 -0
  14. package/docs/CHEBYSHEV_BIQUAD_EQ_IMPLEMENTATION.md +405 -0
  15. package/docs/FFT_IMPLEMENTATION.md +490 -0
  16. package/docs/FFT_IMPROVEMENTS_SUMMARY.md +387 -0
  17. package/docs/FFT_USER_GUIDE.md +494 -0
  18. package/docs/FILTERS_IMPLEMENTATION.md +260 -0
  19. package/docs/FILTER_API_GUIDE.md +418 -0
  20. package/docs/FIR_SIMD_OPTIMIZATION.md +175 -0
  21. package/docs/LOGGER_API_REFERENCE.md +350 -0
  22. package/docs/NOTCH_FILTER_QUICK_REF.md +121 -0
  23. package/docs/PHASE2_TESTS_AND_NOTCH_FILTER.md +341 -0
  24. package/docs/PHASES_5_7_SUMMARY.md +403 -0
  25. package/docs/PIPELINE_FILTER_INTEGRATION.md +446 -0
  26. package/docs/SIMD_OPTIMIZATIONS.md +211 -0
  27. package/docs/TEST_MIGRATION_SUMMARY.md +173 -0
  28. package/docs/TIMESERIES_IMPLEMENTATION_SUMMARY.md +322 -0
  29. package/docs/TIMESERIES_QUICK_REF.md +85 -0
  30. package/docs/advanced.md +559 -0
  31. package/docs/time-series-guide.md +617 -0
  32. package/docs/time-series-migration.md +376 -0
  33. package/jest.config.js +37 -0
  34. package/package.json +42 -0
  35. package/prebuilds/linux-x64/dsp-ts-redis.node +0 -0
  36. package/prebuilds/win32-x64/dsp-ts-redis.node +0 -0
  37. package/scripts/test.js +24 -0
  38. package/src/build/dsp-ts-redis.node +0 -0
  39. package/src/native/DspPipeline.cc +675 -0
  40. package/src/native/DspPipeline.h +44 -0
  41. package/src/native/FftBindings.cc +817 -0
  42. package/src/native/FilterBindings.cc +1001 -0
  43. package/src/native/IDspStage.h +53 -0
  44. package/src/native/adapters/InterpolatorStage.h +201 -0
  45. package/src/native/adapters/MeanAbsoluteValueStage.h +289 -0
  46. package/src/native/adapters/MovingAverageStage.h +306 -0
  47. package/src/native/adapters/RectifyStage.h +88 -0
  48. package/src/native/adapters/ResamplerStage.h +238 -0
  49. package/src/native/adapters/RmsStage.h +299 -0
  50. package/src/native/adapters/SscStage.h +121 -0
  51. package/src/native/adapters/VarianceStage.h +307 -0
  52. package/src/native/adapters/WampStage.h +114 -0
  53. package/src/native/adapters/WaveformLengthStage.h +115 -0
  54. package/src/native/adapters/ZScoreNormalizeStage.h +326 -0
  55. package/src/native/core/FftEngine.cc +441 -0
  56. package/src/native/core/FftEngine.h +224 -0
  57. package/src/native/core/FirFilter.cc +324 -0
  58. package/src/native/core/FirFilter.h +149 -0
  59. package/src/native/core/IirFilter.cc +576 -0
  60. package/src/native/core/IirFilter.h +210 -0
  61. package/src/native/core/MovingAbsoluteValueFilter.cc +17 -0
  62. package/src/native/core/MovingAbsoluteValueFilter.h +135 -0
  63. package/src/native/core/MovingAverageFilter.cc +18 -0
  64. package/src/native/core/MovingAverageFilter.h +135 -0
  65. package/src/native/core/MovingFftFilter.cc +291 -0
  66. package/src/native/core/MovingFftFilter.h +203 -0
  67. package/src/native/core/MovingVarianceFilter.cc +194 -0
  68. package/src/native/core/MovingVarianceFilter.h +114 -0
  69. package/src/native/core/MovingZScoreFilter.cc +215 -0
  70. package/src/native/core/MovingZScoreFilter.h +113 -0
  71. package/src/native/core/Policies.h +352 -0
  72. package/src/native/core/RmsFilter.cc +18 -0
  73. package/src/native/core/RmsFilter.h +131 -0
  74. package/src/native/core/SscFilter.cc +16 -0
  75. package/src/native/core/SscFilter.h +137 -0
  76. package/src/native/core/WampFilter.cc +16 -0
  77. package/src/native/core/WampFilter.h +101 -0
  78. package/src/native/core/WaveformLengthFilter.cc +17 -0
  79. package/src/native/core/WaveformLengthFilter.h +98 -0
  80. package/src/native/utils/CircularBufferArray.cc +336 -0
  81. package/src/native/utils/CircularBufferArray.h +62 -0
  82. package/src/native/utils/CircularBufferVector.cc +145 -0
  83. package/src/native/utils/CircularBufferVector.h +45 -0
  84. package/src/native/utils/NapiUtils.cc +53 -0
  85. package/src/native/utils/NapiUtils.h +21 -0
  86. package/src/native/utils/SimdOps.h +870 -0
  87. package/src/native/utils/SlidingWindowFilter.cc +239 -0
  88. package/src/native/utils/SlidingWindowFilter.h +159 -0
  89. package/src/native/utils/TimeSeriesBuffer.cc +205 -0
  90. package/src/native/utils/TimeSeriesBuffer.h +140 -0
  91. package/src/ts/CircularLogBuffer.ts +87 -0
  92. package/src/ts/DriftDetector.ts +331 -0
  93. package/src/ts/TopicRouter.ts +428 -0
  94. package/src/ts/__tests__/AdvancedDsp.test.ts +585 -0
  95. package/src/ts/__tests__/AuthAndEdgeCases.test.ts +241 -0
  96. package/src/ts/__tests__/Chaining.test.ts +387 -0
  97. package/src/ts/__tests__/ChebyshevBiquad.test.ts +229 -0
  98. package/src/ts/__tests__/CircularLogBuffer.test.ts +158 -0
  99. package/src/ts/__tests__/DriftDetector.test.ts +389 -0
  100. package/src/ts/__tests__/Fft.test.ts +484 -0
  101. package/src/ts/__tests__/ListState.test.ts +153 -0
  102. package/src/ts/__tests__/Logger.test.ts +208 -0
  103. package/src/ts/__tests__/LoggerAdvanced.test.ts +319 -0
  104. package/src/ts/__tests__/LoggerMinor.test.ts +247 -0
  105. package/src/ts/__tests__/MeanAbsoluteValue.test.ts +398 -0
  106. package/src/ts/__tests__/MovingAverage.test.ts +322 -0
  107. package/src/ts/__tests__/RMS.test.ts +315 -0
  108. package/src/ts/__tests__/Rectify.test.ts +272 -0
  109. package/src/ts/__tests__/Redis.test.ts +456 -0
  110. package/src/ts/__tests__/SlopeSignChange.test.ts +166 -0
  111. package/src/ts/__tests__/Tap.test.ts +164 -0
  112. package/src/ts/__tests__/TimeBasedExpiration.test.ts +124 -0
  113. package/src/ts/__tests__/TimeBasedRmsAndMav.test.ts +231 -0
  114. package/src/ts/__tests__/TimeBasedVarianceAndZScore.test.ts +284 -0
  115. package/src/ts/__tests__/TimeSeries.test.ts +254 -0
  116. package/src/ts/__tests__/TopicRouter.test.ts +332 -0
  117. package/src/ts/__tests__/TopicRouterAdvanced.test.ts +483 -0
  118. package/src/ts/__tests__/TopicRouterPriority.test.ts +487 -0
  119. package/src/ts/__tests__/Variance.test.ts +509 -0
  120. package/src/ts/__tests__/WaveformLength.test.ts +147 -0
  121. package/src/ts/__tests__/WillisonAmplitude.test.ts +197 -0
  122. package/src/ts/__tests__/ZScoreNormalize.test.ts +459 -0
  123. package/src/ts/advanced-dsp.ts +566 -0
  124. package/src/ts/backends.ts +1137 -0
  125. package/src/ts/bindings.ts +1225 -0
  126. package/src/ts/easter-egg.ts +42 -0
  127. package/src/ts/examples/MeanAbsoluteValue/test-state.ts +99 -0
  128. package/src/ts/examples/MeanAbsoluteValue/test-streaming.ts +269 -0
  129. package/src/ts/examples/MovingAverage/test-state.ts +85 -0
  130. package/src/ts/examples/MovingAverage/test-streaming.ts +188 -0
  131. package/src/ts/examples/RMS/test-state.ts +97 -0
  132. package/src/ts/examples/RMS/test-streaming.ts +253 -0
  133. package/src/ts/examples/Rectify/test-state.ts +107 -0
  134. package/src/ts/examples/Rectify/test-streaming.ts +242 -0
  135. package/src/ts/examples/Variance/test-state.ts +195 -0
  136. package/src/ts/examples/Variance/test-streaming.ts +260 -0
  137. package/src/ts/examples/ZScoreNormalize/test-state.ts +277 -0
  138. package/src/ts/examples/ZScoreNormalize/test-streaming.ts +306 -0
  139. package/src/ts/examples/advanced-dsp-examples.ts +397 -0
  140. package/src/ts/examples/callbacks/advanced-router-features.ts +326 -0
  141. package/src/ts/examples/callbacks/benchmark-circular-buffer.ts +109 -0
  142. package/src/ts/examples/callbacks/monitoring-example.ts +265 -0
  143. package/src/ts/examples/callbacks/pipeline-callbacks-example.ts +137 -0
  144. package/src/ts/examples/callbacks/pooled-callbacks-example.ts +274 -0
  145. package/src/ts/examples/callbacks/priority-routing-example.ts +277 -0
  146. package/src/ts/examples/callbacks/production-topic-router.ts +214 -0
  147. package/src/ts/examples/callbacks/topic-based-logging.ts +161 -0
  148. package/src/ts/examples/chaining/test-chaining-redis.ts +113 -0
  149. package/src/ts/examples/chaining/test-chaining.ts +52 -0
  150. package/src/ts/examples/emg-features-example.ts +284 -0
  151. package/src/ts/examples/fft-example.ts +309 -0
  152. package/src/ts/examples/fft-examples.ts +349 -0
  153. package/src/ts/examples/filter-examples.ts +320 -0
  154. package/src/ts/examples/list-state-example.ts +131 -0
  155. package/src/ts/examples/logger-example.ts +91 -0
  156. package/src/ts/examples/notch-filter-examples.ts +243 -0
  157. package/src/ts/examples/phase5/drift-detection-example.ts +290 -0
  158. package/src/ts/examples/phase6-7/production-observability.ts +476 -0
  159. package/src/ts/examples/phase6-7/redis-timeseries-integration.ts +446 -0
  160. package/src/ts/examples/redis/redis-example.ts +202 -0
  161. package/src/ts/examples/redis-example.ts +202 -0
  162. package/src/ts/examples/simd-benchmark.ts +126 -0
  163. package/src/ts/examples/tap-debugging.ts +230 -0
  164. package/src/ts/examples/timeseries/comparison-example.ts +290 -0
  165. package/src/ts/examples/timeseries/iot-sensor-example.ts +143 -0
  166. package/src/ts/examples/timeseries/redis-streaming-example.ts +233 -0
  167. package/src/ts/examples/waveform-length-example.ts +139 -0
  168. package/src/ts/fft.ts +722 -0
  169. package/src/ts/filters.ts +1078 -0
  170. package/src/ts/index.ts +120 -0
  171. package/src/ts/types.ts +589 -0
  172. package/tsconfig.json +15 -0
@@ -0,0 +1,397 @@
1
+ /**
2
+ * Advanced DSP Operations Examples
3
+ *
4
+ * Demonstrates the new advanced DSP features:
5
+ * - Hjorth Parameters (Activity, Mobility, Complexity)
6
+ * - Spectral Features (Centroid, Rolloff, Flux)
7
+ * - Entropy Measures (Shannon, Sample Entropy, Approximate Entropy)
8
+ */
9
+
10
+ import {
11
+ calculateHjorthParameters,
12
+ calculateSpectralFeatures,
13
+ calculateShannonEntropy,
14
+ calculateSampleEntropy,
15
+ calculateApproximateEntropy,
16
+ HjorthTracker,
17
+ SpectralFeaturesTracker,
18
+ EntropyTracker,
19
+ } from "../advanced-dsp.js";
20
+ import { FftProcessor } from "../fft.js";
21
+
22
+ console.log("=== Advanced DSP Operations Examples ===\n");
23
+
24
+ const sampleRate = 1000; // 1 kHz
25
+
26
+ // ============================================================
27
+ // Example 1: Hjorth Parameters - Signal Complexity Analysis
28
+ // ============================================================
29
+
30
+ console.log("--- Example 1: Hjorth Parameters ---");
31
+
32
+ // Create test signals with different complexity
33
+ const simpleSignal = new Float32Array(200);
34
+ const complexSignal = new Float32Array(200);
35
+ const noisySignal = new Float32Array(200);
36
+
37
+ for (let i = 0; i < 200; i++) {
38
+ // Simple: smooth sine wave
39
+ simpleSignal[i] = Math.sin((2 * Math.PI * 5 * i) / sampleRate);
40
+
41
+ // Complex: mix of multiple frequencies
42
+ complexSignal[i] =
43
+ Math.sin((2 * Math.PI * 5 * i) / sampleRate) +
44
+ 0.5 * Math.sin((2 * Math.PI * 15 * i) / sampleRate) +
45
+ 0.3 * Math.sin((2 * Math.PI * 30 * i) / sampleRate);
46
+
47
+ // Noisy: sine wave + random noise
48
+ noisySignal[i] =
49
+ Math.sin((2 * Math.PI * 5 * i) / sampleRate) + (Math.random() - 0.5) * 0.3;
50
+ }
51
+
52
+ const hjorthSimple = calculateHjorthParameters(simpleSignal);
53
+ const hjorthComplex = calculateHjorthParameters(complexSignal);
54
+ const hjorthNoisy = calculateHjorthParameters(noisySignal);
55
+
56
+ console.log("Simple signal (smooth sine):");
57
+ console.log(` Activity: ${hjorthSimple.activity.toFixed(4)}`);
58
+ console.log(` Mobility: ${hjorthSimple.mobility.toFixed(4)}`);
59
+ console.log(` Complexity: ${hjorthSimple.complexity.toFixed(4)}`);
60
+
61
+ console.log("\nComplex signal (multi-frequency):");
62
+ console.log(` Activity: ${hjorthComplex.activity.toFixed(4)}`);
63
+ console.log(` Mobility: ${hjorthComplex.mobility.toFixed(4)}`);
64
+ console.log(` Complexity: ${hjorthComplex.complexity.toFixed(4)}`);
65
+
66
+ console.log("\nNoisy signal:");
67
+ console.log(` Activity: ${hjorthNoisy.activity.toFixed(4)}`);
68
+ console.log(` Mobility: ${hjorthNoisy.mobility.toFixed(4)}`);
69
+ console.log(` Complexity: ${hjorthNoisy.complexity.toFixed(4)}`);
70
+
71
+ console.log(
72
+ "\n✅ Higher complexity indicates more irregular/unpredictable signal\n"
73
+ );
74
+
75
+ // ============================================================
76
+ // Example 2: Hjorth Tracker - Real-Time Monitoring
77
+ // ============================================================
78
+
79
+ console.log("--- Example 2: Hjorth Tracker (Sliding Window) ---");
80
+
81
+ const tracker = new HjorthTracker(100);
82
+
83
+ console.log("Processing samples one at a time...");
84
+ for (let i = 0; i < 150; i++) {
85
+ const sample =
86
+ Math.sin((2 * Math.PI * 5 * i) / sampleRate) + (Math.random() - 0.5) * 0.1;
87
+ const hjorth = tracker.update(sample);
88
+
89
+ if (hjorth && i % 50 === 0) {
90
+ console.log(` Sample ${i}:`);
91
+ console.log(` Activity: ${hjorth.activity.toFixed(4)}`);
92
+ console.log(` Mobility: ${hjorth.mobility.toFixed(4)}`);
93
+ console.log(` Complexity: ${hjorth.complexity.toFixed(4)}`);
94
+ }
95
+ }
96
+
97
+ console.log("✅ Real-time Hjorth tracking for continuous monitoring\n");
98
+
99
+ // ============================================================
100
+ // Example 3: Spectral Features - Frequency Content Analysis
101
+ // ============================================================
102
+
103
+ console.log("--- Example 3: Spectral Features ---");
104
+
105
+ // Create test signal with specific frequency content
106
+ const fftSize = 2048;
107
+ const testSignal = new Float32Array(fftSize);
108
+
109
+ // Low-frequency dominated signal
110
+ for (let i = 0; i < fftSize; i++) {
111
+ testSignal[i] =
112
+ 2.0 * Math.sin((2 * Math.PI * 100 * i) / sampleRate) + // Strong 100 Hz
113
+ 0.5 * Math.sin((2 * Math.PI * 500 * i) / sampleRate); // Weak 500 Hz
114
+ }
115
+
116
+ // Perform FFT
117
+ const fft = new FftProcessor(fftSize);
118
+ const spectrum = fft.rfft(testSignal);
119
+ const magnitude = fft.getMagnitude(spectrum);
120
+
121
+ // Calculate spectral features
122
+ const features = calculateSpectralFeatures(magnitude, sampleRate);
123
+
124
+ console.log("Signal with 100 Hz (strong) + 500 Hz (weak):");
125
+ console.log(` Spectral Centroid: ${features.centroid.toFixed(2)} Hz`);
126
+ console.log(` Spectral Rolloff (85%): ${features.rolloff.toFixed(2)} Hz`);
127
+ console.log(` Spectral Flux: ${features.flux.toFixed(4)}`);
128
+
129
+ console.log("\n✅ Centroid shows center of frequency mass");
130
+ console.log("✅ Rolloff shows where most energy is contained\n");
131
+
132
+ // ============================================================
133
+ // Example 4: Spectral Features Tracker - Frame-by-Frame
134
+ // ============================================================
135
+
136
+ console.log("--- Example 4: Spectral Features Tracker ---");
137
+
138
+ const spectralTracker = new SpectralFeaturesTracker();
139
+
140
+ // Simulate changing frequency content over frames
141
+ console.log("Processing frames with changing frequency content...");
142
+
143
+ for (let frame = 0; frame < 3; frame++) {
144
+ const frameSignal = new Float32Array(fftSize);
145
+ const baseFreq = 200 + frame * 100; // Frequency increases each frame
146
+
147
+ for (let i = 0; i < fftSize; i++) {
148
+ frameSignal[i] = Math.sin((2 * Math.PI * baseFreq * i) / sampleRate);
149
+ }
150
+
151
+ const spectrum = fft.rfft(frameSignal);
152
+ const magnitude = fft.getMagnitude(spectrum);
153
+ const frameFeatures = spectralTracker.calculate(magnitude, sampleRate);
154
+
155
+ console.log(` Frame ${frame + 1} (${baseFreq} Hz):`);
156
+ console.log(` Centroid: ${frameFeatures.centroid.toFixed(2)} Hz`);
157
+ console.log(` Flux: ${frameFeatures.flux.toFixed(4)}`);
158
+ }
159
+
160
+ console.log("✅ Flux tracks changes in spectrum between consecutive frames\n");
161
+
162
+ // ============================================================
163
+ // Example 5: Shannon Entropy - Signal Randomness
164
+ // ============================================================
165
+
166
+ console.log("--- Example 5: Shannon Entropy ---");
167
+
168
+ // Deterministic signal (low entropy)
169
+ const deterministicSignal = new Float32Array(1000);
170
+ for (let i = 0; i < 1000; i++) {
171
+ deterministicSignal[i] = Math.sin((2 * Math.PI * 10 * i) / sampleRate);
172
+ }
173
+
174
+ // Random signal (high entropy)
175
+ const randomSignal = new Float32Array(1000);
176
+ for (let i = 0; i < 1000; i++) {
177
+ randomSignal[i] = Math.random() * 2 - 1;
178
+ }
179
+
180
+ // Mixed signal (medium entropy)
181
+ const mixedSignal = new Float32Array(1000);
182
+ for (let i = 0; i < 1000; i++) {
183
+ mixedSignal[i] =
184
+ 0.7 * Math.sin((2 * Math.PI * 10 * i) / sampleRate) +
185
+ 0.3 * (Math.random() * 2 - 1);
186
+ }
187
+
188
+ const entropyDeterministic = calculateShannonEntropy(deterministicSignal, 256);
189
+ const entropyRandom = calculateShannonEntropy(randomSignal, 256);
190
+ const entropyMixed = calculateShannonEntropy(mixedSignal, 256);
191
+
192
+ console.log("Deterministic signal (pure sine):");
193
+ console.log(` Shannon Entropy: ${entropyDeterministic.toFixed(4)} bits`);
194
+
195
+ console.log("\nRandom signal (uniform noise):");
196
+ console.log(` Shannon Entropy: ${entropyRandom.toFixed(4)} bits`);
197
+
198
+ console.log("\nMixed signal (sine + noise):");
199
+ console.log(` Shannon Entropy: ${entropyMixed.toFixed(4)} bits`);
200
+
201
+ console.log("\n✅ Higher entropy = more unpredictable/random signal\n");
202
+
203
+ // ============================================================
204
+ // Example 6: Entropy Tracker - Real-Time Randomness Monitoring
205
+ // ============================================================
206
+
207
+ console.log("--- Example 6: Entropy Tracker ---");
208
+
209
+ const entropyTracker = new EntropyTracker(200, 128);
210
+
211
+ console.log(
212
+ "Monitoring entropy as signal transitions from periodic to random..."
213
+ );
214
+
215
+ for (let i = 0; i < 300; i++) {
216
+ // Transition from sine wave to noise
217
+ const noiseLevel = Math.min(i / 300, 1.0);
218
+ const sample =
219
+ (1 - noiseLevel) * Math.sin((2 * Math.PI * 10 * i) / sampleRate) +
220
+ noiseLevel * (Math.random() * 2 - 1);
221
+
222
+ const entropy = entropyTracker.update(sample);
223
+
224
+ if (entropy !== null && i % 100 === 0) {
225
+ console.log(` Sample ${i}: Entropy = ${entropy.toFixed(4)} bits`);
226
+ }
227
+ }
228
+
229
+ console.log("✅ Entropy increases as signal becomes more random\n");
230
+
231
+ // ============================================================
232
+ // Example 7: Sample Entropy (SampEn) - Pattern Regularity
233
+ // ============================================================
234
+
235
+ console.log("--- Example 7: Sample Entropy ---");
236
+
237
+ // Regular periodic signal
238
+ const regularSignal = new Float32Array(500);
239
+ for (let i = 0; i < 500; i++) {
240
+ regularSignal[i] = Math.sin((2 * Math.PI * 5 * i) / sampleRate);
241
+ }
242
+
243
+ // Chaotic signal (more irregular)
244
+ const chaoticSignal = new Float32Array(500);
245
+ for (let i = 0; i < 500; i++) {
246
+ chaoticSignal[i] =
247
+ Math.sin((2 * Math.PI * 5 * i) / sampleRate) +
248
+ 0.5 * Math.sin((2 * Math.PI * 13.7 * i) / sampleRate) +
249
+ 0.3 * Math.sin((2 * Math.PI * 23.1 * i) / sampleRate);
250
+ }
251
+
252
+ try {
253
+ const sampEnRegular = calculateSampleEntropy(regularSignal, 2);
254
+ const sampEnChaotic = calculateSampleEntropy(chaoticSignal, 2);
255
+
256
+ console.log("Regular periodic signal:");
257
+ console.log(` Sample Entropy: ${sampEnRegular.toFixed(4)}`);
258
+
259
+ console.log("\nChaotic signal:");
260
+ console.log(` Sample Entropy: ${sampEnChaotic.toFixed(4)}`);
261
+
262
+ console.log(
263
+ "\n✅ Lower SampEn = more regular patterns, Higher SampEn = more chaotic\n"
264
+ );
265
+ } catch (error) {
266
+ console.log("Note: SampEn calculation can be computationally intensive\n");
267
+ }
268
+
269
+ // ============================================================
270
+ // Example 8: Approximate Entropy (ApEn) - Faster Alternative
271
+ // ============================================================
272
+
273
+ console.log("--- Example 8: Approximate Entropy ---");
274
+
275
+ const apEnRegular = calculateApproximateEntropy(regularSignal, 2);
276
+ const apEnChaotic = calculateApproximateEntropy(chaoticSignal, 2);
277
+
278
+ console.log("Regular periodic signal:");
279
+ console.log(` Approximate Entropy: ${apEnRegular.toFixed(4)}`);
280
+
281
+ console.log("\nChaotic signal:");
282
+ console.log(` Approximate Entropy: ${apEnChaotic.toFixed(4)}`);
283
+
284
+ console.log("\n✅ ApEn is faster than SampEn but may have more bias\n");
285
+
286
+ // ============================================================
287
+ // Example 9: Real-World Application - EMG Signal Analysis
288
+ // ============================================================
289
+
290
+ console.log("--- Example 9: EMG Signal Analysis Use Case ---");
291
+
292
+ // Simulate EMG signal (muscle activity)
293
+ const emgSignal = new Float32Array(2000);
294
+ for (let i = 0; i < 2000; i++) {
295
+ // Mix of frequencies typical in EMG (20-450 Hz)
296
+ emgSignal[i] =
297
+ 0.3 * Math.sin((2 * Math.PI * 50 * i) / sampleRate) +
298
+ 0.5 * Math.sin((2 * Math.PI * 120 * i) / sampleRate) +
299
+ 0.4 * Math.sin((2 * Math.PI * 250 * i) / sampleRate) +
300
+ 0.2 * (Math.random() * 2 - 1);
301
+ }
302
+
303
+ const emgHjorth = calculateHjorthParameters(emgSignal);
304
+ const emgEntropy = calculateShannonEntropy(emgSignal, 256);
305
+
306
+ console.log("EMG Signal Analysis:");
307
+ console.log(` Hjorth Activity: ${emgHjorth.activity.toFixed(4)}`);
308
+ console.log(` Hjorth Mobility: ${emgHjorth.mobility.toFixed(4)}`);
309
+ console.log(` Hjorth Complexity: ${emgHjorth.complexity.toFixed(4)}`);
310
+ console.log(` Shannon Entropy: ${emgEntropy.toFixed(4)} bits`);
311
+
312
+ console.log("\n✅ Combined features useful for:");
313
+ console.log(" - Muscle fatigue detection (Hjorth Mobility trends)");
314
+ console.log(" - Signal quality assessment (Entropy)");
315
+ console.log(" - Activity level classification (Hjorth Activity)\n");
316
+
317
+ // ============================================================
318
+ // Example 10: EEG/Biosignal Monitoring Pipeline
319
+ // ============================================================
320
+
321
+ console.log("--- Example 10: Complete Monitoring Pipeline ---");
322
+
323
+ console.log("Real-time biosignal monitoring:");
324
+
325
+ const monitoringTracker = new HjorthTracker(250);
326
+ const monitoringEntropy = new EntropyTracker(250, 128);
327
+
328
+ // Simulate streaming data
329
+ console.log("Processing 1000 samples in sliding windows...");
330
+
331
+ let complexityWarnings = 0;
332
+ let entropyWarnings = 0;
333
+
334
+ for (let i = 0; i < 1000; i++) {
335
+ // Simulate changing signal conditions
336
+ const signal =
337
+ Math.sin((2 * Math.PI * 10 * i) / sampleRate) +
338
+ (Math.random() - 0.5) * (i > 500 ? 0.8 : 0.2); // Noise increases halfway
339
+
340
+ const hjorth = monitoringTracker.update(signal);
341
+ const entropy = monitoringEntropy.update(signal);
342
+
343
+ if (hjorth && entropy !== null && i % 250 === 0) {
344
+ console.log(` Checkpoint at sample ${i}:`);
345
+ console.log(` Complexity: ${hjorth.complexity.toFixed(4)}`);
346
+ console.log(` Entropy: ${entropy.toFixed(4)} bits`);
347
+
348
+ // Detect abnormal conditions
349
+ if (hjorth.complexity > 2.0) {
350
+ console.log(` ⚠️ High complexity detected`);
351
+ complexityWarnings++;
352
+ }
353
+ if (entropy > 6.0) {
354
+ console.log(` ⚠️ High entropy detected`);
355
+ entropyWarnings++;
356
+ }
357
+ }
358
+ }
359
+
360
+ console.log(`\n✅ Detected ${complexityWarnings} complexity warnings`);
361
+ console.log(`✅ Detected ${entropyWarnings} entropy warnings`);
362
+ console.log("✅ Real-time monitoring enables early anomaly detection\n");
363
+
364
+ // ============================================================
365
+ // Summary
366
+ // ============================================================
367
+
368
+ console.log("=== Summary ===");
369
+
370
+ console.log("\n✅ Hjorth Parameters:");
371
+ console.log(" - Activity: Signal variance (power)");
372
+ console.log(" - Mobility: Rate of change");
373
+ console.log(" - Complexity: Change of change (irregularity)");
374
+ console.log(" - Use: EMG/EEG analysis, signal quality");
375
+
376
+ console.log("\n✅ Spectral Features:");
377
+ console.log(" - Centroid: Frequency center of mass");
378
+ console.log(" - Rolloff: Energy concentration point");
379
+ console.log(" - Flux: Frame-to-frame spectral change");
380
+ console.log(" - Use: Audio analysis, speech processing");
381
+
382
+ console.log("\n✅ Entropy Measures:");
383
+ console.log(" - Shannon: Amplitude distribution randomness");
384
+ console.log(" - Sample Entropy: Pattern regularity");
385
+ console.log(" - Approximate Entropy: Faster alternative to SampEn");
386
+ console.log(" - Use: Complexity analysis, anomaly detection");
387
+
388
+ console.log("\n✅ Stateful Trackers:");
389
+ console.log(" - HjorthTracker: Sliding window Hjorth parameters");
390
+ console.log(" - SpectralFeaturesTracker: Frame-by-frame features");
391
+ console.log(" - EntropyTracker: Sliding window entropy");
392
+ console.log(" - Use: Real-time monitoring, streaming analysis");
393
+
394
+ console.log("\n📚 All implemented in pure TypeScript for flexibility!");
395
+ console.log(
396
+ "🚀 Use with existing FFT and filter operations for complete DSP pipelines!"
397
+ );