echogarden 0.11.12 → 0.11.13

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 (122) hide show
  1. package/data/schemas/options.json +16 -0
  2. package/dist/api/Alignment.js +2 -2
  3. package/dist/api/Alignment.js.map +1 -1
  4. package/dist/api/Recognition.js +2 -2
  5. package/dist/api/Recognition.js.map +1 -1
  6. package/dist/api/Synthesis.js +5 -4
  7. package/dist/api/Synthesis.js.map +1 -1
  8. package/dist/api/Translation.js +2 -2
  9. package/dist/api/Translation.js.map +1 -1
  10. package/dist/audio/AudioUtilities.d.ts +1 -0
  11. package/dist/audio/AudioUtilities.js +25 -7
  12. package/dist/audio/AudioUtilities.js.map +1 -1
  13. package/dist/cli/CLI.js +2 -2
  14. package/dist/cli/CLI.js.map +1 -1
  15. package/dist/recognition/WhisperSTT.js +2 -2
  16. package/dist/recognition/WhisperSTT.js.map +1 -1
  17. package/dist/subtitles/Subtitles.d.ts +10 -7
  18. package/dist/subtitles/Subtitles.js +268 -207
  19. package/dist/subtitles/Subtitles.js.map +1 -1
  20. package/docs/Options.md +4 -2
  21. package/package.json +7 -6
  22. package/src/alignment/DTWMfccSequenceAlignment.ts +43 -0
  23. package/src/alignment/DTWSequenceAlignment.ts +121 -0
  24. package/src/alignment/DTWSequenceAlignmentWindowed.ts +210 -0
  25. package/src/alignment/LevenshteinSequenceAlignment.ts +126 -0
  26. package/src/alignment/SpeechAlignment.ts +488 -0
  27. package/src/api/API.ts +12 -0
  28. package/src/api/APIOptions.ts +15 -0
  29. package/src/api/Alignment.ts +329 -0
  30. package/src/api/Common.ts +16 -0
  31. package/src/api/Denoising.ts +120 -0
  32. package/src/api/LanguageDetection.ts +286 -0
  33. package/src/api/Recognition.ts +344 -0
  34. package/src/api/Synthesis.ts +1735 -0
  35. package/src/api/Translation.ts +143 -0
  36. package/src/api/Vad.ts +172 -0
  37. package/src/audio/AudioBufferConversion.ts +248 -0
  38. package/src/audio/AudioPlayer.ts +358 -0
  39. package/src/audio/AudioRecorder.ts +91 -0
  40. package/src/audio/AudioUtilities.ts +392 -0
  41. package/src/audio/SoxPath.ts +24 -0
  42. package/src/cli/CLI.ts +1360 -0
  43. package/src/cli/CLIConfigFile.ts +91 -0
  44. package/src/cli/CLILauncher.ts +26 -0
  45. package/src/cli/CLIOptionsSchema.ts +54 -0
  46. package/src/cli/CLIParser.ts +41 -0
  47. package/src/cli/CLIStarter.ts +40 -0
  48. package/src/codecs/FFMpegTranscoder.ts +214 -0
  49. package/src/codecs/TIMITCodec.ts +17 -0
  50. package/src/codecs/WaveCodec.ts +260 -0
  51. package/src/denoising/RNNoise.ts +95 -0
  52. package/src/dsp/BiquadFilter.ts +488 -0
  53. package/src/dsp/FFT.ts +187 -0
  54. package/src/dsp/MFCC.ts +227 -0
  55. package/src/dsp/MelSpectogram.ts +145 -0
  56. package/src/dsp/Rubberband.ts +249 -0
  57. package/src/dsp/Sonic.ts +59 -0
  58. package/src/dsp/SpeexResampler.ts +79 -0
  59. package/src/math/VectorMath.ts +812 -0
  60. package/src/nlp/ChineseSegmentation.ts +68 -0
  61. package/src/nlp/CompromiseNLP.ts +113 -0
  62. package/src/nlp/EspeakPhonemizer.ts +168 -0
  63. package/src/nlp/IPA.ts +139 -0
  64. package/src/nlp/JapaneseSegmentation.ts +53 -0
  65. package/src/nlp/Lexicon.ts +119 -0
  66. package/src/nlp/PhoneConversion.ts +508 -0
  67. package/src/nlp/Segmentation.ts +237 -0
  68. package/src/nlp/TextNormalizer.ts +160 -0
  69. package/src/recognition/AmazonTranscribeSTT.ts +112 -0
  70. package/src/recognition/AzureCognitiveServicesSTT.ts +76 -0
  71. package/src/recognition/GoogleCloudSTT.ts +92 -0
  72. package/src/recognition/SileroSTT.ts +173 -0
  73. package/src/recognition/VoskSTT.ts +112 -0
  74. package/src/recognition/WhisperSTT.ts +1518 -0
  75. package/src/server/Client.ts +297 -0
  76. package/src/server/Server.ts +178 -0
  77. package/src/server/ServerStarter.ts +12 -0
  78. package/src/server/Worker.ts +400 -0
  79. package/src/server/WorkerStarter.ts +38 -0
  80. package/src/speech-language-detection/SileroLanguageDetection.ts +105 -0
  81. package/src/subtitles/Subtitles.ts +478 -0
  82. package/src/synthesis/AwsPollyTTS.ts +78 -0
  83. package/src/synthesis/AzureCognitiveServicesTTS.ts +146 -0
  84. package/src/synthesis/CoquiServerTTS.ts +29 -0
  85. package/src/synthesis/ElevenLabsTTS.ts +104 -0
  86. package/src/synthesis/EspeakTTS.ts +552 -0
  87. package/src/synthesis/FliteTTS.ts +387 -0
  88. package/src/synthesis/GoogleCloudTTS.ts +112 -0
  89. package/src/synthesis/GoogleTranslateTTS.ts +210 -0
  90. package/src/synthesis/MicrosoftEdgeTTS.ts +298 -0
  91. package/src/synthesis/SamTTS.ts +30 -0
  92. package/src/synthesis/SapiTTS.ts +222 -0
  93. package/src/synthesis/StreamlabsPollyTTS.ts +114 -0
  94. package/src/synthesis/SvoxPicoTTS.ts +318 -0
  95. package/src/synthesis/VitsTTS.ts +734 -0
  96. package/src/tests/Test.ts +24 -0
  97. package/src/text-language-detection/FastTextLanguageDetection.ts +53 -0
  98. package/src/text-language-detection/TinyLDLanguageDetection.ts +16 -0
  99. package/src/typings/Fillers.d.ts +41 -0
  100. package/src/utilities/BinaryArrayConversion.ts +159 -0
  101. package/src/utilities/Compression.ts +91 -0
  102. package/src/utilities/FileDownloader.ts +201 -0
  103. package/src/utilities/FileSystem.ts +265 -0
  104. package/src/utilities/Hashing.ts +230 -0
  105. package/src/utilities/Locale.ts +119 -0
  106. package/src/utilities/Logger.ts +72 -0
  107. package/src/utilities/NdArrayUtilities.ts +31 -0
  108. package/src/utilities/ObjectUtilities.ts +169 -0
  109. package/src/utilities/OpenPromise.ts +13 -0
  110. package/src/utilities/PackageManager.ts +97 -0
  111. package/src/utilities/Queue.ts +17 -0
  112. package/src/utilities/RandomGenerator.ts +237 -0
  113. package/src/utilities/SignalChannel.ts +22 -0
  114. package/src/utilities/TarballMaker.ts +68 -0
  115. package/src/utilities/Timeline.ts +231 -0
  116. package/src/utilities/Timer.ts +93 -0
  117. package/src/utilities/Utilities.ts +574 -0
  118. package/src/utilities/WasmMemoryManager.ts +516 -0
  119. package/src/utilities/WebReader.ts +55 -0
  120. package/src/utilities/WikipediaReader.ts +41 -0
  121. package/src/voice-activity-detection/SileroVAD.ts +86 -0
  122. package/src/voice-activity-detection/WebRtcVAD.ts +76 -0
