dsp-collection 0.2.5 → 0.2.7

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 (86) hide show
  1. package/README.md +6 -2
  2. package/filter/FirFilterWin.d.ts +8 -0
  3. package/filter/FirFilterWin.d.ts.map +1 -0
  4. package/filter/FirFilterWin.js +55 -0
  5. package/filter/FirFilterWin.js.map +1 -0
  6. package/filter/SpecFilt.d.ts +11 -10
  7. package/filter/SpecFilt.d.ts.map +1 -0
  8. package/filter/SpecFilt.js +98 -98
  9. package/filter/SpecFilt.js.map +1 -1
  10. package/math/Complex.d.ts +43 -42
  11. package/math/Complex.d.ts.map +1 -0
  12. package/math/Complex.js +130 -129
  13. package/math/Complex.js.map +1 -1
  14. package/math/ComplexArray.d.ts +37 -36
  15. package/math/ComplexArray.d.ts.map +1 -0
  16. package/math/ComplexArray.js +170 -170
  17. package/math/ComplexArray.js.map +1 -1
  18. package/math/MathUtils.d.ts +10 -7
  19. package/math/MathUtils.d.ts.map +1 -0
  20. package/math/MathUtils.js +116 -81
  21. package/math/MathUtils.js.map +1 -1
  22. package/math/MutableComplex.d.ts +24 -22
  23. package/math/MutableComplex.d.ts.map +1 -0
  24. package/math/MutableComplex.js +68 -64
  25. package/math/MutableComplex.js.map +1 -1
  26. package/math/NumApprox.d.ts +4 -3
  27. package/math/NumApprox.d.ts.map +1 -0
  28. package/math/NumApprox.js +67 -67
  29. package/math/NumApprox.js.map +1 -1
  30. package/math/PolyReal.d.ts +14 -13
  31. package/math/PolyReal.d.ts.map +1 -0
  32. package/math/PolyReal.js +226 -226
  33. package/math/PolyReal.js.map +1 -1
  34. package/package.json +11 -3
  35. package/signal/AdaptiveStft.d.ts +13 -12
  36. package/signal/AdaptiveStft.d.ts.map +1 -0
  37. package/signal/AdaptiveStft.js +57 -57
  38. package/signal/AdaptiveStft.js.map +1 -1
  39. package/signal/Autocorrelation.d.ts +6 -5
  40. package/signal/Autocorrelation.d.ts.map +1 -0
  41. package/signal/Autocorrelation.js +53 -53
  42. package/signal/Autocorrelation.js.map +1 -1
  43. package/signal/Dft.d.ts +10 -9
  44. package/signal/Dft.d.ts.map +1 -0
  45. package/signal/Dft.js +87 -87
  46. package/signal/Dft.js.map +1 -1
  47. package/signal/EnvelopeDetection.d.ts +2 -1
  48. package/signal/EnvelopeDetection.d.ts.map +1 -0
  49. package/signal/EnvelopeDetection.js +9 -9
  50. package/signal/EnvelopeDetection.js.map +1 -1
  51. package/signal/Fft.d.ts +10 -9
  52. package/signal/Fft.d.ts.map +1 -0
  53. package/signal/Fft.js +275 -275
  54. package/signal/Fft.js.map +1 -1
  55. package/signal/Goertzel.d.ts +6 -5
  56. package/signal/Goertzel.d.ts.map +1 -0
  57. package/signal/Goertzel.js +48 -48
  58. package/signal/Goertzel.js.map +1 -1
  59. package/signal/InstFreq.d.ts +9 -8
  60. package/signal/InstFreq.d.ts.map +1 -0
  61. package/signal/InstFreq.js +26 -26
  62. package/signal/InstFreq.js.map +1 -1
  63. package/signal/PitchDetectionHarm.d.ts +27 -26
  64. package/signal/PitchDetectionHarm.d.ts.map +1 -0
  65. package/signal/PitchDetectionHarm.js +72 -68
  66. package/signal/PitchDetectionHarm.js.map +1 -1
  67. package/signal/Resampling.d.ts +8 -7
  68. package/signal/Resampling.d.ts.map +1 -0
  69. package/signal/Resampling.js +218 -218
  70. package/signal/Resampling.js.map +1 -1
  71. package/signal/WindowFunctions.d.ts +42 -40
  72. package/signal/WindowFunctions.d.ts.map +1 -0
  73. package/signal/WindowFunctions.js +194 -194
  74. package/signal/WindowFunctions.js.map +1 -1
  75. package/utils/ArrayUtils.d.ts +10 -9
  76. package/utils/ArrayUtils.d.ts.map +1 -0
  77. package/utils/ArrayUtils.js +68 -68
  78. package/utils/ArrayUtils.js.map +1 -1
  79. package/utils/DspUtils.d.ts +5 -2
  80. package/utils/DspUtils.d.ts.map +1 -0
  81. package/utils/DspUtils.js +12 -6
  82. package/utils/DspUtils.js.map +1 -1
  83. package/utils/MiscUtils.d.ts +7 -6
  84. package/utils/MiscUtils.d.ts.map +1 -0
  85. package/utils/MiscUtils.js +20 -20
  86. package/utils/MiscUtils.js.map +1 -1
