npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

algomatic

v4.0.0

Published

Various algorithms and math utilities.

Downloads

498

Readme

Algomatic

Various algorithms and utilities.

  • High performance and low memory consumption (no heap allocations);
  • Lightweight and tree-shakable;
  • Thoroughly tested.

🔎 API documentation is available here.

npm install --save-prod algomatic

Algebra

Clamp a value to range:

import { clamp } from 'algomatic';

const f = clamp(5, 10);

f(33);
// ⮕ 10

Scale a value from one range to another:

const f = scale(0, 1, 50, 100);

f(75);
// ⮕ 0.5

Round a value to the closest value that is divided by divisor without any remainder:

const f = snap(10);

f(17);
// ⮕ 20

Bring a value to the range by adding or subtracting the range size:

const f = cycle(0, 10);

f(12);
// ⮕ 2

Bitwise operations

Bitwise operators that can manipulate integers in [MIN_SAFE_INTEGER, MAX_SAFE_INTEGER] range:

import { left, right, and, or } from 'algomatic';

left(0x11, 8); // Same as 0x11 << 8
// ⮕ 0x11_00 

left(0x11_22_33_44, 24)
// ⮕ 0x11_22_33_44_00_00_00

right(0x11_22, 8); // Same as 0x11_22 >> 8
// ⮕ 0x11

right(0x11_22_22_44_55_66_77, 24);
// ⮕ 0x11_22_22_44

and(0x10_aa_bb_00_00_00_ff, 0x10_00_bb_cc_00_00_ff);
// ⮕ 0x10_00_bb_00_00_00_ff

or(0x10_aa_bb_00_00_00_ff, 0x10_00_bb_cc_00_00_ff);
// ⮕ 0x10_aa_bb_cc_00_00_ff

xor(0x10_aa_bb_00_00_00_ff, 0x10_00_bb_cc_00_00_ff);
// ⮕ 0xaa_00_cc_00_00_00

Distributions

Create an array and fill it with numbers that are evenly distributed in a range:

import { seq } from 'algomatic';

seq(3);
// ⮕ [0, 0.5, 1]

seq(4, -10, 2);
// ⮕ [-10, -6, -2, 2]

Create gaussian distribution (normal distribution):

seq(3).map(gauss(0.5, 0.3));
// ⮕ [0.33, 1.32, 0.33]

Create cumulative distribution function for Gaussian (normal) distribution:

seq(3).map(cdfGauss(0.5, 0.3));
// ⮕ [ 0.04, 0.5, 0.95 ]

Inverse distribution function (quantile function) for Gaussian (normal) distribution:

seq(3).map(cdfGaussInv);

Easing

Various easing function:

import { easeExp, easeInCubic } from 'algomatic';

const f = easeExp();

f(0.5)
// ⮕ 0.3775

easeInCubic(0.5);
// ⮕ 0.125

Interpolation

Linear interpolator:

import { lerp } from 'algomatic';

const f = lerp(xs, ys);

const y = f(x);

Here xs is the array of X coordinates of pivot points in ascending order, and ys is the array of corresponding Y coordinates of pivot points.

A cubic spline interpolator for given pivot points:

const f = cspline(xs, ys);
const y = f(x);

More control over cubic spline caching and computation:

import { interpolateCSpline, populateCSplines } from 'algomatic';

// Pre-allocate an array of spline components that can be later reused
// to avoid excessive memory allocations
const splines = new Float32Array(xs.length * 3);

populateCSplines(xs, ys, xs.length, splines);
// or
// const splines = createCSplines(xs, ys, xs.length);

const y = interpolateCSpline(xs, ys, x, xs.length, splines);

A monotone cubic interpolator for given pivot points:

const f = csplineMonot(xs, ys);
const y = f(x);

Or using more fine-grained approach:

import { interpolateCSplineMonot, populateCSplinesMonot } from 'algomatic';

const y = interpolateCSplineMonot(xs, ys, x, xs.length, populateCSplinesMonot(xs, ys, xs.length));

Search

Binary search searches the specified array for the specified value using the binary search algorithm. The array must be sorted into ascending order according to the natural ordering of its elements prior to making this call. If it is not sorted, the results are undefined.

Returns the index of the searched value, if it is contained in the array; otherwise, -(insertion point) - 1. The insertion point is defined as the point at which the searched value would be inserted into the array: the index of the first element greater than the searched value, or array length if all elements in the array are less than the specified key. Note that this guarantees that the return value will be ≥ 0 if and only if the searched value is found.

import { binarySearch } from 'algomatic';

binarySearch([10, 20, 30, 40], 20);
// ⮕ 1

binarySearch([10, 20, 30, 40], 25);
// ⮕ -3

Binary search with a comparator:

binarySearch(
  [{x: 10}, {x: 20}, {x: 30}],
  {x: 20},
  (a, b) => a.x - b.x
);

Sort

Sort the array in-place:

import { qsort } from 'algomatic';

const arr = [3, 2, 0, 1];

qsort(arr);

Sort the array in-place and invoke a callback after a pair of elements was swapped:

qsort(arr, (i, j) => {
  // Called when i and j elements of arr were swapped.
  // Use this to sort multiple arrays in parallel.
});

Sort using a comparator:

qsort(arr, undefined, (a, b) => {
  // Comparator works the same way as in Array.sort
  return 0;
});

qsort uses a non-recursive Quicksort algorithm. In contrast to Array.sort, qsort doesn't convert array elements to strings before comparison and uses comparison operators directly. So numeric arrays are sorted in natural order with qsort(arr). You can provide an element comparator to change the sorting order.

qsort is 10x faster than Array.sort on both small and big arrays. The plot below uses a log scale and shows the dependency of number of operations per second from the input array length.