UNPKG

xen-dev-utils

Version:

Utility functions used by the Scale Workshop ecosystem

175 lines (174 loc) 7.89 kB
import { Fraction, FractionValue } from './fraction'; import { Monzo } from './monzo'; export * from './fraction'; export * from './primes'; export * from './conversion'; export * from './combinations'; export * from './monzo'; export * from './approximation'; export * from './number-array'; export * from './basis'; export * from './hnf'; export { sum } from './polyfills/sum-precise'; export interface AnyArray { [key: number]: any; length: number; } /** * Check if the contents of two arrays are equal using '==='. * @param a The first array. * @param b The second array. * @returns True if the arrays are component-wise equal. */ export declare function arraysEqual(a: AnyArray, b: AnyArray): boolean; /** * Floor division. * @param a The dividend. * @param b The divisor. * @returns The quotient of Euclidean division of a by b. */ export declare function div(a: number, b: number): number; /** Result of the extended Euclidean algorithm. */ export type ExtendedEuclid = { /** Bézout coefficient of the first parameter. */ coefA: number; /** Bézout coefficient of the second parameter. */ coefB: number; /** Greatest common divisor of the parameters. */ gcd: number; /** Quotient of the first parameter when divided by the gcd */ quotientA: number; /** Quotient of the second parameter when divided by the gcd */ quotientB: number; }; /** * Extended Euclidean algorithm for integers a and b: * Find x and y such that ax + by = gcd(a, b). * ```ts * result.gcd = a * result.coefA + b * result.coefB; // = gcd(a, b) * result.quotientA = div(a, gcd(a, b)); * result.quotientB = div(b, gcd(a, b)); * ``` * @param a The first integer. * @param b The second integer. * @returns Bézout coefficients, gcd and quotients. */ export declare function extendedEuclid(a: number, b: number): ExtendedEuclid; /** * Iterated (extended) Euclidean algorithm. * @param params An iterable of integers. * @returns Bézout coefficients of the parameters. */ export declare function iteratedEuclid(params: Iterable<number>): number[]; /** * Find modular inverse of a (mod b). * @param a Number to find modular inverse of. * @param b Modulus. * @param strict Ensure that a * modInv(a, b) = 1 (mod b). If `strict = false` we have a * modInv(a, b) = gdc(a, b) (mod b) instead. * @returns The modular inverse in the range {0, 1, ..., b - 1}. */ export declare function modInv(a: number, b: number, strict?: boolean): number; /** * Collection of unique fractions. */ export declare class FractionSet extends Set<Fraction> { /** * Check `value` membership. * @param value Value to check for membership. * @returns A boolean asserting whether an element is present with the given value in the `FractionSet` object or not. */ has(value: Fraction): boolean; /** * Appends `value` to the `FractionSet` object. * @param value Value to append. * @returns The `FractionSet` object with added value. */ add(value: Fraction): this; /** * Removes the element associated to the `value`. * @param value Value to remove. * @returns A boolean asserting whether an element was successfully removed or not. `FractionSet.prototype.has(value)` will return `false` afterwards. */ delete(value: Fraction): boolean; } /** * Calculate the Binomial coefficient *n choose k*. * @param n Size of the set to choose from. * @param k Number of elements to choose. * @returns The number of ways to choose `k` (unordered) elements from a set size `n`. */ export declare function binomial(n: number, k: number): number; /** * Clamp a value to a finite range. * @param minValue Lower bound. * @param maxValue Upper bound. * @param value Value to clamp between bounds. * @returns Clamped value. */ export declare function clamp(minValue: number, maxValue: number, value: number): number; /** * Calculate the difference between two cents values such that equave equivalence is taken into account. * @param a The first pitch measured in cents. * @param b The second pitch measured in cents. * @param equaveCents The interval of equivalence measured in cents. * @returns The first pitch minus the second pitch but on a circle such that large differences wrap around. */ export declare function circleDifference(a: number, b: number, equaveCents?: number): number; /** * Calculate the distance between two cents values such that equave equivalence is taken into account. * @param a The first pitch measured in cents. * @param b The second pitch measured in cents. * @param equaveCents The interval of equivalence measured in cents. * @returns The absolute distance between the two pitches measured in cents but on a circle such that large distances wrap around. */ export declare function circleDistance(a: number, b: number, equaveCents?: number): number; /** * Calculate the smallest power of two greater or equal to the input value. * @param x Value to compare to. * @returns Smallest `2**n` such that `x <= 2**n`. */ export declare function ceilPow2(x: number): number; /** * Create an iterator over the n'th Farey sequence. (All fractions between 0 and 1 inclusive.) * @param maxDenominator Maximum denominator in the sequence. * @yields Fractions in ascending order starting from 0/1 and ending at 1/1. */ export declare function fareySequence(maxDenominator: number): Generator<Fraction, undefined, undefined>; /** * Create an iterator over the interior of n'th Farey sequence. (All fractions between 0 and 1 exclusive.) * @param maxDenominator Maximum denominator in the sequence. * @yields Fractions in ascending order starting from 1/maxDenominator and ending at (maxDenominator-1)/maxDenominator. */ export declare function fareyInterior(maxDenominator: number): Generator<Fraction, undefined, undefined>; /** * Determine if an equally tempered scale has constant structure i.e. you can tell the interval class from the size of an interval. * @param steps Musical intervals measured in steps not including the implicit 0 at the start, but including the interval of repetition at the end. * @returns A pair of pairs of indices that have the same stepspan but different subtension. `null` if the scale has constant structure. */ export declare function falsifyConstantStructure(steps: number[]): [[number, number], [number, number]] | null; /** * Determine if a scale has constant structure i.e. you can tell the interval class from the size of an interval. * @param scaleCents Musical intervals measured in cents not including the implicit 0 at the start, but including the interval of repetition at the end. * @param margin Margin of equivalence between two intervals measured in cents. * @returns `true` if the scale definitely has constant structure. (A `false` result may convert to `true` using a smaller margin.) */ export declare function hasMarginConstantStructure(scaleCents: number[], margin: number): boolean; /** * Measure the size of a monzo in cents. * Monzos representing small rational numbers (commas) are measured accurately. * @param monzo Array or prime exponents, possibly fractional. * @returns The size of the represented number in cents (1200ths of an octave). */ export declare function monzoToCents(monzo: Monzo): number; /** * Given fraction p/q calculate log(abs(p*q)). * @param value Rational number or an array of its prime exponents. * @returns The Tenney-height of the number. */ export declare function tenneyHeight(value: Monzo | FractionValue): number; /** * Given fraction p/q calculate sopfr(p) + sopfr(q), ignoring sign. * @param value Rational number, an array of its prime exponents or a `Map` of its prime exponents. * @returns Sum of prime factors with repetition of p*q. */ export declare function wilsonHeight(value: Monzo | FractionValue | Map<number, number>): number;