catniff 0.1.1 → 0.1.2
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.
- package/README.md +19 -6
- package/dist/tensor.d.ts +1 -0
- package/dist/tensor.js +25 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# Catniff
|
|
2
2
|
|
|
3
3
|
Catniff is a small and experimental tensor library and autograd engine inspired by [micrograd](https://github.com/karpathy/micrograd). The name is a play on "catnip" and "differentiation".
|
|
4
4
|
|
|
@@ -41,13 +41,26 @@ All available APIs are in `./src/tensor.ts`.
|
|
|
41
41
|
|
|
42
42
|
To compute the gradient of our mathematical expression, we use the `Node` class to dynamically build our DAG:
|
|
43
43
|
```js
|
|
44
|
-
const { Node } = require("
|
|
44
|
+
const { Node } = require("../index");
|
|
45
45
|
|
|
46
|
-
const X = new Node([
|
|
47
|
-
|
|
46
|
+
const X = new Node([
|
|
47
|
+
[ 0.5, -1.0 ],
|
|
48
|
+
[ 2.0, 0.0 ]
|
|
49
|
+
]);
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const Y = new Node([
|
|
52
|
+
[ 1.0, -2.0 ],
|
|
53
|
+
[ 0.5, 1.5 ]
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
const D = X.sub(Y);
|
|
57
|
+
const E = D.exp();
|
|
58
|
+
const F = E.add(1);
|
|
59
|
+
const G = F.log();
|
|
60
|
+
|
|
61
|
+
G.backward();
|
|
62
|
+
|
|
63
|
+
console.log(X.grad, Y.grad);
|
|
51
64
|
```
|
|
52
65
|
|
|
53
66
|
All available APIs are in `./src/autograd.ts`.
|
package/dist/tensor.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class TensorMath {
|
|
|
11
11
|
static lt(tA: Tensor, tB: Tensor): Tensor;
|
|
12
12
|
static ge(tA: Tensor, tB: Tensor): Tensor;
|
|
13
13
|
static le(tA: Tensor, tB: Tensor): Tensor;
|
|
14
|
+
static eq(tA: Tensor, tB: Tensor): Tensor;
|
|
14
15
|
static neg(tA: Tensor): Tensor;
|
|
15
16
|
static exp(tA: Tensor): Tensor;
|
|
16
17
|
static log(tA: Tensor): Tensor;
|
package/dist/tensor.js
CHANGED
|
@@ -247,6 +247,31 @@ class TensorMath {
|
|
|
247
247
|
}
|
|
248
248
|
throw new Error("Inputs are not tensors");
|
|
249
249
|
}
|
|
250
|
+
static eq(tA, tB) {
|
|
251
|
+
if (typeof tA === "number" && typeof tB === "number") {
|
|
252
|
+
return tA === tB ? 1 : 0;
|
|
253
|
+
}
|
|
254
|
+
else if (Array.isArray(tA) && Array.isArray(tB)) {
|
|
255
|
+
const outLen = Math.max(tA.length, tB.length);
|
|
256
|
+
if (tA.length !== tB.length && tA.length !== 1 && tB.length !== 1) {
|
|
257
|
+
throw new Error("Inputs are incompatible tensors");
|
|
258
|
+
}
|
|
259
|
+
const result = [];
|
|
260
|
+
for (let i = 0; i < outLen; i++) {
|
|
261
|
+
const subA = tA[tA.length === 1 ? 0 : i];
|
|
262
|
+
const subB = tB[tB.length === 1 ? 0 : i];
|
|
263
|
+
result.push(TensorMath.eq(subA, subB));
|
|
264
|
+
}
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
else if (Array.isArray(tA) && typeof tB === "number") {
|
|
268
|
+
return tA.map(subA => TensorMath.eq(subA, tB));
|
|
269
|
+
}
|
|
270
|
+
else if (typeof tA === "number" && Array.isArray(tB)) {
|
|
271
|
+
return tB.map(subB => TensorMath.eq(tA, subB));
|
|
272
|
+
}
|
|
273
|
+
throw new Error("Inputs are not tensors");
|
|
274
|
+
}
|
|
250
275
|
static neg(tA) {
|
|
251
276
|
if (typeof tA === "number") {
|
|
252
277
|
return -tA;
|