xen-dev-utils
Version:
Utility functions used by the Scale Workshop ecosystem
175 lines (174 loc) • 7.89 kB
TypeScript
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;