UNPKG

@thi.ng/tensors

Version:

0D/1D/2D/3D/4D tensors with extensible polymorphic operations and customizable storage

118 lines (117 loc) 2.3 kB
import { identity } from "@thi.ng/api/fn"; import { constant, tensor } from "./tensor.js"; const SOBEL1 = tensor([-1, 0, 1]); const SOBEL2 = tensor([ [-1, -2, -1], [0, 0, 0], [1, 2, 1] ]); const SOBEL3 = tensor([ [ [-1, -2, -1], [-2, -4, -2], [-1, -2, -1] ], [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ], [ [1, 2, 1], [2, 4, 2], [1, 2, 1] ] ]); const EDGE2 = (r) => { r |= 0; const w = 2 * r + 1; const data = new Array(w * w).fill(-1); data[data.length >> 1] = w * w - 1; return tensor("num", [w, w], { data, copy: false }); }; const SHARPEN2_3x3 = tensor([ [0, -1, 0], [-1, 5, -1], [0, -1, 0] ]); const BOX_BLUR2 = (r) => { r = 2 * r + 1; return constant([r, r], 1 / (r * r), "num"); }; const GAUSSIAN_BLUR2 = (r) => { r |= 0; const sigma = -1 / (2 * (Math.SQRT2 * r / 3) ** 2); const res = []; let sum = 0; for (let y = -r; y <= r; y++) { for (let x = -r; x <= r; x++) { const g = Math.exp((x * x + y * y) * sigma); res.push(g); sum += g; } } const size = r * 2 + 1; return tensor("num", [size, size], { data: res.map((x) => x / sum), copy: false }); }; const { max, min } = Math; const MAX2_POOL = (w, h = w) => { return { shape: [w, h], init: () => -Infinity, reduce: (acc, val) => max(acc, val), complete: identity }; }; const MIN2_POOL = (w, h = w) => { return { shape: [w, h], init: () => Infinity, reduce: (acc, val) => min(acc, val), complete: identity }; }; const MAXIMA2 = (r) => { r |= 0; const w = 2 * r + 1; return { shape: [w, w], init: () => [-Infinity, 0], reduce: (acc, val, i, j) => { if (i === r && j === r) acc[1] = val; else acc[0] = max(acc[0], val); return acc; }, complete: (acc) => acc[1] > acc[0] ? 1 : 0 }; }; const MINIMA2 = (r) => { r |= 0; const w = 2 * r + 1; return { shape: [w, w], init: () => [Infinity, 0], reduce: (acc, val, i, j) => { if (i === r && j === r) acc[1] = val; else acc[0] = min(acc[0], val); return acc; }, complete: (acc) => acc[1] < acc[0] ? 1 : 0 }; }; export { BOX_BLUR2, EDGE2, GAUSSIAN_BLUR2, MAX2_POOL, MAXIMA2, MIN2_POOL, MINIMA2, SHARPEN2_3x3, SOBEL1, SOBEL2, SOBEL3 };