@numio/bigmath
Version:
@numio/bigmath is an arbitrary-precision arithmetic library. It can be used for basic operations with decimal numbers (integers and float)
35 lines (34 loc) • 1.61 kB
JavaScript
import { cbrtInner } from "../cbrt/utils.js";
import { isLeftGreaterOrEqualInner } from "../compare/utils.js";
import { IQRInner } from "../IQR/utils.js";
import { MADInner } from "../MAD/utils.js";
import { divInner } from "../operations/div/utils.js";
import { PipeInner } from "../pipe/utils.js";
import { tryBigInt } from "../shared/utils.js";
const getBinsNum = (range, binWidth) => {
let binNum = new PipeInner().div([range, binWidth], 10).bi;
if (binNum[1] > 0) {
binNum = [new PipeInner().div([range, binWidth], 0).bi[0] + 1n, 0];
}
return binNum;
};
export const fdrInner = (array, options = { useMadAbove: 0, maxBinNumber: 90, madFrom: "mean" }) => {
const mad = MADInner(array, { from: options.madFrom });
const nonNilMad = mad[0] <= 0n ? [1n, 0] : mad;
const IQR = IQRInner(array);
const isMadUsed = array.length < options.useMadAbove || IQR[0] === 0n;
const validIQR = isMadUsed ? nonNilMad : IQR;
const [cbrtLen] = cbrtInner([tryBigInt(array.length), 0]);
const binWidth = new PipeInner().mul([[2n, 0], validIQR]).div([cbrtLen]).bi;
const range = new PipeInner().sub([array[array.length - 1], array[0]]).bi;
const binNum = getBinsNum(range, binWidth);
const maxBinNum = [tryBigInt(options.maxBinNumber), 0];
const scale = isLeftGreaterOrEqualInner({ left: binNum, right: maxBinNum })
? divInner([binNum, maxBinNum], 20)
: [1n, 0];
const scaledBinWidth = new PipeInner().mul([binWidth, scale]).bi;
return {
binWidth: scaledBinWidth,
binNum: getBinsNum(range, scaledBinWidth),
};
};