@mark1russell7/rigor-statistics 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,6 +71,8 @@ To vary a conditional dimension, `sliceResponse` needs its parent at a level ins
71
71
 
72
72
  The band of a curve is `value ± width × RMSE`, from the held-out error of the folds. On a log scale, the band is a ratio. The band has one width along the curve. It is the mean error of the model.
73
73
 
74
+ A measure with the field `range` keeps each view inside it, for example `[0, 1]` for a share. `sliceResponse` and `surfaceResponse` move `value`, `low` and `high` to the nearest end. Such a place has the field `clipped`, and the field `clipped` of the view counts these places. `predictResponse` gives the value that the model fitted, and a fit does not use the range. `parseResponseRecord` refuses a measured value outside the range.
75
+
74
76
  The field `nearest` of each place tells how far the place is from a measurement. It goes from 0 to 1, and 0 means that a point was measured there. A viewer can fade the band away from the data. A table cell with the `fallback` value has `nearest` above 0.
75
77
 
76
78
  ### The error of one cell
@@ -115,6 +117,8 @@ The default expansion has one product for each pair of levels of two dimensions.
115
117
  | `pairedPermutation(candidate, baseline, options)` | The paired permutation test (random sign flips). It uses the size of each difference. |
116
118
  | `wilson(k, n, z)` | The Wilson interval of a proportion. |
117
119
  | `medianInterval(values, level)` | The distribution-free interval of a median, from two order statistics. It gives `low`, `high`, the `rank` of `low` and the `coverage`. |
120
+ | `quantileInterval(values, p, level)` | The distribution-free interval of a quantile, from two order statistics. A side with no rank is infinite. The values must be independent draws. |
121
+ | `quantileSamples(p, level)` | The fewest independent values that give a quantile an upper bound. At the level 0.95: 72 values for p95, 368 for p99 and 3,688 for p99.9. |
118
122
  | `binomialInterval(n, p, level)`, `negativeBinomialInterval(successes, p, level)` | The central interval of a binomial count, and of a count of failures before `successes` successes. Each tail outside holds `(1 - level) / 2` or less. |
119
123
  | `holm(pValues, level)` | The Holm correction of a family of tests. |
120
124
  | `spearman`, `kendallTau`, `ranks` | The rank correlations, with mean ranks for ties. |
@@ -124,6 +128,8 @@ The default expansion has one product for each pair of levels of two dimensions.
124
128
  | `parseResponseRecord(value)` | The examination of unknown data. It gives the record, or one fault with a path for each error. |
125
129
  | `predictResponse(model, inputs)`, `heldOutError(record, measure)` | The value of a model at one set of inputs, and the error of the folds of a measure. |
126
130
  | `heldOutErrorAt(record, measure, ids)` | The held-out error of a chosen set of points, from the predictions of the option `outOfFold`. |
131
+ | `responseCells(record, vary, steps)` | The number of fitted places of a view, level axes included. It lets a caller bound the time of a view before the view starts. |
132
+ | `whenHolds(dimension, values)` | True when a place has the condition of a dimension. A dimension with no `when` is always present. |
127
133
  | `sliceResponse(record, measure, options)`, `surfaceResponse(record, measure, options)` | A fitted curve over one dimension, or a fitted surface over two, with the matching measured points, the matching points with no value, a band and the distance to the nearest measurement. |
128
134
 
129
135
  Each function throws a RangeError for an empty list, for a NaN and for a parameter out of its range. Thus a missing value cannot make a quiet NaN in a record.
package/build/index.d.ts CHANGED
@@ -215,6 +215,11 @@ interface ResponseMeasure {
215
215
  readonly unit: string;
216
216
  /** The better direction of the value. The value `none` means that no direction is better. */
217
217
  readonly direction: "higher" | "lower" | "none";
218
+ /**
219
+ * The low and the high end of the possible values, for example `[0, 1]` for a share. Each measured value is in this
220
+ * range. A view clips its fitted values to it, and a fit does not use it.
221
+ */
222
+ readonly range?: readonly [number, number];
218
223
  }
