UNPKG

@thi.ng/tensors

Version:

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

61 lines (60 loc) 1.67 kB
import { cdf } from "./cdf.js"; import { defOpT } from "./defopt.js"; import { ensureShape } from "./errors.js"; import { findIndex } from "./find.js"; import { mulN } from "./muln.js"; import { tensor } from "./tensor.js"; const histogramUint = (src, depth, mask = (1 << depth) - 1, shift = 0) => { const histType = src.length < 256 ? "u8" : src.length < 65536 ? "u16" : "u32"; const histogram = tensor(histType, [1 << depth]); if (src.dim > 1) src = src.reshape([src.length]); const { offset: oa, shape: [sa], stride: [ta], data: adata } = src; for (let i = 0; i < sa; i++) histogram.data[adata[oa + i * ta] >>> shift & mask]++; return histogram; }; const equalizeHistogram = (out, src, depth, numSamples, threshold = 0) => { !out && (out = src); ensureShape(out, src.shape); const norm = mulN(tensor("f64", [src.length]), src, 1 / numSamples); const $cdf = cdf(null, norm); const lo = findIndex($cdf, (x) => x > threshold); if (lo < 0) return out.fill(0); const { offset: oc, shape: [sc], stride: [tc], data: cdata } = $cdf; const { offset: oo, stride: [to], data: odata } = out; const base = cdata[oc + lo * tc]; const scale = (2 ** depth - 1) / (cdata[oc + (sc - 1) * tc] - base); for (let i = 0; i < sc; i++) { odata[oo + i * to] = Math.max(0, scale * (cdata[oc + i * tc] - base)); } return out; }; const applyLUT = (out, a, lut) => { !out && (out = a); ensureShape(out, a.shape); const { offset: ol, stride: [tl], data: ldata } = lut; return defOpT((x) => ldata[ol + x * tl])(out, a); }; export { applyLUT, equalizeHistogram, histogramUint };