package/README.md CHANGED
@@ -1,9 +1,11 @@
1
- # The source-code.biz JavaScript DSP Collection
1
+ # The JavaScript DSP Collection
2
2
 
3
3
  A collection of JavaScript modules for digital signal processing (written in TypeScript).
4
4
 
5
5
  (This package is currently in development)
6
6
 
7
+ NPM package: [dsp-collection](https://www.npmjs.com/package/dsp-collection)
8
+
7
9
  ## Online test applications
8
10
 
9
11
  * [Window functions test](https://www.source-code.biz/dsp/js/simpleTests/testWindowFunctions.html)
@@ -13,12 +15,14 @@ A collection of JavaScript modules for digital signal processing (written in Typ
13
15
 
14
16
  * [HarmSyn - Harmonic synthesizer](https://www.source-code.biz/harmSyn)
15
17
  * [KlattSyn - Klatt formant synthesizer](https://www.source-code.biz/klattSyn)
18
+ * [NoiseSyn - Spectral noise synthesizer](https://www.source-code.biz/noiseSyn)
16
19
  * [SinSyn - Sinusoidal synthesizer](https://www.source-code.biz/sinSyn)
17
20
  * [SpecFilt - Spectral filter tool](https://www.source-code.biz/specFilt)
18
21
 
19
22
  ## Associated JavaScript packages
20
23
 
21
- * [commons-math-interpolation - Interpolation and regression algorithms](https://github.com/chdh/commons-math-interpolation)
24
+ * [commons-math-interpolation](https://github.com/chdh/commons-math-interpolation) - Interpolation and regression algorithms
22
25
  * [Function curve editor widget](https://www.source-code.biz/snippets/typescript/functionCurveEditor)
23
26
  * [Function curve viewer widget](https://www.source-code.biz/snippets/typescript/functionCurveViewer)
24
27
  * [WAV file encoder](https://github.com/chdh/wav-file-encoder)
28
+ * [WAV file decoder](https://github.com/chdh/wav-file-decoder)
@@ -0,0 +1,8 @@
1
+ import MutableComplex from "../math/MutableComplex.ts";
2
+ import { WindowFunction } from "../signal/WindowFunctions.ts";
3
+ export declare function createWindowKernel(f: WindowFunction, width: number, symetric?: boolean): Float64Array;
4
+ export declare function createLpFilterKernel(windowFunctionId: string, normFirstMinFreq: number): Float64Array;
5
+ export declare function calcFreqRespAt(kernel: ArrayLike<number>, normFreq: number): MutableComplex;
6
+ export declare function applyFirKernelAt(signal: ArrayLike<number>, pos: number, kernel: ArrayLike<number>): number;
7
+ export declare function applyFirKernel(signal: ArrayLike<number>, kernel: Float64Array): Float64Array;
8
+ //# sourceMappingURL=FirFilterWin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FirFilterWin.d.ts","sourceRoot":"","sources":["../../src/filter/FirFilterWin.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,MAAM,2BAA2B,CAAC;AAEvD,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAM5D,wBAAgB,kBAAkB,CAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAc,GAAI,YAAY,CAK/F;AAKf,wBAAgB,oBAAoB,CAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAI,YAAY,CAKzD;AAI/C,wBAAgB,cAAc,CAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAEhD;AAY5C,wBAAgB,gBAAgB,CAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAI,MAAM,CAU7F;AAGhB,wBAAgB,cAAc,CAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,GAAI,YAAY,CAI/E"}
@@ -0,0 +1,55 @@
1
+ import * as WindowFunctions from "../signal/WindowFunctions.js";
2
+ import { goertzelSingle } from "../signal/Goertzel.js";
3
+ import * as ArrayUtils from "../utils/ArrayUtils.js";
4
+ export function createWindowKernel(f, width, symetric = true) {
5
+ const nudge = symetric ? 1 : 0;
6
+ const a1 = Float64Array.from({ length: width }, (_x, i) => f(i / (width - nudge)));
7
+ const sum = ArrayUtils.sum(a1);
8
+ const a2 = a1.map(x => x / sum);
9
+ return a2;
10
+ }
11
+ export function createLpFilterKernel(windowFunctionId, normFirstMinFreq) {
12
+ const descr = WindowFunctions.getFunctionDescrById(windowFunctionId);
13
+ const width = Math.round(descr.firstMinPos / normFirstMinFreq);
14
+ if (width < 3) {
15
+ throw new Error("Filter parameters out of range.");
16
+ }
17
+ return createWindowKernel(descr.f, width);
18
+ }
19
+ export function calcFreqRespAt(kernel, normFreq) {
20
+ const relFreq = normFreq * kernel.length;
21
+ return goertzelSingle(kernel, relFreq);
22
+ }
23
+ function reflectIndex(i, n) {
24
+ if (i >= 0 && i < n) {
25
+ return i;
26
+ }
27
+ if (n <= 1) {
28
+ return 0;
29
+ }
30
+ const period = 2 * (n - 1);
31
+ const t = (i % period + period) % period;
32
+ return (t < n) ? t : period - t;
33
+ }
34
+ export function applyFirKernelAt(signal, pos, kernel) {
35
+ if (pos < 0 || pos >= signal.length) {
36
+ return NaN;
37
+ }
38
+ const width = kernel.length;
39
+ const m = Math.floor(kernel.length / 2);
40
+ const p0 = pos - m;
41
+ let acc = 0;
42
+ for (let i = 0; i < width; i++) {
43
+ const p = reflectIndex(p0 + i, signal.length);
44
+ acc += signal[p] * kernel[i];
45
+ }
46
+ return acc;
47
+ }
48
+ export function applyFirKernel(signal, kernel) {
49
+ const out = new Float64Array(signal.length);
50
+ for (let i = 0; i < signal.length; i++) {
51
+ out[i] = applyFirKernelAt(signal, i, kernel);
52
+ }
53
+ return out;
54
+ }
55
+ //# sourceMappingURL=FirFilterWin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FirFilterWin.js","sourceRoot":"","sources":["../../src/filter/FirFilterWin.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- export declare const enum FilterType {
2
- lowPass = "LP",
3
- highPass = "HP",
4
- bandPass = "BP",
5
- bandStop = "BS"
6
- }
7
- export declare type FilterCurveFunction = (frequency: number) => number;
8
- export declare function getFilterCurveFunction(filterType: FilterType, filterFreq1: number, filterFreq2: number, smoothingWidth: number): FilterCurveFunction;
9
- export declare function applyFilterCurveFunction(inAmplitudes: ArrayLike<number>, scalingFactor: number, filterCurveFunction: FilterCurveFunction): Float64Array;
10
- export declare function filterSignal(inSamples: ArrayLike<number>, sampleRate: number, filterType: FilterType, filterFreq1: number, filterFreq2: number, smoothingWidth: number): Float64Array;
1
+ export declare const enum FilterType {
2
+ lowPass = "LP",
3
+ highPass = "HP",
4
+ bandPass = "BP",
5
+ bandStop = "BS"
6
+ }
7
+ export type FilterCurveFunction = (frequency: number) => number;
8
+ export declare function getFilterCurveFunction(filterType: FilterType, filterFreq1: number, filterFreq2: number, smoothingWidth: number): FilterCurveFunction;
9
+ export declare function applyFilterCurveFunction(inAmplitudes: ArrayLike<number>, scalingFactor: number, filterCurveFunction: FilterCurveFunction): Float64Array<ArrayBuffer>;
10
+ export declare function filterSignal(inSamples: ArrayLike<number>, sampleRate: number, filterType: FilterType, filterFreq1: number, filterFreq2: number, smoothingWidth: number): Float64Array;
11
+ //# sourceMappingURL=SpecFilt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpecFilt.d.ts","sourceRoot":"","sources":["../../src/filter/SpecFilt.ts"],"names":[],"mappings":"AASA,0BAAkB,UAAU;IACzB,OAAO,OAAQ;IACf,QAAQ,OAAO;IACf,QAAQ,OAAO;IACf,QAAQ,OAAO;CAAE;AAEpB,MAAM,MAAM,mBAAmB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;AAoBhE,wBAAgB,sBAAsB,CAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAI,mBAAmB,CA2C9F;AAKzD,wBAAgB,wBAAwB,CAAE,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,6BAOhH;AAwB1B,wBAAgB,YAAY,CAAE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAI,YAAY,CAUlK"}
@@ -1,99 +1,99 @@
1
- import ComplexArray from "../math/ComplexArray.js";
2
- import * as Fft from "../signal/Fft.js";
3
- function smoothingFunction(x) {
4
- return (Math.sin(x * Math.PI / 2) + 1) / 2;
5
- }
6
- export function getFilterCurveFunction(filterType, filterFreq1, filterFreq2, smoothingWidth) {
7
- switch (filterType) {
8
- case "LP": {
9
- return (freq) => {
10
- if (freq < filterFreq1 - smoothingWidth) {
11
- return 1;
12
- }
13
- else if (freq < filterFreq1 + smoothingWidth) {
14
- return smoothingFunction((filterFreq1 - freq) / smoothingWidth);
15
- }
16
- else {
17
- return 0;
18
- }
19
- };
20
- }
21
- case "HP": {
22
- return (freq) => {
23
- if (freq < filterFreq1 - smoothingWidth) {
24
- return 0;
25
- }
26
- else if (freq < filterFreq1 + smoothingWidth) {
27
- return smoothingFunction((freq - filterFreq1) / smoothingWidth);
28
- }
29
- else {
30
- return 1;
31
- }
32
- };
33
- }
34
- case "BP": {
35
- return (freq) => {
36
- if (freq < filterFreq1 - smoothingWidth) {
37
- return 0;
38
- }
39
- else if (freq < filterFreq1 + smoothingWidth) {
40
- return smoothingFunction((freq - filterFreq1) / smoothingWidth);
41
- }
42
- else if (freq < filterFreq2 - smoothingWidth) {
43
- return 1;
44
- }
45
- else if (freq < filterFreq2 + smoothingWidth) {
46
- return smoothingFunction((filterFreq2 - freq) / smoothingWidth);
47
- }
48
- else {
49
- return 0;
50
- }
51
- };
52
- }
53
- case "BS": {
54
- return (freq) => {
55
- if (freq < filterFreq1 - smoothingWidth) {
56
- return 1;
57
- }
58
- else if (freq < filterFreq1 + smoothingWidth) {
59
- return smoothingFunction((filterFreq1 - freq) / smoothingWidth);
60
- }
61
- else if (freq < filterFreq2 - smoothingWidth) {
62
- return 0;
63
- }
64
- else if (freq < filterFreq2 + smoothingWidth) {
65
- return smoothingFunction((freq - filterFreq2) / smoothingWidth);
66
- }
67
- else {
68
- return 1;
69
- }
70
- };
71
- }
72
- default: {
73
- throw new Error("Unsupported filter type.");
74
- }
75
- }
76
- }
77
- export function applyFilterCurveFunction(inAmplitudes, scalingFactor, filterCurveFunction) {
78
- const n = inAmplitudes.length;
79
- const outAmplitudes = new Float64Array(n);
80
- for (let p = 0; p < n; p++) {
81
- const frequency = p / scalingFactor;
82
- const filterFactor = filterCurveFunction(frequency);
83
- outAmplitudes[p] = filterFactor * inAmplitudes[p];
84
- }
85
- return outAmplitudes;
86
- }
87
- export function filterSignal(inSamples, sampleRate, filterType, filterFreq1, filterFreq2, smoothingWidth) {
88
- const n = inSamples.length;
89
- const inSpectrum = Fft.fftRealSpectrum(inSamples);
90
- const inAmplitudes = inSpectrum.getAbsArray();
91
- const inPhases = inSpectrum.getArgArray();
92
- const filterCurveFunction = getFilterCurveFunction(filterType, filterFreq1, filterFreq2, smoothingWidth);
93
- const outAmplitudes = applyFilterCurveFunction(inAmplitudes, n / sampleRate, filterCurveFunction);
94
- const outPhases = inPhases;
95
- const outSpectrum = ComplexArray.fromPolar(outAmplitudes, outPhases);
96
- const outSignal = Fft.iFftRealHalf(outSpectrum, n);
97
- return outSignal;
98
- }
1
+ import ComplexArray from "../math/ComplexArray.js";
2
+ import * as Fft from "../signal/Fft.js";
3
+ function smoothingFunction(x) {
4
+ return (Math.sin(x * Math.PI / 2) + 1) / 2;
5
+ }
6
+ export function getFilterCurveFunction(filterType, filterFreq1, filterFreq2, smoothingWidth) {
7
+ switch (filterType) {
8
+ case "LP": {
9
+ return (freq) => {
10
+ if (freq < filterFreq1 - smoothingWidth) {
11
+ return 1;
12
+ }
13
+ else if (freq < filterFreq1 + smoothingWidth) {
14
+ return smoothingFunction((filterFreq1 - freq) / smoothingWidth);
15
+ }
16
+ else {
17
+ return 0;
18
+ }
19
+ };
20
+ }
21
+ case "HP": {
22
+ return (freq) => {
23
+ if (freq < filterFreq1 - smoothingWidth) {
24
+ return 0;
25
+ }
26
+ else if (freq < filterFreq1 + smoothingWidth) {
27
+ return smoothingFunction((freq - filterFreq1) / smoothingWidth);
28
+ }
29
+ else {
30
+ return 1;
31
+ }
32
+ };
33
+ }
34
+ case "BP": {
35
+ return (freq) => {
36
+ if (freq < filterFreq1 - smoothingWidth) {
37
+ return 0;
38
+ }
39
+ else if (freq < filterFreq1 + smoothingWidth) {
40
+ return smoothingFunction((freq - filterFreq1) / smoothingWidth);
41
+ }
42
+ else if (freq < filterFreq2 - smoothingWidth) {
43
+ return 1;
44
+ }
45
+ else if (freq < filterFreq2 + smoothingWidth) {
46
+ return smoothingFunction((filterFreq2 - freq) / smoothingWidth);
47
+ }
48
+ else {
49
+ return 0;
50
+ }
51
+ };
52
+ }
53
+ case "BS": {
54
+ return (freq) => {
55
+ if (freq < filterFreq1 - smoothingWidth) {
56
+ return 1;
57
+ }
58
+ else if (freq < filterFreq1 + smoothingWidth) {
59
+ return smoothingFunction((filterFreq1 - freq) / smoothingWidth);
60
+ }
61
+ else if (freq < filterFreq2 - smoothingWidth) {
62
+ return 0;
63
+ }
64
+ else if (freq < filterFreq2 + smoothingWidth) {
65
+ return smoothingFunction((freq - filterFreq2) / smoothingWidth);
66
+ }
67
+ else {
68
+ return 1;
69
+ }
70
+ };
71
+ }
72
+ default: {
73
+ throw new Error("Unsupported filter type.");
74
+ }
75
+ }
76
+ }
77
+ export function applyFilterCurveFunction(inAmplitudes, scalingFactor, filterCurveFunction) {
78
+ const n = inAmplitudes.length;
79
+ const outAmplitudes = new Float64Array(n);
80
+ for (let p = 0; p < n; p++) {
81
+ const frequency = p / scalingFactor;
82
+ const filterFactor = filterCurveFunction(frequency);
83
+ outAmplitudes[p] = filterFactor * inAmplitudes[p];
84
+ }
85
+ return outAmplitudes;
86
+ }
87
+ export function filterSignal(inSamples, sampleRate, filterType, filterFreq1, filterFreq2, smoothingWidth) {
88
+ const n = inSamples.length;
89
+ const inSpectrum = Fft.fftRealSpectrum(inSamples);
90
+ const inAmplitudes = inSpectrum.getAbsArray();
91
+ const inPhases = inSpectrum.getArgArray();
92
+ const filterCurveFunction = getFilterCurveFunction(filterType, filterFreq1, filterFreq2, smoothingWidth);
93
+ const outAmplitudes = applyFilterCurveFunction(inAmplitudes, n / sampleRate, filterCurveFunction);
94
+ const outPhases = inPhases;
95
+ const outSpectrum = ComplexArray.fromPolar(outAmplitudes, outPhases);
96
+ const outSignal = Fft.iFftRealHalf(outSpectrum, n);
97
+ return outSignal;
98
+ }
99
99
  //# sourceMappingURL=SpecFilt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpecFilt.js","sourceRoot":"","sources":["../../src/filter/SpecFilt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SpecFilt.js","sourceRoot":"","sources":["../../src/filter/SpecFilt.ts"],"names":[],"mappings":"AAMA,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAWxC,SAAS,iBAAiB,CAAE,CAAS;IAClC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAAC,CAAC;AAgBhD,MAAM,UAAU,sBAAsB,CAAE,UAAsB,EAAE,WAAmB,EAAE,WAAmB,EAAE,cAAsB;IAC7H,QAAQ,UAAU,EAAE,CAAC;QAClB,SAAuB,CAAC,CAAC,CAAC;YACvB,OAAO,CAAC,IAAY,EAAE,EAAE;gBACrB,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBACvC,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,CAAC;oBACJ,OAAO,CAAC,CAAC;gBAAC,CAAC;YAAA,CAAC,CAAC;QAAC,CAAC;QACxB,SAAwB,CAAC,CAAC,CAAC;YACxB,OAAO,CAAC,IAAY,EAAE,EAAE;gBACrB,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBACvC,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,CAAC;oBACJ,OAAO,CAAC,CAAC;gBAAC,CAAC;YAAA,CAAC,CAAC;QAAC,CAAC;QACxB,SAAwB,CAAC,CAAC,CAAC;YACxB,OAAO,CAAC,IAAY,EAAE,EAAE;gBACrB,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBACvC,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,CAAC;oBACJ,OAAO,CAAC,CAAC;gBAAC,CAAC;YAAA,CAAC,CAAC;QAAC,CAAC;QACxB,SAAwB,CAAC,CAAC,CAAC;YACxB,OAAO,CAAC,IAAY,EAAE,EAAE;gBACrB,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBACvC,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,CAAC,CAAC;gBAAC,CAAC;qBACR,IAAI,IAAI,GAAG,WAAW,GAAG,cAAc,EAAE,CAAC;oBAC7C,OAAO,iBAAiB,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC;gBAAC,CAAC;qBAC/D,CAAC;oBACJ,OAAO,CAAC,CAAC;gBAAC,CAAC;YAAA,CAAC,CAAC;QAAC,CAAC;QACxB,OAAO,CAAC,CAAC,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAAC,CAAC;IAAA,CAAC;AAAA,CAAC;AAKzD,MAAM,UAAU,wBAAwB,CAAE,YAA+B,EAAE,aAAqB,EAAE,mBAAwC;IACvI,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;IAC9B,MAAM,aAAa,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,CAAC,GAAG,aAAa,CAAC;QACpC,MAAM,YAAY,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACpD,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IACvD,OAAO,aAAa,CAAC;AAAC,CAAC;AAwB1B,MAAM,UAAU,YAAY,CAAE,SAA4B,EAAE,UAAkB,EAAE,UAAsB,EAAE,WAAmB,EAAE,WAAmB,EAAE,cAAsB;IACrK,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;IAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACzG,MAAM,aAAa,GAAG,wBAAwB,CAAC,YAAY,EAAE,CAAC,GAAG,UAAU,EAAE,mBAAmB,CAAC,CAAC;IAClG,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC3B,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACnD,OAAO,SAAS,CAAC;AAAC,CAAC"}
package/math/Complex.d.ts CHANGED
@@ -1,42 +1,43 @@
1
- export default class Complex {
2
- static readonly I: Complex;
3
- static readonly ZERO: Complex;
4
- static readonly ONE: Complex;
5
- static readonly TWO: Complex;
6
- static readonly NaN: Complex;
7
- static readonly INFINITY: Complex;
8
- readonly re: number;
9
- readonly im: number;
10
- constructor(re: number, im?: number);
11
- toString(): string;
12
- toNumber(eps: number): number;
13
- isNaN(): boolean;
14
- isInfinite(): boolean;
15
- isFinite(): boolean;
16
- equals(x: Complex): boolean;
17
- fuzzyEquals(x: Complex, eps: number): boolean;
18
- static expj(arg: number): Complex;
19
- static fromPolar(abs: number, arg: number): Complex;
20
- abs(): number;
21
- arg(): number;
22
- conj(): Complex;
23
- neg(): Complex;
24
- reciprocal(): Complex;
25
- exp(): Complex;
26
- log(): Complex;
27
- sqr(): Complex;
28
- sqrt(): Complex;
29
- addReal(x: number): Complex;
30
- add(x: Complex): Complex;
31
- subReal(x: number): Complex;
32
- static subFromReal(x: number, y: Complex): Complex;
33
- sub(x: Complex): Complex;
34
- mulReal(x: number): Complex;
35
- mul(x: Complex): Complex;
36
- divReal(x: number): Complex;
37
- div(x: Complex): Complex;
38
- static divFromReal(x: number, y: Complex): Complex;
39
- powInt(x: number): Complex;
40
- powReal(x: number): Complex;
41
- pow(x: Complex): Complex;
42
- }
1
+ export default class Complex {
2
+ static readonly I: Complex;
3
+ static readonly ZERO: Complex;
4
+ static readonly ONE: Complex;
5
+ static readonly TWO: Complex;
6
+ static readonly NaN: Complex;
7
+ static readonly INFINITY: Complex;
8
+ readonly re: number;
9
+ readonly im: number;
10
+ constructor(re: number, im?: number);
11
+ toString(): string;
12
+ toNumber(eps: number): number;
13
+ isNaN(): boolean;
14
+ isInfinite(): boolean;
15
+ isFinite(): boolean;
16
+ equals(x: Complex): boolean;
17
+ fuzzyEquals(x: Complex, eps: number): boolean;
18
+ static expj(arg: number): Complex;
19
+ static fromPolar(abs: number, arg: number): Complex;
20
+ abs(): number;
21
+ arg(): number;
22
+ conj(): Complex;
23
+ neg(): Complex;
24
+ reciprocal(): Complex;
25
+ exp(): Complex;
26
+ log(): Complex;
27
+ sqr(): Complex;
28
+ sqrt(): Complex;
29
+ addReal(x: number): Complex;
30
+ add(x: Complex): Complex;
31
+ subReal(x: number): Complex;
32
+ static subFromReal(x: number, y: Complex): Complex;
33
+ sub(x: Complex): Complex;
34
+ mulReal(x: number): Complex;
35
+ mul(x: Complex): Complex;
36
+ divReal(x: number): Complex;
37
+ div(x: Complex): Complex;
38
+ static divFromReal(x: number, y: Complex): Complex;
39
+ powInt(x: number): Complex;
40
+ powReal(x: number): Complex;
41
+ pow(x: Complex): Complex;
42
+ }
43
+ //# sourceMappingURL=Complex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Complex.d.ts","sourceRoot":"","sources":["../../src/math/Complex.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,OAAO,OAAO;IAOzB,gBAAuB,CAAC,UAAqB;IAG7C,gBAAuB,IAAI,UAAkB;IAG7C,gBAAuB,GAAG,UAAkB;IAG5C,gBAAuB,GAAG,UAAkB;IAG5C,gBAAuB,GAAG,UAAyB;IAGnD,gBAAuB,QAAQ,UAAmC;IAOlE,SAAgB,EAAE,EAAE,MAAM,CAAC;IAG3B,SAAgB,EAAE,EAAE,MAAM,CAAC;gBAYP,EAAE,EAAE,MAAM,EAAE,EAAE,GAAE,MAAU;IASvC,QAAQ,IAAK,MAAM;IAOnB,QAAQ,CAAE,GAAG,EAAE,MAAM,GAAI,MAAM;IAS/B,KAAK,IAAK,OAAO;IAMjB,UAAU;IAMV,QAAQ;IAMR,MAAM,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAO7B,WAAW,CAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAI,OAAO;WAQxC,IAAI,CAAE,GAAG,EAAE,MAAM,GAAI,OAAO;WAM5B,SAAS,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAI,OAAO;IAQrD,GAAG,IAAK,MAAM;IAMd,GAAG,IAAK,MAAM;IAMd,IAAI,IAAK,OAAO;IAMhB,GAAG,IAAK,OAAO;IAMf,UAAU,IAAK,OAAO;IActB,GAAG,IAAK,OAAO;IAMf,GAAG,IAAK,OAAO;IAMf,GAAG,IAAK,OAAO;IAMf,IAAI,IAAK,OAAO;IAWhB,OAAO,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;IAM7B,GAAG,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAM1B,OAAO,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;WAMtB,WAAW,CAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAMpD,GAAG,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAM1B,OAAO,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;IAM7B,GAAG,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAM1B,OAAO,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;IAM7B,GAAG,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;WAOnB,WAAW,CAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAI,OAAO;IAOpD,MAAM,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;IAQ5B,OAAO,CAAE,CAAC,EAAE,MAAM,GAAI,OAAO;IAM7B,GAAG,CAAE,CAAC,EAAE,OAAO,GAAI,OAAO;CAGhC"}