import { TransformN } from '../math/transform.js'; import { VecN } from '../math/vecn.js'; import type { HomogeneousProjection } from '../projection/types.js'; import { type CoordinateConstraintConsistency, type CoordinateConstraintDetermination } from './coordinate-constraints.js'; import { type SourceCellReferenceN, type SourceCellReferenceStatusN } from './source-reference.js'; export interface SourceSimplexReferenceN { readonly kind: 'source-simplex-reference'; /** Persistent source cell containing the authored vertex simplex. */ readonly parent: SourceCellReferenceN; readonly complex: SourceCellReferenceN['complex']; readonly intrinsicDim: number; readonly vertexIndices: readonly number[]; } export interface SourceSimplexCoordinateN { readonly kind: 'source-simplex-coordinate'; readonly reference: SourceSimplexReferenceN; /** Ordered barycentric weights matching `reference.vertexIndices`. */ readonly weights: readonly number[]; } export interface SourceSimplexCoordinateOptions { /** Scale-relative barycentric validation tolerance. Default `1e-12`. */ readonly tolerance?: number; } export interface SourceSimplexProjectionN { readonly coordinate: SourceSimplexCoordinateN; readonly point: VecN; readonly squaredDistance: number; readonly affineRank: number; readonly unresolvedDegreesOfFreedom: number; readonly candidateFaces: number; } export interface SourceSimplexProjectionObservationN { /** Optional stable identity for incremental observation composition. */ readonly key?: string; readonly projection: HomogeneousProjection; readonly targetPoint: readonly [number, number, number]; readonly weight?: number; readonly label?: string; } export interface SourceSimplexObservationFitOptions { readonly transform?: TransformN; /** Scale-relative forward and compatibility tolerance. Default `1e-9`. */ readonly tolerance?: number; /** Relative/normalized singular-value rank tolerance. Default `1e-10`. */ readonly rankTolerance?: number; /** Null-space preference. Default is the uniform simplex coordinate. */ readonly prior?: SourceSimplexCoordinateN; /** Safety bound for the exact active-face enumeration. Default `262143`. */ readonly maxCandidateFaces?: number; } /** * What one observation contributed to a fit, and whether it was worth having. * * Three separate judgements, and a fit can fail any one of them while the * others look fine: * * - `individualRank` — how much this observation constrained on its own. A * projection pins a point to a ray, so one observation cannot determine a * position by itself and a low rank here is expected, not a fault; * - `representationResidual` — how far the recovered point lands from where * this observation said it was, once re-projected through the same map; * - `minAbsQ` — the smallest homogeneous denominator met while forming the * equations. Near zero means this observation sits close to the * projection's singularity, where the equations are ill-conditioned and a * small residual proves less than it appears to. */ export interface SourceSimplexObservationDiagnosticN { /** Stable identity, matching this diagnostic to the observation supplied. */ readonly key: string; /** Human-readable name, if one was given. */ readonly label?: string; /** Weight this observation carried in the fit. */ readonly weight: number; /** Where the observation said the point appears. */ readonly targetPoint: readonly [number, number, number]; /** Where the recovered coordinate actually re-projects to. */ readonly representationPoint: readonly [number, number, number]; /** The distance between those two — this observation's own error. */ readonly representationResidual: number; /** RMS of the homogeneous equation residual across the three coordinates. */ readonly homogeneousEquationRms: number; /** Independent directions this observation constrained by itself. */ readonly individualRank: number; /** Smallest homogeneous denominator encountered; a conditioning warning * rather than an error, since the fit already refuses a denominator that * has actually degenerated. */ readonly minAbsQ: number; } export type SourceSimplexObservationFitFailureReason = 'no-observations' | 'invalid-projection-vertex' | 'invalid-homogeneous-denominator' | 'too-many-simplex-faces' | 'no-feasible-coordinate' | 'invalid-reconciled-projection'; /** * A source position recovered from several observations of the same point, * together with the evidence for how far it can be trusted. * * One projection of a point constrains it to a fibre rather than fixing it, * so recovering a source position takes more than one observation. Whether * enough were supplied is a property of the observations, not of the answer, * and the fields below report it rather than leaving a caller to assume. * * Read in this order: * * - `consistency` — `conflicting` means the observations cannot describe one * point, and `coordinate` is then the least-squares compromise rather than * a recovered position; * - `determination` — `rank-deficient` means the observations leave the point * underdetermined, and `unresolvedDegreesOfFreedom` counts by how much; * - the residuals — small values mean the recovered point reproduces the * observations it came from. * * A fit that is `compatible` and `unique` with residuals at rounding error is * a recovered source point. Anything else is a best effort, and which of the * two it is cannot be told from `coordinate` alone. */ export interface AvailableSourceSimplexObservationFitN { /** Whether the observations determined the point outright or were * reconciled by least squares. */ readonly kind: 'exact' | 'least-squares'; /** Whether the observations can describe a single source point at all. */ readonly consistency: CoordinateConstraintConsistency; /** Whether they pin it down, or leave directions unresolved. */ readonly determination: CoordinateConstraintDetermination; /** The recovered coordinate within its source simplex. */ readonly coordinate: SourceSimplexCoordinateN; /** The recovered point in the simplex's own parameterisation. */ readonly point: VecN; /** The same point in the complex's ambient space. */ readonly ambientPoint: VecN; /** Per-observation diagnostics, in the order supplied. */ readonly observations: readonly SourceSimplexObservationDiagnosticN[]; /** Degrees of freedom the source simplex has to be pinned down. */ readonly sourceDegreesOfFreedom: number; /** How many of them the observations actually constrain. */ readonly observationRank: number; /** The shortfall between the two; zero for a unique determination. */ readonly unresolvedDegreesOfFreedom: number; /** Conditioning of the constrained directions. A large value means the * rank was attained only marginally, so the point is nominally determined * but numerically soft. */ readonly rankConditioning: number; /** Residual of the constraint normals, measuring how far the observations * are from being mutually consistent. */ readonly constraintNormalResidual: number; /** Dimension of the simplex face the point resolved onto; lower than the * simplex's own dimension when the point lies on its boundary. */ readonly activeFaceDimension: number; /** RMS of the normalised equations, comparable across observation counts. */ readonly normalizedEquationRms: number; /** RMS distance between each observation and the recovered point * re-projected through the same map. */ readonly representationRmsResidual: number; /** The largest such distance; a single bad observation shows here while * the RMS still looks acceptable. */ readonly maxRepresentationResidual: number; /** Simplex faces considered before settling on `activeFaceDimension`. */ readonly candidateFaces: number; } export interface UnavailableSourceSimplexObservationFitN { readonly kind: 'unavailable'; readonly reason: SourceSimplexObservationFitFailureReason; readonly details: Readonly>; } export type SourceSimplexObservationFitN = AvailableSourceSimplexObservationFitN | UnavailableSourceSimplexObservationFitN; /** * Create a persistent vertex-simplex inside a current source cell. * * `vertexIndices` may name the whole source simplex or an authored simplex * used to triangulate a non-simplex parent face. Lifecycle follows the parent * cell; changing its vertex tuple retires every derived simplex reference. * * A single vertex is a legitimate 0-simplex feature: the pair-distance * vocabulary needs vertex--face pairs, whose vertex side is exactly this. * (The floor was 2 before P56; nothing downstream assumed it.) */ export declare function createSourceSimplexReferenceN(parent: SourceCellReferenceN, vertexIndices?: readonly number[]): SourceSimplexReferenceN; export declare function inspectSourceSimplexReferenceN(reference: SourceSimplexReferenceN): SourceCellReferenceStatusN; export declare function createSourceSimplexCoordinateN(reference: SourceSimplexReferenceN, weights: ArrayLike, options?: SourceSimplexCoordinateOptions): SourceSimplexCoordinateN; export declare function evaluateSourceSimplexCoordinateN(coordinate: SourceSimplexCoordinateN): VecN; /** Closest Float64 point on the closed source simplex. */ export declare function projectPointToSourceSimplexN(reference: SourceSimplexReferenceN, point: ArrayLike, options?: SourceSimplexObservationFitOptions): SourceSimplexProjectionN; /** * Reconcile R3 observations as homogeneous linear constraints on one source * simplex's barycentric weights. * * For target `y` and homogeneous vertex image `(h_j, q_j)`, each coordinate * contributes `sum_j w_j (h_j[c] - y[c] q_j) = 0`. Multiple views stack * those rows. The closed-simplex least-squares problem is solved by an exact * active-face enumeration; rank is measured on the barycentric tangent space. */ export declare function fitSourceSimplexCoordinateToObservationsN(reference: SourceSimplexReferenceN, observations: readonly SourceSimplexProjectionObservationN[], options?: SourceSimplexObservationFitOptions): SourceSimplexObservationFitN; //# sourceMappingURL=source-simplex-coordinate.d.ts.map