@@ -0,0 +1,812 @@
1
+ import createMedianFilter from 'moving-median'
2
+
3
+ export function covarianceMatrixOfSamples(samples: number[][], weights?: number[], biased = false) {
4
+ if (samples.length == 0) {
5
+ throw new Error("No vectors given")
6
+ }
7
+
8
+ const { centeredVectors: centeredSamples, mean } = centerVectors(samples, weights)
9
+
10
+ let covarianceMatrix
11
+
12
+ if (weights) {
13
+ covarianceMatrix = weightedCovarianceMatrixOfCenteredSamples(centeredSamples, weights)
14
+ } else {
15
+ covarianceMatrix = covarianceMatrixOfCenteredSamples(centeredSamples, biased)
16
+ }
17
+
18
+ return { covarianceMatrix, mean }
19
+ }
20
+
21
+ export function covarianceMatrixOfCenteredSamples(centeredSamples: number[][], biased = false, diagonalRegularizationAmount = 1e-6) {
22
+ const sampleCount = centeredSamples.length
23
+
24
+ if (sampleCount == 0) {
25
+ throw new Error("No vectors given")
26
+ }
27
+
28
+ const sampleSizeMetric = biased || sampleCount == 1 ? sampleCount : sampleCount - 1
29
+ const featureCount = centeredSamples[0].length
30
+
31
+ const covarianceMatrix = createVectorArray(featureCount, featureCount)
32
+
33
+ if (sampleCount == 1) {
34
+ return covarianceMatrix
35
+ }
36
+
37
+ for (let i = 0; i < featureCount; i++) {
38
+ for (let j = 0; j < featureCount; j++) {
39
+ if (i > j) {
40
+ covarianceMatrix[i][j] = covarianceMatrix[j][i]
41
+ continue
42
+ }
43
+
44
+ let matrixElement = 0.0
45
+
46
+ for (const sample of centeredSamples) {
47
+ matrixElement += sample[i] * sample[j]
48
+ }
49
+
50
+ matrixElement /= sampleSizeMetric
51
+
52
+ if (i == j) {
53
+ matrixElement += diagonalRegularizationAmount
54
+ }
55
+
56
+ covarianceMatrix[i][j] = matrixElement
57
+ }
58
+ }
59
+
60
+ return covarianceMatrix
61
+ }
62
+
63
+ export function weightedCovarianceMatrixOfCenteredSamples(centeredSamples: number[][], weights: number[], diagonalRegularizationAmount = 1e-6) {
64
+ const sampleCount = centeredSamples.length
65
+
66
+ if (sampleCount == 0) {
67
+ throw new Error("No vectors given")
68
+ }
69
+
70
+ const featureCount = centeredSamples[0].length
71
+
72
+ const covarianceMatrix = createVectorArray(featureCount, featureCount)
73
+
74
+ if (sampleCount == 1) {
75
+ return covarianceMatrix
76
+ }
77
+
78
+ for (let i = 0; i < featureCount; i++) {
79
+ for (let j = 0; j < featureCount; j++) {
80
+ if (i > j) {
81
+ covarianceMatrix[i][j] = covarianceMatrix[j][i]
82
+ continue
83
+ }
84
+
85
+ let matrixElement = 0.0
86
+
87
+ for (let sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) {
88
+ const sample = centeredSamples[sampleIndex]
89
+ const weight = weights[sampleIndex]
90
+
91
+ matrixElement += weight * (sample[i] * sample[j])
92
+ }
93
+
94
+ if (i == j) {
95
+ matrixElement += diagonalRegularizationAmount
96
+ }
97
+
98
+ covarianceMatrix[i][j] = matrixElement
99
+ }
100
+ }
101
+
102
+ return covarianceMatrix
103
+ }
104
+
105
+ export function centerVectors(vectors: number[][], weights?: number[]) {
106
+ const vectorCount = vectors.length
107
+
108
+ if (vectorCount == 0) {
109
+ return { centeredVectors: [], mean: [] }
110
+ }
111
+
112
+ let mean: number[]
113
+ if (weights) {
114
+ mean = weightedMeanOfVectors(vectors, weights)
115
+ } else {
116
+ mean = meanOfVectors(vectors)
117
+ }
118
+
119
+ const centeredVectors: number[][] = new Array(vectorCount)
120
+
121
+ for (let i = 0; i < vectorCount; i++) {
122
+ centeredVectors[i] = subtractVectors(vectors[i], mean)
123
+ }
124
+
125
+ return { centeredVectors, mean }
126
+ }
127
+
128
+ export function centerVector(vector: number[]) {
129
+ const mean = meanOfVector(vector)
130
+
131
+ const centeredVector: number[] = new Array(vector.length)
132
+
133
+ for (let i = 0; i < vector.length; i++) {
134
+ centeredVector[i] = vector[i] - mean
135
+ }
136
+
137
+ return centeredVector
138
+ }
139
+
140
+ export function scaleToSumTo1(vector: number[]) {
141
+ if (vector.length == 0) {
142
+ return []
143
+ }
144
+
145
+ if (vector.length == 1) {
146
+ return [1]
147
+ }
148
+
149
+ const minValue = vector[indexOfMin(vector)]
150
+
151
+ const scaledVector = vector.slice()
152
+
153
+ if (minValue < 0) {
154
+ const addedOffset = -minValue * 2
155
+
156
+ for (let i = 0; i < scaledVector.length; i++) {
157
+ scaledVector[i] += addedOffset
158
+ }
159
+ }
160
+
161
+ const sum = sumVector(scaledVector)
162
+
163
+ if (sum == 0) {
164
+ return scaledVector
165
+ }
166
+
167
+ if (sum == Infinity) {
168
+ throw new Error("Vector sum is infinite")
169
+ }
170
+
171
+ for (let i = 0; i < vector.length; i++) {
172
+ scaledVector[i] /= sum
173
+
174
+ scaledVector[i] = zeroIfNaN(scaledVector[i])
175
+ }
176
+
177
+ return scaledVector
178
+ }
179
+
180
+ export function normalizeVector(vector: number[], kind: "population" | "sample" = "population") {
181
+ if (vector.length == 0) {
182
+ throw new Error("Vector is empty")
183
+ }
184
+
185
+ const mean = meanOfVector(vector)
186
+ const stdDeviation = stdDeviationOfVector(vector, kind, mean)
187
+
188
+ const normalizedVector = createVector(vector.length)
189
+
190
+ for (let i = 0; i < vector.length; i++) {
191
+ normalizedVector[i] = (vector[i] - mean) / stdDeviation
192
+
193
+ normalizedVector[i] = zeroIfNaN(normalizedVector[i])
194
+ }
195
+
196
+ return { normalizedVector, mean, stdDeviation }
197
+ }
198
+
199
+ export function normalizeVectors(vectors: number[][], kind: "population" | "sample" = "population") {
200
+ const vectorCount = vectors.length
201
+
202
+ if (vectorCount == 0) {
203
+ return { normalizedVectors: [], mean: [], stdDeviation: [] }
204
+ }
205
+
206
+ const featureCount = vectors[0].length
207
+
208
+ const mean = meanOfVectors(vectors)
209
+ const stdDeviation = stdDeviationOfVectors(vectors, kind, mean)
210
+
211
+ const normalizedVectors: number[][] = []
212
+
213
+ for (const vector of vectors) {
214
+ const normalizedVector = createVector(featureCount)
215
+
216
+ for (let featureIndex = 0; featureIndex < featureCount; featureIndex++) {
217
+ normalizedVector[featureIndex] = (vector[featureIndex] - mean[featureIndex]) / stdDeviation[featureIndex]
218
+
219
+ normalizedVector[featureIndex] = zeroIfNaN(normalizedVector[featureIndex])
220
+ }
221
+
222
+ normalizedVectors.push(normalizedVector)
223
+ }
224
+
225
+ return { normalizedVectors, mean, stdDeviation }
226
+ }
227
+
228
+ export function deNormalizeVectors(normalizedVectors: number[][], originalMean: number[], originalStdDeviation: number[]) {
229
+ const vectorCount = normalizeVectors.length
230
+
231
+ if (vectorCount == 0) {
232
+ return []
233
+ }
234
+
235
+ const featureCount = normalizedVectors[0].length
236
+
237
+ const deNormalizedVectors: number[][] = []
238
+
239
+ for (const normalizedVector of normalizedVectors) {
240
+ const deNormalizedVector = createVector(featureCount)
241
+
242
+ for (let featureIndex = 0; featureIndex < featureCount; featureIndex++) {
243
+ deNormalizedVector[featureIndex] = originalMean[featureIndex] + (normalizedVector[featureIndex] * originalStdDeviation[featureIndex])
244
+ }
245
+
246
+ deNormalizedVectors.push(deNormalizedVector)
247
+ }
248
+
249
+ return deNormalizedVectors
250
+ }
251
+
252
+ export function meanOfVectors(vectors: number[][]) {
253
+ const vectorCount = vectors.length
254
+
255
+ if (vectorCount == 0) {
256
+ return []
257
+ }
258
+
259
+ const featureCount = vectors[0].length
260
+
261
+ const result = createVector(featureCount)
262
+
263
+ for (const vector of vectors) {
264
+ for (let featureIndex = 0; featureIndex < featureCount; featureIndex++) {
265
+ result[featureIndex] += vector[featureIndex]
266
+ }
267
+ }
268
+
269
+ for (let featureIndex = 0; featureIndex < featureCount; featureIndex++) {
270
+ result[featureIndex] /= vectorCount
271
+ }
272
+
273
+ return result
274
+ }
275
+
276
+ export function weightedMeanOfVectors(vectors: number[][], weights: number[]) {
277
+ const vectorCount = vectors.length
278
+
279
+ if (vectorCount == 0) {
280
+ return []
281
+ }
282
+
283
+ const featureCount = vectors[0].length
284
+
285
+ const result = createVector(featureCount)
286
+
287
+ for (let vectorIndex = 0; vectorIndex < vectorCount; vectorIndex++) {
288
+ const vector = vectors[vectorIndex]
289
+ const vectorWeight = weights[vectorIndex]
290
+
291
+ for (let featureIndex = 0; featureIndex < featureCount; featureIndex++) {
292
+ result[featureIndex] += vectorWeight * vector[featureIndex]
293
+ }
294
+ }
295
+
296
+ return result
297
+ }
298
+
299
+ export function stdDeviationOfVectors(vectors: number[][], kind: "population" | "sample" = "population", mean?: number[]) {
300
+ return varianceOfVectors(vectors, kind, mean).map(v => Math.sqrt(v))
301
+ }
302
+
303
+ export function varianceOfVectors(vectors: number[][], kind: "population" | "sample" = "population", mean?: number[]) {
304
+ const vectorCount = vectors.length
305
+
306
+ if (vectorCount == 0) {
307
+ return []
308
+ }
309
+
310
+ const sampleSizeMetric = kind == "population" || vectorCount == 1 ? vectorCount : vectorCount - 1
311
+ const featureCount = vectors[0].length
312
+
313
+ if (!mean) {
314
+ mean = meanOfVectors(vectors)
315
+ }
316
+
317
+ const result = createVector(featureCount)
318
+
319
+ for (const vector of vectors) {
320
+ for (let i = 0; i < featureCount; i++) {
321
+ result[i] += (vector[i] - mean[i]) ** 2
322
+ }
323
+ }
324
+
325
+ for (let i = 0; i < featureCount; i++) {
326
+ result[i] /= sampleSizeMetric
327
+ }
328
+
329
+ return result
330
+ }
331
+
332
+ export function meanOfVector(vector: number[]) {
333
+ if (vector.length == 0) {
334
+ throw new Error("Vector is empty")
335
+ }
336
+
337
+ return sumVector(vector) / vector.length
338
+ }
339
+
340
+ export function medianOfVector(vector: number[]) {
341
+ if (vector.length == 0) {
342
+ throw new Error("Vector is empty")
343
+ }
344
+
345
+ return vector[Math.floor(vector.length / 2)]
346
+ }
347
+
348
+ export function stdDeviationOfVector(vector: number[], kind: "population" | "sample" = "population", mean?: number) {
349
+ return Math.sqrt(varianceOfVector(vector, kind, mean))
350
+ }
351
+
352
+ export function varianceOfVector(vector: number[], kind: "population" | "sample" = "population", mean?: number) {
353
+ if (vector.length == 0) {
354
+ throw new Error("Vector is empty")
355
+ }
356
+
357
+ const sampleSizeMetric = kind == "population" || vector.length == 1 ? vector.length : vector.length - 1
358
+
359
+ if (mean == null) {
360
+ mean = meanOfVector(vector)
361
+ }
362
+
363
+ let result = 0.0
364
+
365
+ for (const value of vector) {
366
+ result += (value - mean) ** 2
367
+ }
368
+
369
+ return result / sampleSizeMetric
370
+ }
371
+
372
+ export function logOfVector(vector: number[], minVal = 1e-40) {
373
+ return vector.map(value => Math.log(minVal + value))
374
+ }
375
+
376
+ export function expOfVector(vector: number[]) {
377
+ return vector.map(value => Math.exp(value))
378
+ }
379
+
380
+ export function transpose(matrix: number[][]) {
381
+ const vectorCount = matrix.length
382
+ const featureCount = matrix[0].length
383
+
384
+ const transposedMatrix = createVectorArray(featureCount, vectorCount)
385
+
386
+ for (let i = 0; i < vectorCount; i++) {
387
+ for (let j = 0; j < featureCount; j++) {
388
+ transposedMatrix[j][i] = matrix[i][j]
389
+ }
390
+ }
391
+
392
+ return transposedMatrix
393
+ }
394
+
395
+ export function movingAverageOfWindow3(vector: number[]) {
396
+ const elementCount = vector.length
397
+
398
+ if (elementCount == 0) {
399
+ return []
400
+ }
401
+
402
+ if (elementCount == 1) {
403
+ return vector.slice()
404
+ }
405
+
406
+ const result: number[] = []
407
+
408
+ result.push((vector[0] + vector[0] + vector[1]) / 3)
409
+
410
+ for (let i = 1; i < elementCount - 1; i++) {
411
+ result.push((vector[i - 1] + vector[i] + vector[i + 1]) / 3)
412
+ }
413
+
414
+ result.push((vector[elementCount - 2] + vector[elementCount - 1] + vector[elementCount - 1]) / 3)
415
+
416
+ return result
417
+ }
418
+
419
+ export function averageMeanSquaredError(actual: number[][], expected: number[][]) {
420
+ if (actual.length != expected.length) {
421
+ throw new Error("Vectors are not the same length")
422
+ }
423
+
424
+ const vectorCount = actual.length
425
+
426
+ if (vectorCount == 0) {
427
+ return 0
428
+ }
429
+
430
+ let sum = 0.0
431
+
432
+ for (let i = 0; i < vectorCount; i++) {
433
+ sum += meanSquaredError(actual[i], expected[i])
434
+ }
435
+
436
+ return sum / vectorCount
437
+ }
438
+
439
+ export function meanSquaredError(actual: number[], expected: number[]) {
440
+ if (actual.length != expected.length) {
441
+ throw new Error("Vectors are not the same length")
442
+ }
443
+
444
+ const featureCount = actual.length
445
+
446
+ if (featureCount == 0) {
447
+ return 0
448
+ }
449
+
450
+ let sum = 0.0
451
+
452
+ for (let i = 0; i < featureCount; i++) {
453
+ sum += (actual[i] - expected[i]) ** 2
454
+ }
455
+
456
+ return sum / featureCount
457
+ }
458
+
459
+ export function eucledianDistance(vector1: number[], vector2: number[]) {
460
+ return Math.sqrt(squaredEucledianDistance(vector1, vector2))
461
+ }
462
+
463
+ export function squaredEucledianDistance(vector1: number[], vector2: number[]) {
464
+ if (vector1.length != vector2.length) {
465
+ throw new Error("Vectors are not the same length")
466
+ }
467
+
468
+ const elementCount = vector1.length
469
+
470
+ if (elementCount == 0) {
471
+ return 0
472
+ }
473
+
474
+ let sum = 0.0
475
+
476
+ for (let i = 0; i < elementCount; i++) {
477
+ sum += (vector1[i] - vector2[i]) ** 2
478
+ }
479
+
480
+ return sum
481
+ }
482
+
483
+ export function cosineDistance(vector1: number[], vector2: number[]) {
484
+ return 1 - cosineSimilarity(vector1, vector2)
485
+ }
486
+
487
+ export function cosineSimilarity(vector1: number[], vector2: number[]) {
488
+ if (vector1.length != vector2.length) {
489
+ throw new Error("Vectors are not the same length")
490
+ }
491
+
492
+ if (vector1.length == 0) {
493
+ return 0
494
+ }
495
+
496
+ const elementCount = vector1.length
497
+
498
+ let dotProduct = 0.0
499
+
500
+ let squaredMagnitude1 = 0.0
501
+ let squaredMagnitude2 = 0.0
502
+
503
+ for (let i = 0; i < elementCount; i++) {
504
+ dotProduct += vector1[i] * vector2[i]
505
+
506
+ squaredMagnitude1 += vector1[i] ** 2
507
+ squaredMagnitude2 += vector2[i] ** 2
508
+ }
509
+
510
+ const result = dotProduct / (Math.sqrt(squaredMagnitude1) * Math.sqrt(squaredMagnitude2))
511
+
512
+ return zeroIfNaN(result)
513
+ }
514
+
515
+ export function minkowskiDistance(vector1: number[], vector2: number[], power: number) {
516
+ if (vector1.length != vector2.length) {
517
+ throw new Error("Vectors are not the same length")
518
+ }
519
+
520
+ const elementCount = vector1.length
521
+
522
+ if (elementCount == 0) {
523
+ return 0
524
+ }
525
+
526
+ let sum = 0.0
527
+
528
+ for (let i = 0; i < elementCount; i++) {
529
+ sum += Math.abs(vector1[i] - vector2[i]) ** power
530
+ }
531
+
532
+ return sum ** (1 / power)
533
+ }
534
+
535
+ export function cosineDistancePrecomputedMagnitudes(vector1: number[], vector2: number[], magnitude1: number, magnitude2: number) {
536
+ return 1 - cosineSimilarityPrecomputedMagnitudes(vector1, vector2, magnitude1, magnitude2)
537
+ }
538
+
539
+ export function cosineSimilarityPrecomputedMagnitudes(vector1: number[], vector2: number[], magnitude1: number, magnitude2: number) {
540
+ if (vector1.length != vector2.length) {
541
+ throw new Error("Vectors are not the same length")
542
+ }
543
+
544
+ if (vector1.length == 0) {
545
+ return 0
546
+ }
547
+
548
+ const featureCount = vector1.length
549
+
550
+ let dotProduct = 0.0
551
+
552
+ for (let i = 0; i < featureCount; i++) {
553
+ dotProduct += vector1[i] * vector2[i]
554
+ }
555
+
556
+ const result = dotProduct / (magnitude1 * magnitude2)
557
+
558
+ return zeroIfNaN(result)
559
+ }
560
+
561
+
562
+ export function subtractVectors(vector1: number[], vector2: number[]) {
563
+ if (vector1.length != vector2.length) {
564
+ throw new Error("Vectors are not the same length")
565
+ }
566
+
567
+ const result = createVector(vector1.length)
568
+
569
+ for (let i = 0; i < vector1.length; i++) {
570
+ result[i] = vector1[i] - vector2[i]
571
+ }
572
+
573
+ return result
574
+ }
575
+
576
+ export function sumVector(vector: number[]) {
577
+ let result = 0.0
578
+
579
+ for (let i = 0; i < vector.length; i++) {
580
+ result += vector[i]
581
+ }
582
+
583
+ return result
584
+ }
585
+
586
+ export function dotProduct(vector1: number[], vector2: number[]) {
587
+ if (vector1.length != vector2.length) {
588
+ throw new Error("Vectors are not the same length")
589
+ }
590
+
591
+ const elementCount = vector1.length
592
+
593
+ let result = 0.0
594
+
595
+ for (let i = 0; i < elementCount; i++) {
596
+ result += vector1[i] * vector2[i]
597
+ }
598
+
599
+ return result
600
+ }
601
+
602
+ export function magnitude(vector: number[]) {
603
+ const featureCount = vector.length
604
+
605
+ let squaredMagnitude = 0.0
606
+
607
+ for (let i = 0; i < featureCount; i++) {
608
+ squaredMagnitude += vector[i] ** 2
609
+ }
610
+
611
+ return Math.sqrt(squaredMagnitude)
612
+ }
613
+
614
+ export function maxValue(vector: number[]) {
615
+ return vector[indexOfMax(vector)]
616
+ }
617
+
618
+ export function indexOfMax(vector: number[]) {
619
+ let maxValue = -Infinity
620
+ let result = -1
621
+
622
+ for (let i = 0; i < vector.length; i++) {
623
+ if (vector[i] > maxValue) {
624
+ maxValue = vector[i]
625
+ result = i
626
+ }
627
+ }
628
+
629
+ return result
630
+ }
631
+
632
+ export function minValue(vector: number[]) {
633
+ return vector[indexOfMin(vector)]
634
+ }
635
+
636
+ export function indexOfMin(vector: number[]) {
637
+ let minValue = Infinity
638
+ let result = -1
639
+
640
+ for (let i = 0; i < vector.length; i++) {
641
+ if (vector[i] < minValue) {
642
+ minValue = vector[i]
643
+ result = i
644
+ }
645
+ }
646
+
647
+ return result
648
+ }
649
+
650
+ export function exponentialSmoothingMeanOfVectors(vectors: number[][], smoothingFactor: number) {
651
+ const vectorCount = vectors.length
652
+
653
+ if (vectorCount == 0) {
654
+ return []
655
+ }
656
+
657
+ const featureCount = vectors[0].length
658
+
659
+ const currentEstimate = createVector(featureCount)
660
+
661
+ for (let i = 0; i < vectorCount; i++) {
662
+ for (let j = 0; j < featureCount; j++) {
663
+ const value = vectors[i][j]
664
+
665
+ currentEstimate[j] = (smoothingFactor * value) + ((1 - smoothingFactor) * currentEstimate[j])
666
+ }
667
+ }
668
+
669
+ return currentEstimate
670
+ }
671
+
672
+ export function sigmoid(x: number) {
673
+ const result = 1 / (1 + Math.exp(-x))
674
+
675
+ return zeroIfNaN(result)
676
+ }
677
+
678
+ export function softmax(logits: number[], temperature = 1.0) {
679
+ if (logits.length == 0) {
680
+ return []
681
+ }
682
+
683
+ let maxValue = -Infinity
684
+
685
+ for (const val of logits) {
686
+ if (val > maxValue) {
687
+ maxValue = val
688
+ }
689
+ }
690
+
691
+ const temperatureMultiplier = 1 / temperature
692
+
693
+ const result: number[] = []
694
+
695
+ let sumOfExponentiatedValues = 0.0
696
+
697
+ for (const value of logits) {
698
+ const eToValue = Math.exp((value - maxValue) * temperatureMultiplier)
699
+
700
+ sumOfExponentiatedValues += eToValue
701
+
702
+ result.push(eToValue)
703
+ }
704
+
705
+ const sumOfExponentiatedValuesMultiplier = 1 / (sumOfExponentiatedValues + 1e-40)
706
+
707
+ for (let i = 0; i < result.length; i++) {
708
+ result[i] *= sumOfExponentiatedValuesMultiplier
709
+ }
710
+
711
+ return result
712
+ }
713
+
714
+ export function hammingDistance(value1: number, value2: number, bitLength = 32) {
715
+ let valueXor = value1 ^ value2
716
+
717
+ let result = 0
718
+
719
+ for (let i = 0; i < bitLength; i++) {
720
+ result += valueXor & 1
721
+ valueXor = valueXor >> 1
722
+ }
723
+
724
+ return result
725
+ }
726
+
727
+ export function medianFilter(vector: number[], width: number) {
728
+ const filter = createMedianFilter(width)
729
+ const result = []
730
+
731
+ for (let i = 0; i < vector.length; i++) {
732
+ result.push(filter(vector[i]))
733
+ }
734
+
735
+ return result
736
+ }
737
+
738
+ export function createVectorArray(vectorCount: number, featureCount: number, initialValue = 0.0) {
739
+ const result: number[][] = new Array(vectorCount)
740
+
741
+ for (let i = 0; i < vectorCount; i++) {
742
+ result[i] = createVector(featureCount, initialValue)
743
+ }
744
+
745
+ return result
746
+ }
747
+
748
+ export function createVector(elementCount: number, initialValue = 0.0) {
749
+ const result: number[] = new Array(elementCount)
750
+
751
+ for (let i = 0; i < elementCount; i++) {
752
+ result[i] = initialValue
753
+ }
754
+
755
+ return result
756
+ }
757
+
758
+ export function createVectorForIntegerRange(start: number, end: number) {
759
+ const newVector: number[] = []
760
+
761
+ for (let i = start; i < end; i++) {
762
+ newVector.push(i)
763
+ }
764
+
765
+ return newVector
766
+ }
767
+
768
+ export function zeroIfNaN(val: number) {
769
+ if (isNaN(val)) {
770
+ return 0
771
+ } else {
772
+ return val
773
+ }
774
+ }
775
+
776
+ export function logSumExp(values: number[], minVal = 1e-40) {
777
+ return Math.log(minVal + sumExp(values))
778
+ }
779
+
780
+ export function sumExp(values: number[]) {
781
+ let sumOfExp = 0
782
+
783
+ for (const value of values) {
784
+ sumOfExp += Math.exp(value)
785
+ }
786
+
787
+ return sumOfExp
788
+ }
789
+
790
+ export function logSoftmax(values: number[], minVal = 1e-40) {
791
+ const softMaxOfValues = softmax(values)
792
+ return logOfVector(softMaxOfValues, minVal)
793
+ }
794
+
795
+ export class IncrementalMean {
796
+ currentElementCount = 0
797
+ currentMean = 0.0
798
+
799
+ addValueToMean(value: number) {
800
+ this.currentElementCount += 1
801
+ this.currentMean += (value + this.currentMean) / this.currentElementCount
802
+ }
803
+
804
+ // 1, 3.2, 7.23
805
+ // 0 + ((1 - 0) / 1) = 1
806
+ // 1 + ((3.2 - 1) / 2) = 2.1
807
+ // 2.1 + ((7.23 - 3.1) / 3) = 2.04
808
+
809
+ // 3.81
810
+ }
811
+
812
+ export type DistanceFunction = (a: number[], b: number[]) => number