import { type NumberOps } from "./number-ops"; import { BisectOptions } from "./roots"; export declare enum EvalMethod { NORMAL = "normal", HORNER = "horner" } /** * A polynomial instance. * * import {Polynomial} from "@erosson/polynomial" * const p = Polynomial.parse([3,2,1]) * p.toString() // "t^2 + 2t + 3" */ export declare class Polynomial { coeffs: readonly T[]; ops: NumberOps; /** * @param coeffs The polynomial's coefficients. `coeffs[0]` is the constant term; `coeffs` of `[3,2,1]` are the polynomial `t^2 + 2 t + 3` * @param ops Fundamental operations for this polynomial's number type. Used to implement polynomials for {@link https://mikemcl.github.io/decimal.js/ | Decimal.js} or other non-builtin number types. If you're using the builtin number type, feel free to ignore it. */ private constructor(); /** * Given a list of numbers, create a polynomial. The numbers are the polynomial's coefficients. * * import {Polynomial} from "@erosson/polynomial" * const p = Polynomial.parse([1,2,3]) * p.toString() // "3 t^2 + 2 t + 1" * * @group constructors */ static parse(coeffs: readonly number[]): Polynomial; /** * Given a list of numbers and a `NumberOps`, create a polynomial. The numbers are the polynomial's coefficients. * * import {Polynomial, decimalNumberOps} from "@erosson/polynomial" * import Decimal from "decimal.js" * const p = Polynomial.parse([new Decimal(1), new Decimal(2), new Decimal(3)], decimalNumberOps(Decimal)) * p.toString() // "3 t^2 + 2 t + 1" * * @group constructors */ static parse(coeffs: readonly T[], ops: NumberOps): Polynomial; /** * The constant-term polynomial zero. Equivalent to `Polynomial.parse(0)`. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.zero().toString() // "0" * * @group constructors */ static zero(): Polynomial; /** * The constant-term polynomial zero. Equivalent to `Polynomial.parse(0)`. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.zero(decimalNumberOps(Decimal)).toString() // "0" * * @group constructors */ static zero(ops: NumberOps): Polynomial; /** * Return the *degree* of this polynomial - the value of its highest exponent. * * https://en.wikipedia.org/wiki/Degree_of_a_polynomial * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([1,2,3]).degree // 2 * Polynomial.parse([9,8,7,6]).degree // 3 * Polynomial.parse([9,8,7,6]).degree // 3 * Polynomial.zero().degree // 0 */ get degree(): number; /** * Is this polynomial a constant? That is, is its degree equal to zero? * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([1,2,3]).isConstant // false * Polynomial.parse([1]).isConstant // true * Polynomial.zero().isConstant // true */ get isConstant(): boolean; /** * Return this polynomial's constant term. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([1,2,3]).constantTerm // 1 * Polynomial.parse([1]).constantTerm // 1 * Polynomial.parse([9,8,7,6]).constantTerm // 9 * Polynomial.zero().constantTerm // 0 */ get constantTerm(): T; /** * Evaluate the polynomial at the given point. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2]).evaluate(0) // 3 * Polynomial.parse([3,2]).evaluate(1) // 5 * Polynomial.parse([3,2]).evaluate(2) // 7 * Polynomial.parse([3,2,1]).evaluate(0) // 3 * Polynomial.parse([3,2,1]).evaluate(1) // 6 * Polynomial.parse([3,2,1]).evaluate(2) // 11 * * @group evaluate */ evaluate(seconds: number, evalMethod?: EvalMethod): T; /** * Evaluate the polynomial at the given point, with the given degree. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).evaluateDegree(2, 0) // 11 = 3 + 2*2 + 1*(2^2) * Polynomial.parse([3,2,1]).evaluateDegree(2, 1) // 6 = 2*2 + 1*(2^2) * Polynomial.parse([3,2,1]).evaluateDegree(2, 2) // 2 = 1*(2^2) * * @group evaluate */ evaluateDegree(seconds: number, degree: number, evalMethod?: EvalMethod): T; /** * Add two polynomials. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).add(Polynomial.parse([1,2,3])) // [4,4,4] * Polynomial.parse([3,2,1]).add(Polynomial.parse([5])) // [8,2,1] * Polynomial.parse([3,2,1]).add(Polynomial.zero()) // [3,2,1] * * @group transforms */ add(b: Polynomial): Polynomial; /** * Add a polynomial and some polynomial coefficients. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).add([1,2,3]) // [4,4,4] * Polynomial.parse([3,2,1]).add([5]) // [8,2,1] * Polynomial.parse([3,2,1]).add([]) // [3,2,1] * * @group transforms */ addCoeffs(b: readonly T[]): Polynomial; /** * Add a list of polynomials. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).sum([Polynomial.parse([1,2,3]), Polynomial.parse([1,1,1])]) // [5,5,5] * * See also {@link sums} * * @group transforms */ sum(bs: readonly Polynomial[]): Polynomial; /** * Add a list of polynomials. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.sums([Polynomial.parse([1,2,3]), Polynomial.parse([1,1,1])]) // [5,5,5] * Polynomial.sums([]) // throws error * * @group transforms */ static sums(ps: readonly Polynomial[]): Polynomial; /** * Add a list of polynomial-coefficients. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).sumCoeffs([[1,2,3], [1,1,1]]) // [5,5,5] * Polynomial.parse([3,2,1]).sumCoeffs([]) // [3,2,1] * * @group transforms */ sumCoeffs(bs: readonly (readonly T[])[]): Polynomial; /** * Multiply a polynomial by a scalar. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).mul(5) // [15,10,5] * Polynomial.parse([3,2,1]).mul(0) // [0] * * @group transforms */ mul(c: number): Polynomial; /** * Multiply a polynomial by a scalar. Similar to `mul`, but this one supports uses the same number format as your polynomial. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).mulT(5) // [15,10,5] * Polynomial.parse([3,2,1]).mulT(0) // [0] * * @group transforms */ mulT(c: T): Polynomial; /** * True if the given value is a root of this polynomial - that is, if `evaluate(t) === 0` for this t. * * @param tolerance floating point imprecision allowed for this to return true * * @group roots */ isRoot(t: number, tolerance?: number): boolean; /** * Will `{@link findRootsQuick}` work for this polynomial? * * True if degree 3 or less, or (trivially) if the constant term is zero. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([-3,2,1]).isRootQuick // true * Polynomial.parse([-64,0,0,1]).isRootQuick // true * Polynomial.parse([-5,4,3,2,1]).isRootQuick // false * Polynomial.parse([0]).isRootQuick // true * Polynomial.parse([1]).isRootQuick // true * * @group roots */ get isRootQuick(): boolean; /** * Try to find at least one root of this polynomial - that is, the values of `t` where `evaluate(t) === 0`. * * For polynomials with degree <= 3, we use exact formulas to find one. For larger polynomials, we use an iterative method, which will be slower and less accurate. * * @todo polynomials with degree >= 4 not yet implemented, throw an error * * https://en.wikipedia.org/wiki/Polynomial_root-finding_algorithms * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([-3,2,1]).findRootsQuick() // Set([1,-3]) * Polynomial.parse([-64,0,0,1]).findRootsQuick() // Set([4]) * Polynomial.parse([-5,4,3,2,1]).findRootsQuick() // throws Error - degree too high; isRootQuick was false * Polynomial.parse([0]).findRootsQuick() // Set([0]) * Polynomial.parse([1]).findRootsQuick() // Set([]) * * @group roots */ findRootsQuick(): ReadonlySet; /** * Does this polynomial start negative, grow continuously, and eventually become non-negative? * * - is the constant term `coeffs[0]` negative? * - are all non-constant terms `coeffs[1..]` non-negative? * * That is, does it look like: * * -p0 + p1 t + p2 t^2 + p3 t^3 + ... * * If so, we can bisect it to approximate a root. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([-3,2,1]).isRootBisectable // true * Polynomial.parse([-64,0,0,1]).isRootBisectable // true * Polynomial.parse([-5,4,3,2,1]).isRootBisectable // false * Polynomial.parse([0]).isRootBisectable // false * Polynomial.parse([1]).isRootBisectable // false * * @group roots */ get isRootBisectable(): boolean; /** * Try to approximate exactly one root of this polynomial - that is, the values of `t` where `evaluate(t) === 0`. * * This uses bisection, which is slower than some other methods. Also, it only works for {@link isRootBisectable | bisectable polynomials}. Also, it's an approximation, not an exact result. * * You should prefer {@link findRootsQuick} when possible. * * https://en.wikipedia.org/wiki/Bisection_method#Algorithm * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([-3,2,1]).findRootBisect() // 0.999999... * Polynomial.parse([-64,0,0,1]).findRootBisect() // 3.99999... * Polynomial.parse([-256,0,0,0,1]).findRootBisect() // 3.99999... * Polynomial.parse([0]).findRootBisect() // error: not bisectable * Polynomial.parse([1]).isRootBisectable // error: not bisectable * Polynomial.parse([-1]).isRootBisectable // error: not bisectable * * @group roots */ findRootBisect(opts?: BisectOptions): number; /** * Transform a polynomial to a list of `[formatted-coefficient, degree]`, suitable for string formatting. * You could use this to implement an HTML representation, for example. * * import {Polynomial} from "@erosson/polynomial" * * Polynomial.parse([3,2,1]).format() // [["",2],["2 ",1],["3 ",0]] * Polynomial.parse([3,2,1]).toString() // "t^2 + 2 t + 3" * * Polynomial.parse([3,0,1]).format() // [["",2],["0 ",1],["3 ",0]] * Polynomial.parse([3,0,1]).toString() // "t^2 + 0 t + 3" * * @group rendering */ format(): readonly (readonly [string, number])[]; /** * Transform a polynomial to a list of `[formatted-coefficient, degree]`, suitable for string formatting. * * import {Polynomial} from "@erosson/polynomial" * * Polynomial.parse([3,2,1]).formats() // ["t^2", "2 t", "3"] * Polynomial.parse([3,2,1]).toString() // "t^2 + 2 t + 3" * * Polynomial.parse([3,0,1]).formats() // ["t^2", "0 t", "3"] * Polynomial.parse([3,0,1]).toString() // "t^2 + 0 t + 3" * * @group rendering */ formats(): string[]; /** * Render a polynomial as a string. * * If you need custom formatting, start with {@link format} instead. * * import {Polynomial} from "@erosson/polynomial" * Polynomial.parse([3,2,1]).toString() // "t^2 + 2 t + 3" * Polynomial.parse([3,0,1]).toString() // "t^2 + 0 t + 3" * * @group rendering */ toString(): string; }