Skip to content

Commit

Permalink
refactor(transducers-stats): replace thi.ng/dcons dependency
Browse files Browse the repository at this point in the history
- switch to use more lightweight & GC-friendly ringbuffer impl from thi.ng/buffers
- update the following transducers:
  - `momentum()`
  - `roc()`
  - `sma()`
- add tests
  • Loading branch information
postspectacular committed Dec 24, 2024
1 parent a4b96c6 commit e9940ed
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 26 deletions.
4 changes: 2 additions & 2 deletions packages/transducers-stats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ For Node.js REPL:
const ts = await import("@thi.ng/transducers-stats");
```

Package sizes (brotli'd, pre-treeshake): ESM: 1.75 KB
Package sizes (brotli'd, pre-treeshake): ESM: 1.74 KB

## Dependencies

- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
- [@thi.ng/buffers](https://github.com/thi-ng/umbrella/tree/develop/packages/buffers)
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
- [@thi.ng/dcons](https://github.com/thi-ng/umbrella/tree/develop/packages/dcons)
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)

Expand Down
2 changes: 1 addition & 1 deletion packages/transducers-stats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
},
"dependencies": {
"@thi.ng/api": "^8.11.14",
"@thi.ng/buffers": "^0.1.17",
"@thi.ng/checks": "^3.6.16",
"@thi.ng/dcons": "^3.2.134",
"@thi.ng/errors": "^2.5.20",
"@thi.ng/transducers": "^9.2.10"
},
Expand Down
13 changes: 6 additions & 7 deletions packages/transducers-stats/src/momentum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DCons } from "@thi.ng/dcons/dcons";
import { sliding } from "@thi.ng/buffers/sliding";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import type { Reducer, Transducer } from "@thi.ng/transducers";
import { compR } from "@thi.ng/transducers/compr";
Expand Down Expand Up @@ -27,14 +27,13 @@ export function momentum(period: number, src?: Iterable<number>): any {
period < 1 && illegalArgs("period must be >= 1");
return (rfn: Reducer<number, any>) => {
const reduce = rfn[2];
const window = new DCons<number>();
const window = sliding<number>(period);
return compR(rfn, (acc, x: number) => {
window.push(x);
if (window.length <= period) {
return acc;
if (window.length === period) {
acc = reduce(acc, x - window.read());
}
const prev = window.drop()!;
return reduce(acc, x - prev);
window.write(x);
return acc;
});
};
}
15 changes: 8 additions & 7 deletions packages/transducers-stats/src/roc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DCons } from "@thi.ng/dcons/dcons";
import { sliding } from "@thi.ng/buffers/sliding";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import type { Reducer, Transducer } from "@thi.ng/transducers";
import { compR } from "@thi.ng/transducers/compr";
Expand All @@ -24,17 +24,18 @@ export function roc(period: number, src?: Iterable<number>): any {
if (src) {
return iterator1(roc(period), src);
}
period |= 0;
period < 1 && illegalArgs("period must be >= 1");
return (rfn: Reducer<number, any>) => {
const reduce = rfn[2];
const window = new DCons<number>();
const window = sliding<number>(period);
return compR(rfn, (acc, x: number) => {
window.push(x);
if (window.length <= period) {
return acc;
if (window.length === period) {
const prev = window.read();
acc = reduce(acc, (x - prev) / prev);
}
const prev = window.drop()!;
return reduce(acc, (x - prev) / prev);
window.write(x);
return acc;
});
};
}
15 changes: 8 additions & 7 deletions packages/transducers-stats/src/sma.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DCons } from "@thi.ng/dcons/dcons";
import { sliding } from "@thi.ng/buffers/sliding";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import type { Reducer, Transducer } from "@thi.ng/transducers";
import { compR } from "@thi.ng/transducers/compr";
Expand All @@ -24,17 +24,18 @@ export function sma(period: number, src?: Iterable<number>): any {
return iterator1(sma(period), src);
}
period |= 0;
period < 2 && illegalArgs("period must be >= 2");
period < 1 && illegalArgs("period must be >= 1");
return (rfn: Reducer<number, any>) => {
const reduce = rfn[2];
const window = new DCons<number>();
const window = sliding<number>(period);
let sum = 0;
return compR(rfn, (acc, x: number) => {
window.push(x);
const n = window.length;
if (window.length === period) {
sum -= window.read();
}
window.write(x);
sum += x;
n > period && (sum -= window.drop()!);
return n >= period ? reduce(acc, sum / period) : acc;
return window.length === period ? reduce(acc, sum / period) : acc;
});
};
}
39 changes: 38 additions & 1 deletion packages/transducers-stats/test/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { expect, test } from "bun:test";
import { donchian, movingMaximum, movingMinimum } from "../src/index.js";
import {
donchian,
momentum,
movingMaximum,
movingMinimum,
roc,
sma,
} from "../src/index.js";

test("movingMaxium", () => {
expect([...movingMaximum(3, [1, 3, 1, 1, 4, 1, 1, 2, 5, 6])]).toEqual([
Expand All @@ -25,3 +32,33 @@ test("donchian", () => {
[2, 6],
]);
});

test("momentum", () => {
expect(() => momentum(0)).toThrow();
expect([...momentum(4, [1, 2, 3, 4, 5, 6, 7, 8, 9])]).toEqual([
4, 4, 4, 4, 4,
]);
});

test("roc", () => {
expect(() => roc(0)).toThrow();
expect([...roc(4, [1, 2, 3, 4, 5, 6, 7, 8, 9])]).toEqual([
4 / 1,
4 / 2,
4 / 3,
4 / 4,
4 / 5,
]);
});

test("sma", () => {
expect(() => sma(0)).toThrow();
expect([...sma(4, [1, 2, 3, 4, 5, 6, 7, 8, 9])]).toEqual([
(1 + 2 + 3 + 4) / 4,
(2 + 3 + 4 + 5) / 4,
(3 + 4 + 5 + 6) / 4,
(4 + 5 + 6 + 7) / 4,
(5 + 6 + 7 + 8) / 4,
(6 + 7 + 8 + 9) / 4,
]);
});
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6780,8 +6780,8 @@ __metadata:
dependencies:
"@microsoft/api-extractor": "npm:^7.48.0"
"@thi.ng/api": "npm:^8.11.14"
"@thi.ng/buffers": "npm:^0.1.17"
"@thi.ng/checks": "npm:^3.6.16"
"@thi.ng/dcons": "npm:^3.2.134"
"@thi.ng/errors": "npm:^2.5.20"
"@thi.ng/transducers": "npm:^9.2.10"
esbuild: "npm:^0.24.0"
Expand Down

0 comments on commit e9940ed

Please sign in to comment.