219
224
  /** A declared reason that a measure is absent, for example infeasible, unsupported or out of budget. */
220
225
  interface ResponseReason {
@@ -406,6 +411,8 @@ interface ResponseBand {
406
411
  * count over the dimensions.
407
412
  */
408
413
  readonly nearest: number;
414
+ /** This field is true when the measure has a `range` and the view moved `value`, `low` or `high` into it. */
415
+ readonly clipped?: true;
409
416
  }
410
417
  /** One place of a curve. */
411
418
  interface ResponseCurvePoint extends ResponseBand {
@@ -440,6 +447,8 @@ interface ResponseSlice {
440
447
  /** The points that match the held values and have no value of the measure, each with its reason. */
441
448
  readonly absent: readonly ResponseAbsentPoint[];
442
449
  readonly error: ResponseHeldOutError;
450
+ /** The number of places of `curve` with the field `clipped`. */
451
+ readonly clipped: number;
443
452
  }
444
453
  /** A measured point of a surface. */
445
454
  interface ResponseSurfacePoint {
@@ -472,7 +481,11 @@ interface ResponseSurface {
472
481
  /** The points that match the held values and have no value of the measure, each with its reason. */
473
482
  readonly absent: readonly ResponseSurfaceAbsentPoint[];
474
483
  readonly error: ResponseHeldOutError;
484
+ /** The number of places of `cells` with the field `clipped`. */
485
+ readonly clipped: number;
475
486
  }
487
+ /** This function gives true when a place has the condition of a dimension. A dimension with no condition is present. */
488
+ export declare function whenHolds(dimension: ResponseDimension, values: Readonly<Record<string, unknown>>): boolean;
476
489
  /**
477
490
  * This function gives the value of a model at `inputs`, on the scale of the measure. The inputs have a value for each
478
491
  * dimension that the model reads. An absent conditional dimension has `null`. A table model gives its `fallback` for a
@@ -525,6 +538,10 @@ export declare function heldOutErrorAt(record: ResponseRecord, measure: string,
525
538
  * distance is on the log scale of the model, so the band is a ratio. The band has one width along all the curve. The
526
539
  * band is the mean error of the model, and `nearest` tells how far the place is from a measurement.
527
540
  *
541
+ * A measure with a `range` keeps each place inside it. The fields `value`, `low` and `high` move to the nearest end.
542
+ * The place then has the field `clipped`, and the field `clipped` of the view counts these places. The function
543
+ * `predictResponse` gives the value that the model fitted.
544
+ *
528
545
  * The function throws a RangeError for an unknown measure or dimension, and for a held value that is not good for its
529
546
  * dimension. It also throws for a dimension that is both varied and held, and for a bad option.
530
547
  */
@@ -536,6 +553,14 @@ export declare function sliceResponse(record: ResponseRecord, measure: string, o
536
553
  * It throws when a conditional dimension varies with its parent, and when two varied dimensions need no common level.
537
554
  */
538
555
  export declare function surfaceResponse(record: ResponseRecord, measure: string, options: ResponseSurfaceOptions): ResponseSurface;
556
+ /**
557
+ * This function gives the number of fitted places of a view before the view starts: the product of the lengths of its
558
+ * axes. A level axis counts its levels, and a continuous axis counts `steps`. The field `nearest` reads each point at
559
+ * each place, so the reads of a view are this count times the number of points. The default of `steps` is the default
560
+ * of a view. The function throws a RangeError for an unknown dimension, for one dimension named two times, and for a
561
+ * bad `steps`.
562
+ */
563
+ export declare function responseCells(record: Pick<ResponseRecord, "dimensions">, vary: string | readonly [string, string], steps?: number): number;
539
564
  /** The largest power of a factor. A larger power of a coordinate from -1 to 1 adds almost nothing to a model. */
540
565
  export declare const RESPONSE_MAX_POWER = 8;
541
566
  /** One fault of a record. */
@@ -738,6 +763,33 @@ interface MedianInterval {
738
763
  * is less than `level`.
739
764
  */
740
765
  export declare function medianInterval(values: readonly number[], level?: number): MedianInterval;
766
+ /** The distribution-free interval of a quantile, from two order statistics of the sample. */
767
+ interface QuantileInterval {
768
+ /** The value x_(lowRank), or `-Infinity` when the sample has no rank for a lower bound. */
769
+ readonly low: number;
770
+ /** The value x_(highRank), or `Infinity` when the sample has no rank for an upper bound. */
771
+ readonly high: number;
772
+ /** The rank of `low`, from 1, or 0 when `low` is `-Infinity`. */
773
+ readonly lowRank: number;
774
+ /** The rank of `high`, from 1, or n + 1 when `high` is `Infinity`. */
775
+ readonly highRank: number;
776
+ /** The chance that the interval holds the quantile of the population. */
777
+ readonly coverage: number;
778
+ }
779
+ /**
780
+ * This function gives the distribution-free interval of the quantile `p` of a sample. Each tail outside the interval holds
781
+ * (1 - level) / 2 or less. Let X ~ Binomial(n, p). The lower rank is the largest l with P(X <= l - 1) in the tail. The upper
782
+ * rank is the smallest u with P(X >= u) in the tail. The values must be independent draws, or the coverage is false.
783
+ *
784
+ * A side with no such rank is infinite. Thus a small sample gives no upper bound: refer to `quantileSamples`.
785
+ */
786
+ export declare function quantileInterval(values: readonly number[], p: number, level?: number): QuantileInterval;
787
+ /**
788
+ * This function gives the fewest independent values that give the quantile `p` an upper bound at `level`: the smallest n with
789
+ * p^n <= (1 - level) / 2. With that n, the upper bound is the largest value. At the level 0.95, p95 needs 72 values, p99 needs
790
+ * 368 values and p99.9 needs 3,688 values.
791
+ */
792
+ export declare function quantileSamples(p: number, level?: number): number;
741
793
  /** A central interval of a count, from `low` to `high`, both included. */
742
794
  interface CountInterval {
743
795
  readonly low: number;
@@ -868,5 +920,5 @@ interface CalibrationLevel {
868
920
  }
869
921
  /** The hit rate of each stated level, from the lowest level. */
870
922
  export declare function calibration(forecasts: readonly Forecast[]): CalibrationLevel[];
871
- export type { BootstrapOptions, CalibrationLevel, CategoricalDimension, CompareOptions, Comparison, ContinuousDimension, Corrected, CountInterval, Effect, Forecast, Interval, LeastSquaresFit, LeastSquaresOptions, MedianInterval, NoiseOptions, NoiseState, NoiseVerdict, OrdinalDimension, ParsedResponseRecord, PermutationOptions, PermutationResult, Proportion, QuantileMethod, ResponseAbsentPoint, ResponseBand, ResponseCurvePoint, ResponseData, ResponseDimension, ResponseDimensionBase, ResponseFactor, ResponseFault, ResponseFitOptions, ResponseFold, ResponseFoldError, ResponseHeldOutError, ResponseInputValue, ResponseMeasure, ResponseModel, ResponseModelBase, ResponsePoint, ResponseReason, ResponseRecord, ResponseSlice, ResponseSliceOptions, ResponseSlicePoint, ResponseSurface, ResponseSurfaceAbsentPoint, ResponseSurfaceOptions, ResponseSurfacePoint, ResponseTableCell, ResponseValue, ResponseViewOptions, ResponseWhen, RidgeInput, RidgeInputBase, RidgeLevelInput, RidgeNumberInput, RidgeOptions, RidgeRankInput, RidgeResponseModel, RidgeTerm, Summary, TableResponseModel };
923
+ export type { BootstrapOptions, CalibrationLevel, CategoricalDimension, CompareOptions, Comparison, ContinuousDimension, Corrected, CountInterval, Effect, Forecast, Interval, LeastSquaresFit, LeastSquaresOptions, MedianInterval, NoiseOptions, NoiseState, NoiseVerdict, OrdinalDimension, ParsedResponseRecord, PermutationOptions, PermutationResult, Proportion, QuantileInterval, QuantileMethod, ResponseAbsentPoint, ResponseBand, ResponseCurvePoint, ResponseData, ResponseDimension, ResponseDimensionBase, ResponseFactor, ResponseFault, ResponseFitOptions, ResponseFold, ResponseFoldError, ResponseHeldOutError, ResponseInputValue, ResponseMeasure, ResponseModel, ResponseModelBase, ResponsePoint, ResponseReason, ResponseRecord, ResponseSlice, ResponseSliceOptions, ResponseSlicePoint, ResponseSurface, ResponseSurfaceAbsentPoint, ResponseSurfaceOptions, ResponseSurfacePoint, ResponseTableCell, ResponseValue, ResponseViewOptions, ResponseWhen, RidgeInput, RidgeInputBase, RidgeLevelInput, RidgeNumberInput, RidgeOptions, RidgeRankInput, RidgeResponseModel, RidgeTerm, Summary, TableResponseModel };
872
924
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/ridge.ts","../src/response.ts","../src/response-parse.ts","../src/response-fit.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/ridge.ts","../src/response.ts","../src/response-parse.ts","../src/response-fit.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"mappings":"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"}
package/build/index.js CHANGED
@@ -717,6 +717,12 @@ function heldValues(name, record, vary, hold, needed) {
717
717
  };
718
718
  return Object.fromEntries(others.map((d) => [d.id, valueOf(d)]));
719
719
  }
720
+ /** This function refuses a bad option `steps`. */
721
+ function checkSteps(name, steps) {
722
+ if (!Number.isSafeInteger(steps) || steps < 2) throw new RangeError(`${name}: steps is a whole number of 2 or more, not ${steps}.`);
723
+ }
724
+ /** This function gives a value inside a range. */
725
+ const clip = (value, [low, high]) => Math.min(high, Math.max(low, value));
720
726
  /** This function gives the values of an axis: each level, or `steps` equal distances on the scale of the dimension. */
721
727
  function axisValues(dimension, steps) {
722
728
  if (dimension.kind !== "continuous") return dimension.levels;
@@ -739,7 +745,7 @@ function matches(dimension, value, held, tolerance) {
739
745
  /** This function examines the request of a view, and it gives the parts that the two views share. */
740
746
  function frameOf(name, record, measure, vary, options) {
741
747
  const { hold = {}, steps = 33, tolerance = 0, width = 1 } = options;
742
- if (!Number.isSafeInteger(steps) || steps < 2) throw new RangeError(`${name}: steps is a whole number of 2 or more, not ${steps}.`);
748
+ checkSteps(name, steps);
743
749
  if (!(Number.isFinite(tolerance) && tolerance >= 0)) throw new RangeError(`${name}: tolerance is a finite number of 0 or more, not ${tolerance}.`);
744
750
  if (!(Number.isFinite(width) && width >= 0)) throw new RangeError(`${name}: width is a finite number of 0 or more, not ${width}.`);
745
751
  const model = record.models.find((m) => m.measure === measure);
@@ -765,14 +771,25 @@ function frameOf(name, record, measure, vary, options) {
765
771
  const missing = placed.filter((p) => typeof p.measures[measure] !== "number");
766
772
  const error = heldOutError(record, measure);
767
773
  const nearest = nearestOf(record.dimensions, record.points, measure);
774
+ const range = record.measures.find((m) => m.id === measure)?.range;
768
775
  const band = (inputs) => {
769
776
  const place = Object.fromEntries(record.dimensions.map((d) => [d.id, whenHolds(d, inputs) ? inputs[d.id] : null]));
770
777
  const value = predictScaled(model, place);
771
- return {
778
+ const fitted = {
772
779
  value: unscale(model, value),
773
780
  low: unscale(model, value - width * error.rmse),
774
- high: unscale(model, value + width * error.rmse),
775
- nearest: nearest(place)
781
+ high: unscale(model, value + width * error.rmse)
782
+ };
783
+ const inside = range === void 0 ? fitted : {
784
+ value: clip(fitted.value, range),
785
+ low: clip(fitted.low, range),
786
+ high: clip(fitted.high, range)
787
+ };
788
+ const moved = inside.value !== fitted.value || inside.low !== fitted.low || inside.high !== fitted.high;
789
+ return {
790
+ ...inside,
791
+ nearest: nearest(place),
792
+ ...moved ? { clipped: true } : {}
776
793
  };
777
794
  };
778
795
  return {
@@ -812,23 +829,28 @@ const reasonOf = (point, measure) => point.absent !== void 0 && Object.hasOwn(po
812
829
  * distance is on the log scale of the model, so the band is a ratio. The band has one width along all the curve. The
813
830
  * band is the mean error of the model, and `nearest` tells how far the place is from a measurement.
814
831
  *
832
+ * A measure with a `range` keeps each place inside it. The fields `value`, `low` and `high` move to the nearest end.
833
+ * The place then has the field `clipped`, and the field `clipped` of the view counts these places. The function
834
+ * `predictResponse` gives the value that the model fitted.
835
+ *
815
836
  * The function throws a RangeError for an unknown measure or dimension, and for a held value that is not good for its
816
837
  * dimension. It also throws for a dimension that is both varied and held, and for a bad option.
817
838
  */
818
839
  function sliceResponse(record, measure, options) {
819
840
  const { vary } = options;
820
841
  const { held, axes, matched, missing, error, band } = frameOf("sliceResponse", record, measure, [vary], options);
842
+ const curve = axes[0].map((at) => ({
843
+ at,
844
+ ...band({
845
+ ...held,
846
+ [vary]: at
847
+ })
848
+ }));
821
849
  return {
822
850
  measure,
823
851
  vary,
824
852
  held,
825
- curve: axes[0].map((at) => ({
826
- at,
827
- ...band({
828
- ...held,
829
- [vary]: at
830
- })
831
- })),
853
+ curve,
832
854
  points: matched.map((p) => ({
833
855
  id: p.id,
834
856
  at: p.values[vary],
@@ -841,7 +863,8 @@ function sliceResponse(record, measure, options) {
841
863
  reason: reasonOf(p, measure),
842
864
  ...groupOf(p)
843
865
  })),
844
- error
866
+ error,
867
+ clipped: curve.filter((place) => place.clipped === true).length
845
868
  };
846
869
  }
847
870
  /**
@@ -856,17 +879,18 @@ function surfaceResponse(record, measure, options) {
856
879
  const { held, axes, matched, missing, error, band } = frameOf("surfaceResponse", record, measure, vary, options);
857
880
  const x = axes[0];
858
881
  const y = axes[1];
882
+ const cells = y.map((b) => x.map((a) => band({
883
+ ...held,
884
+ [xId]: a,
885
+ [yId]: b
886
+ })));
859
887
  return {
860
888
  measure,
861
889
  vary,
862
890
  held,
863
891
  x,
864
892
  y,
865
- cells: y.map((b) => x.map((a) => band({
866
- ...held,
867
- [xId]: a,
868
- [yId]: b
869
- }))),
893
+ cells,
870
894
  points: matched.map((p) => ({
871
895
  id: p.id,
872
896
  at: [p.values[xId], p.values[yId]],
@@ -879,9 +903,27 @@ function surfaceResponse(record, measure, options) {
879
903
  reason: reasonOf(p, measure),
880
904
  ...groupOf(p)
881
905
  })),
882
- error
906
+ error,
907
+ clipped: cells.flat().filter((place) => place.clipped === true).length
883
908
  };
884
909
  }
910
+ /**
911
+ * This function gives the number of fitted places of a view before the view starts: the product of the lengths of its
912
+ * axes. A level axis counts its levels, and a continuous axis counts `steps`. The field `nearest` reads each point at
913
+ * each place, so the reads of a view are this count times the number of points. The default of `steps` is the default
914
+ * of a view. The function throws a RangeError for an unknown dimension, for one dimension named two times, and for a
915
+ * bad `steps`.
916
+ */
917
+ function responseCells(record, vary, steps = 33) {
918
+ checkSteps("responseCells", steps);
919
+ const ids = typeof vary === "string" ? [vary] : vary;
920
+ if (new Set(ids).size !== ids.length) throw new RangeError(`responseCells: the two varied dimensions are one dimension, "${ids[0]}".`);
921
+ return ids.reduce((count, id) => {
922
+ const dimension = record.dimensions.find((d) => d.id === id);
923
+ if (dimension === void 0) throw new RangeError(`responseCells: the record has no dimension "${id}".`);
924
+ return count * (dimension.kind === "continuous" ? steps : dimension.levels.length);
925
+ }, 1);
926
+ }
885
927
  // src/response-parse.ts
886
928
  /**
887
929
  * The validator of the format `response-records/1`. The functions here read unknown data and write faults. Thus a page
@@ -985,9 +1027,7 @@ function checkDimension(value, path, faults) {
985
1027
  need(!Object.hasOwn(object, "levels"), at(path, "levels"), "a continuous dimension has a range, not levels.", faults);
986
1028
  need(!Object.hasOwn(object, "range") || !log || !isNumber(peek(object["range"], "0")) || peek(object["range"], "0") > 0, at(path, "range"), "a log dimension has a range above 0.", faults);
987
1029
  need(Object.hasOwn(object, "range"), at(path, "range"), "this field is missing.", faults);
988
- const range = object["range"];
989
- const good = Array.isArray(range) && range.length === 2 && isNumber(range[0]) && isNumber(range[1]) && range[0] < range[1];
990
- if (Object.hasOwn(object, "range")) need(good, at(path, "range"), `this is a low and a high finite number, with low less than high, not ${shown(range)}.`, faults);
1030
+ if (Object.hasOwn(object, "range")) checkRange(object["range"], at(path, "range"), faults);
991
1031
  } else if (kind === "ordinal" || kind === "categorical") {
992
1032
  need(!Object.hasOwn(object, "range"), at(path, "range"), `a dimension of the kind ${kind} has levels, not a range.`, faults);
993
1033
  need(kind === "ordinal" || !Object.hasOwn(object, "log"), at(path, "log"), "a categorical dimension has no log scale.", faults);
@@ -1021,6 +1061,10 @@ function checkWhen(value, path, dimensions, faults) {
1021
1061
  if (!Array.isArray(known)) return;
1022
1062
  levels.forEach((level, i) => need(known.includes(level), `${at(path, "levels")}[${i}]`, `the dimension ${shown(id)} has no level ${shown(level)}.`, faults));
1023
1063
  }
1064
+ /** This function examines a range. */
1065
+ function checkRange(range, path, faults) {
1066
+ need(Array.isArray(range) && range.length === 2 && isNumber(range[0]) && isNumber(range[1]) && range[0] < range[1], path, `this is a low and a high finite number, with low less than high, not ${shown(range)}.`, faults);
1067
+ }
1024
1068
  /** This function examines one measure. */
1025
1069
  function checkMeasure(value, path, faults) {
1026
1070
  const object = fields(value, path, [
@@ -1028,12 +1072,21 @@ function checkMeasure(value, path, faults) {
1028
1072
  "label",
1029
1073
  "unit",
1030
1074
  "direction"
1031
- ], [], faults);
1075
+ ], ["range"], faults);
1032
1076
  if (object === void 0) return;
1033
1077
  check(object, "id", path, isId, "text with one character or more", faults);
1034
1078
  check(object, "label", path, isString, "text", faults);
1035
1079
  check(object, "unit", path, isString, "text", faults);
1036
1080
  check(object, "direction", path, (v) => v === "higher" || v === "lower" || v === "none", `"higher", "lower" or "none"`, faults);
1081
+ if (Object.hasOwn(object, "range")) checkRange(object["range"], at(path, "range"), faults);
1082
+ }
1083
+ /** This function refuses a measured value outside the range of its measure. */
1084
+ function checkMeasured(point, path, measures, faults) {
1085
+ for (const { id, range } of measures) {
1086
+ const value = peek(peek(point, "measures"), id);
1087
+ if (range === void 0 || typeof value !== "number") continue;
1088
+ need(value >= range[0] && value <= range[1], at(at(path, "measures"), id), `this value is outside the range of the measure, [${range[0]}, ${range[1]}].`, faults);
1089
+ }
1037
1090
  }
1038
1091
  /** This function examines one declared reason. */
1039
1092
  function checkReason(value, path, faults) {
@@ -1125,6 +1178,8 @@ function responseDataFaults(value, required, optional) {
1125
1178
  const points = list(object["points"], "points", 1, faults);
1126
1179
  points.forEach((p, i) => checkPoint(p, `points[${i}]`, dimensions, measureIds, reasonIds, faults));
1127
1180
  uniqueIds(points, "points", faults);
1181
+ if (faults.length > 0) return faults;
1182
+ points.forEach((p, i) => checkMeasured(p, `points[${i}]`, measures, faults));
1128
1183
  return faults;
1129
1184
  }
1130
1185
  /** This function examines one input of a ridge model against the dimensions of the record. */
@@ -2074,8 +2129,8 @@ function kendallTau(a, b, seed = 1) {
2074
2129
  }
2075
2130
  // src/discrete.ts
2076
2131
  /**
2077
- * The intervals that come from a discrete distribution. The interval of a median comes from the order statistics.
2078
- * The central interval of a count comes from a binomial or a negative binomial distribution.
2132
+ * The intervals that come from a discrete distribution. The interval of a median or of a quantile comes from the order
2133
+ * statistics. The central interval of a count comes from a binomial or a negative binomial distribution.
2079
2134
  */
2080
2135
  function whole(name, value) {
2081
2136
  if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name}: ${value} is not a whole number of 0 or more.`);
@@ -2129,6 +2184,58 @@ function medianInterval(values, level = .95) {
2129
2184
  };
2130
2185
  }
2131
2186
  /**
2187
+ * This function gives the distribution-free interval of the quantile `p` of a sample. Each tail outside the interval holds
2188
+ * (1 - level) / 2 or less. Let X ~ Binomial(n, p). The lower rank is the largest l with P(X <= l - 1) in the tail. The upper
2189
+ * rank is the smallest u with P(X >= u) in the tail. The values must be independent draws, or the coverage is false.
2190
+ *
2191
+ * A side with no such rank is infinite. Thus a small sample gives no upper bound: refer to `quantileSamples`.
2192
+ */
2193
+ function quantileInterval(values, p, level = .95) {
2194
+ if (values.length === 0) throw new RangeError("quantileInterval: the list is empty.");
2195
+ for (const v of values) if (Number.isNaN(v)) throw new RangeError("quantileInterval: the list has a NaN.");
2196
+ if (!(p > 0 && p < 1)) throw new RangeError(`quantileInterval: p is more than 0 and less than 1, not ${p}.`);
2197
+ const tail = levelOf("quantileInterval", level);
2198
+ const s = sorted(values);
2199
+ const n = s.length;
2200
+ const terms = binomialTerms(n, p);
2201
+ let lowRank = 0;
2202
+ let left = 0;
2203
+ let below = terms[0];
2204
+ while (lowRank < n && below <= tail) {
2205
+ lowRank += 1;
2206
+ left = below;
2207
+ below += terms[lowRank];
2208
+ }
2209
+ let highRank = n + 1;
2210
+ let right = 0;
2211
+ let above = terms[n];
2212
+ while (highRank > 1 && above <= tail) {
2213
+ highRank -= 1;
2214
+ right = above;
2215
+ above += terms[highRank - 1];
2216
+ }
2217
+ return {
2218
+ low: lowRank === 0 ? -Infinity : s[lowRank - 1],
2219
+ high: highRank === n + 1 ? Infinity : s[highRank - 1],
2220
+ lowRank,
2221
+ highRank,
2222
+ coverage: Math.max(0, 1 - left - right)
2223
+ };
2224
+ }
2225
+ /**
2226
+ * This function gives the fewest independent values that give the quantile `p` an upper bound at `level`: the smallest n with
2227
+ * p^n <= (1 - level) / 2. With that n, the upper bound is the largest value. At the level 0.95, p95 needs 72 values, p99 needs
2228
+ * 368 values and p99.9 needs 3,688 values.
2229
+ */
2230
+ function quantileSamples(p, level = .95) {
2231
+ if (!(p > 0 && p < 1)) throw new RangeError(`quantileSamples: p is more than 0 and less than 1, not ${p}.`);
2232
+ const tail = levelOf("quantileSamples", level);
2233
+ const [logTail, logP] = [Math.log(tail), Math.log(p)];
2234
+ let n = Math.max(1, Math.ceil(logTail / logP));
2235
+ while (n > 1 && (n - 1) * logP <= logTail) n -= 1;
2236
+ return n;
2237
+ }
2238
+ /**
2132
2239
  * The central interval of a count X ~ Binomial(n, p). `low` is the smallest k with P(X <= k) > (1 - level) / 2.
2133
2240
  * `high` is the largest k with P(X >= k) > (1 - level) / 2. Each tail outside the interval holds (1 - level) / 2
2134
2241
  * or less. The two tails are separate sums, so that a small upper tail keeps its digits.
@@ -2327,6 +2434,6 @@ function calibration(forecasts) {
2327
2434
  interval: wilson(hits, n)
2328
2435
  }));
2329
2436
  }
2330
- export { KENDALL_EXACT, RESPONSE_LAMBDAS, RESPONSE_MAX_POWER, RESPONSE_MAX_TERMS, RESPONSE_RECORDS_SCHEMA, Z95, binomialInterval, bootstrap, bootstrapClusters, bootstrapLeastSquares, bootstrapMedian, bootstrapMedianRatio, bootstrapTwo, brier, calibration, compareRatios, fitResponse, heldOutError, heldOutErrorAt, holm, kendallTau, leastSquares, mean, median, medianInterval, negativeBinomialInterval, noiseFloor, noiseVerdict, pairedPermutation, parseResponseRecord, predictResponse, quantile, quantileSorted, ranks, ridgeSolve, sd, signTest, signTestPower, sliceResponse, sorted, spearman, summarize, surfaceResponse, wilson };
2437
+ export { KENDALL_EXACT, RESPONSE_LAMBDAS, RESPONSE_MAX_POWER, RESPONSE_MAX_TERMS, RESPONSE_RECORDS_SCHEMA, Z95, binomialInterval, bootstrap, bootstrapClusters, bootstrapLeastSquares, bootstrapMedian, bootstrapMedianRatio, bootstrapTwo, brier, calibration, compareRatios, fitResponse, heldOutError, heldOutErrorAt, holm, kendallTau, leastSquares, mean, median, medianInterval, negativeBinomialInterval, noiseFloor, noiseVerdict, pairedPermutation, parseResponseRecord, predictResponse, quantile, quantileInterval, quantileSamples, quantileSorted, ranks, responseCells, ridgeSolve, sd, signTest, signTestPower, sliceResponse, sorted, spearman, summarize, surfaceResponse, whenHolds, wilson };
2331
2438
 
2332
2439
  //# sourceMappingURL=index.js.map