@sipemu/anofox-forecast 0.4.9 → 0.5.1

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.
@@ -12,6 +12,71 @@ function _assertClass(instance, klass) {
12
12
  }
13
13
  }
14
14
 
15
+ function debugString(val) {
16
+ // primitive types
17
+ const type = typeof val;
18
+ if (type == 'number' || type == 'boolean' || val == null) {
19
+ return `${val}`;
20
+ }
21
+ if (type == 'string') {
22
+ return `"${val}"`;
23
+ }
24
+ if (type == 'symbol') {
25
+ const description = val.description;
26
+ if (description == null) {
27
+ return 'Symbol';
28
+ } else {
29
+ return `Symbol(${description})`;
30
+ }
31
+ }
32
+ if (type == 'function') {
33
+ const name = val.name;
34
+ if (typeof name == 'string' && name.length > 0) {
35
+ return `Function(${name})`;
36
+ } else {
37
+ return 'Function';
38
+ }
39
+ }
40
+ // objects
41
+ if (Array.isArray(val)) {
42
+ const length = val.length;
43
+ let debug = '[';
44
+ if (length > 0) {
45
+ debug += debugString(val[0]);
46
+ }
47
+ for(let i = 1; i < length; i++) {
48
+ debug += ', ' + debugString(val[i]);
49
+ }
50
+ debug += ']';
51
+ return debug;
52
+ }
53
+ // Test for built-in
54
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
55
+ let className;
56
+ if (builtInMatches && builtInMatches.length > 1) {
57
+ className = builtInMatches[1];
58
+ } else {
59
+ // Failed to match the standard '[object ClassName]'
60
+ return toString.call(val);
61
+ }
62
+ if (className == 'Object') {
63
+ // we're a user defined class or Object
64
+ // JSON.stringify avoids problems with cycles, and is generally much
65
+ // easier than looping through ownProperties of `val`.
66
+ try {
67
+ return 'Object(' + JSON.stringify(val) + ')';
68
+ } catch (_) {
69
+ return 'Object';
70
+ }
71
+ }
72
+ // errors
73
+ if (val instanceof Error) {
74
+ return `${val.name}: ${val.message}\n${val.stack}`;
75
+ }
76
+ // TODO we could test for more things here, like `Set`s and `Map`s.
77
+ return className;
78
+ }
79
+
15
80
  function getArrayF64FromWasm0(ptr, len) {
16
81
  ptr = ptr >>> 0;
17
82
  return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
@@ -224,6 +289,10 @@ const EnsembleForecasterFinalization = (typeof FinalizationRegistry === 'undefin
224
289
  ? { register: () => {}, unregister: () => {} }
225
290
  : new FinalizationRegistry(ptr => wasm.__wbg_ensembleforecaster_free(ptr >>> 0, 1));
226
291
 
292
+ const FeatureGeneratorFinalization = (typeof FinalizationRegistry === 'undefined')
293
+ ? { register: () => {}, unregister: () => {} }
294
+ : new FinalizationRegistry(ptr => wasm.__wbg_featuregenerator_free(ptr >>> 0, 1));
295
+
227
296
  const ForecastFinalization = (typeof FinalizationRegistry === 'undefined')
228
297
  ? { register: () => {}, unregister: () => {} }
229
298
  : new FinalizationRegistry(ptr => wasm.__wbg_forecast_free(ptr >>> 0, 1));
@@ -252,6 +321,14 @@ const JsBacktestResultFinalization = (typeof FinalizationRegistry === 'undefined
252
321
  ? { register: () => {}, unregister: () => {} }
253
322
  : new FinalizationRegistry(ptr => wasm.__wbg_jsbacktestresult_free(ptr >>> 0, 1));
254
323
 
324
+ const JsBootstrapPredictorFinalization = (typeof FinalizationRegistry === 'undefined')
325
+ ? { register: () => {}, unregister: () => {} }
326
+ : new FinalizationRegistry(ptr => wasm.__wbg_jsbootstrappredictor_free(ptr >>> 0, 1));
327
+
328
+ const JsBootstrapResultFinalization = (typeof FinalizationRegistry === 'undefined')
329
+ ? { register: () => {}, unregister: () => {} }
330
+ : new FinalizationRegistry(ptr => wasm.__wbg_jsbootstrapresult_free(ptr >>> 0, 1));
331
+
255
332
  const JsConformalPredictorFinalization = (typeof FinalizationRegistry === 'undefined')
256
333
  ? { register: () => {}, unregister: () => {} }
257
334
  : new FinalizationRegistry(ptr => wasm.__wbg_jsconformalpredictor_free(ptr >>> 0, 1));
@@ -280,6 +357,10 @@ const JsNormalResultFinalization = (typeof FinalizationRegistry === 'undefined')
280
357
  ? { register: () => {}, unregister: () => {} }
281
358
  : new FinalizationRegistry(ptr => wasm.__wbg_jsnormalresult_free(ptr >>> 0, 1));
282
359
 
360
+ const JsPerStepConformalResultFinalization = (typeof FinalizationRegistry === 'undefined')
361
+ ? { register: () => {}, unregister: () => {} }
362
+ : new FinalizationRegistry(ptr => wasm.__wbg_jsperstepconformalresult_free(ptr >>> 0, 1));
363
+
283
364
  const JsPointForecastsFinalization = (typeof FinalizationRegistry === 'undefined')
284
365
  ? { register: () => {}, unregister: () => {} }
285
366
  : new FinalizationRegistry(ptr => wasm.__wbg_jspointforecasts_free(ptr >>> 0, 1));
@@ -1953,6 +2034,162 @@ export class EnsembleForecaster {
1953
2034
  }
1954
2035
  if (Symbol.dispose) EnsembleForecaster.prototype[Symbol.dispose] = EnsembleForecaster.prototype.free;
1955
2036
 
2037
+ /**
2038
+ * Deterministic feature generator for timestamp-based regressors.
2039
+ *
2040
+ * Builds Fourier terms, one-hot calendar indicators, cyclical sin/cos
2041
+ * encodings, binary flags and advanced numeric features from timestamps
2042
+ * alone. Because features are purely deterministic they are safe for
2043
+ * cross-validation and can be shared across models.
2044
+ *
2045
+ * Use the builder pattern to configure features, then call `generate()`
2046
+ * to produce a JS object mapping feature names to `Float64Array` values.
2047
+ *
2048
+ * @example
2049
+ * ```js
2050
+ * const gen = new FeatureGenerator();
2051
+ * gen.fourier(7, 3);
2052
+ * gen.dayOfWeek();
2053
+ * gen.cyclical("month");
2054
+ * gen.binary("weekend");
2055
+ * gen.advanced("days_in_month");
2056
+ *
2057
+ * const features = gen.generate(timestamps); // { fourier_7_sin1: [...], ... }
2058
+ * const names = gen.featureNames(); // sorted array of column names
2059
+ * ```
2060
+ */
2061
+ export class FeatureGenerator {
2062
+ __destroy_into_raw() {
2063
+ const ptr = this.__wbg_ptr;
2064
+ this.__wbg_ptr = 0;
2065
+ FeatureGeneratorFinalization.unregister(this);
2066
+ return ptr;
2067
+ }
2068
+ free() {
2069
+ const ptr = this.__destroy_into_raw();
2070
+ wasm.__wbg_featuregenerator_free(ptr, 0);
2071
+ }
2072
+ /**
2073
+ * Add day-of-week one-hot indicators (Mon-Sat, Sunday dropped).
2074
+ */
2075
+ dayOfWeek() {
2076
+ wasm.featuregenerator_dayOfWeek(this.__wbg_ptr);
2077
+ }
2078
+ /**
2079
+ * Return the sorted list of column names this generator will produce.
2080
+ *
2081
+ * @returns Array of feature name strings
2082
+ * @returns {any}
2083
+ */
2084
+ featureNames() {
2085
+ const ret = wasm.featuregenerator_featureNames(this.__wbg_ptr);
2086
+ if (ret[2]) {
2087
+ throw takeFromExternrefTable0(ret[1]);
2088
+ }
2089
+ return takeFromExternrefTable0(ret[0]);
2090
+ }
2091
+ /**
2092
+ * Add month-of-year one-hot indicators (Feb-Dec, January dropped).
2093
+ */
2094
+ monthOfYear() {
2095
+ wasm.featuregenerator_monthOfYear(this.__wbg_ptr);
2096
+ }
2097
+ /**
2098
+ * Create an empty feature generator.
2099
+ */
2100
+ constructor() {
2101
+ const ret = wasm.featuregenerator_new();
2102
+ this.__wbg_ptr = ret >>> 0;
2103
+ FeatureGeneratorFinalization.register(this, this.__wbg_ptr, this);
2104
+ return this;
2105
+ }
2106
+ /**
2107
+ * Add a binary (0/1) calendar indicator.
2108
+ *
2109
+ * @param indicator - One of: "weekend", "month_start", "month_end",
2110
+ * "quarter_start", "quarter_end", "year_start", "year_end"
2111
+ * @param {string} indicator
2112
+ */
2113
+ binary(indicator) {
2114
+ const ptr0 = passStringToWasm0(indicator, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2115
+ const len0 = WASM_VECTOR_LEN;
2116
+ const ret = wasm.featuregenerator_binary(this.__wbg_ptr, ptr0, len0);
2117
+ if (ret[1]) {
2118
+ throw takeFromExternrefTable0(ret[0]);
2119
+ }
2120
+ }
2121
+ /**
2122
+ * Add Fourier terms for a given period and order.
2123
+ *
2124
+ * Produces `2 * order` columns (`fourier_{period}_sin{k}`,
2125
+ * `fourier_{period}_cos{k}` for k in 1..=order).
2126
+ *
2127
+ * @param period - Period in observation units (e.g. 7 for weekly in daily data)
2128
+ * @param order - Number of harmonics
2129
+ * @param {number} period
2130
+ * @param {number} order
2131
+ */
2132
+ fourier(period, order) {
2133
+ wasm.featuregenerator_fourier(this.__wbg_ptr, period, order);
2134
+ }
2135
+ /**
2136
+ * Add quarter one-hot indicators (Q2-Q4, Q1 dropped).
2137
+ */
2138
+ quarter() {
2139
+ wasm.featuregenerator_quarter(this.__wbg_ptr);
2140
+ }
2141
+ /**
2142
+ * Add an advanced numeric calendar feature.
2143
+ *
2144
+ * @param feature - One of: "leap_year", "days_in_month"
2145
+ * @param {string} feature
2146
+ */
2147
+ advanced(feature) {
2148
+ const ptr0 = passStringToWasm0(feature, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2149
+ const len0 = WASM_VECTOR_LEN;
2150
+ const ret = wasm.featuregenerator_advanced(this.__wbg_ptr, ptr0, len0);
2151
+ if (ret[1]) {
2152
+ throw takeFromExternrefTable0(ret[0]);
2153
+ }
2154
+ }
2155
+ /**
2156
+ * Add cyclical sin/cos encoding of a time component.
2157
+ *
2158
+ * Produces 2 columns: `{name}_sin` and `{name}_cos`.
2159
+ *
2160
+ * @param component - One of: "month", "quarter", "semester",
2161
+ * "week_of_year", "day_of_week", "day_of_month", "day_of_year",
2162
+ * "hour", "minute", "second"
2163
+ * @param {string} component
2164
+ */
2165
+ cyclical(component) {
2166
+ const ptr0 = passStringToWasm0(component, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
2167
+ const len0 = WASM_VECTOR_LEN;
2168
+ const ret = wasm.featuregenerator_cyclical(this.__wbg_ptr, ptr0, len0);
2169
+ if (ret[1]) {
2170
+ throw takeFromExternrefTable0(ret[0]);
2171
+ }
2172
+ }
2173
+ /**
2174
+ * Generate features for the given timestamps.
2175
+ *
2176
+ * @param timestamps - Array of timestamps as milliseconds since Unix epoch
2177
+ * @returns Object mapping feature names to Float64Array values
2178
+ * @param {Float64Array} timestamps
2179
+ * @returns {any}
2180
+ */
2181
+ generate(timestamps) {
2182
+ const ptr0 = passArrayF64ToWasm0(timestamps, wasm.__wbindgen_malloc);
2183
+ const len0 = WASM_VECTOR_LEN;
2184
+ const ret = wasm.featuregenerator_generate(this.__wbg_ptr, ptr0, len0);
2185
+ if (ret[2]) {
2186
+ throw takeFromExternrefTable0(ret[1]);
2187
+ }
2188
+ return takeFromExternrefTable0(ret[0]);
2189
+ }
2190
+ }
2191
+ if (Symbol.dispose) FeatureGenerator.prototype[Symbol.dispose] = FeatureGenerator.prototype.free;
2192
+
1956
2193
  /**
1957
2194
  * Forecast result wrapper for JavaScript.
1958
2195
  *
@@ -2548,6 +2785,198 @@ export class JsBacktestResult {
2548
2785
  }
2549
2786
  if (Symbol.dispose) JsBacktestResult.prototype[Symbol.dispose] = JsBacktestResult.prototype.free;
2550
2787
 
2788
+ /**
2789
+ * Bootstrap predictor for distribution-free prediction intervals.
2790
+ *
2791
+ * Resamples forecast residuals to simulate future error paths, producing
2792
+ * per-step prediction intervals where uncertainty grows with horizon.
2793
+ */
2794
+ export class JsBootstrapPredictor {
2795
+ static __wrap(ptr) {
2796
+ ptr = ptr >>> 0;
2797
+ const obj = Object.create(JsBootstrapPredictor.prototype);
2798
+ obj.__wbg_ptr = ptr;
2799
+ JsBootstrapPredictorFinalization.register(obj, obj.__wbg_ptr, obj);
2800
+ return obj;
2801
+ }
2802
+ __destroy_into_raw() {
2803
+ const ptr = this.__wbg_ptr;
2804
+ this.__wbg_ptr = 0;
2805
+ JsBootstrapPredictorFinalization.unregister(this);
2806
+ return ptr;
2807
+ }
2808
+ free() {
2809
+ const ptr = this.__destroy_into_raw();
2810
+ wasm.__wbg_jsbootstrappredictor_free(ptr, 0);
2811
+ }
2812
+ /**
2813
+ * Use block bootstrap with the given block size.
2814
+ *
2815
+ * Preserves autocorrelation in residuals.
2816
+ *
2817
+ * @param size - Block size (0 falls back to IID)
2818
+ * @param {number} size
2819
+ * @returns {JsBootstrapPredictor}
2820
+ */
2821
+ blockSize(size) {
2822
+ const ptr = this.__destroy_into_raw();
2823
+ const ret = wasm.jsbootstrappredictor_blockSize(ptr, size);
2824
+ return JsBootstrapPredictor.__wrap(ret);
2825
+ }
2826
+ /**
2827
+ * Set the number of bootstrap replicates (default: 1000).
2828
+ *
2829
+ * @param n - Number of replicates (minimum 10)
2830
+ * @param {number} n
2831
+ * @returns {JsBootstrapPredictor}
2832
+ */
2833
+ nReplicates(n) {
2834
+ const ptr = this.__destroy_into_raw();
2835
+ const ret = wasm.jsbootstrappredictor_nReplicates(ptr, n);
2836
+ return JsBootstrapPredictor.__wrap(ret);
2837
+ }
2838
+ /**
2839
+ * Generate prediction intervals for new point forecasts.
2840
+ *
2841
+ * Returns a JsPredictionIntervals with lower and upper bounds.
2842
+ *
2843
+ * @param result - A fitted JsBootstrapResult from fit()
2844
+ * @param pointForecasts - New point forecast values
2845
+ * @param {JsBootstrapResult} result
2846
+ * @param {Float64Array} point_forecasts
2847
+ * @returns {JsPredictionIntervals}
2848
+ */
2849
+ predictIntervals(result, point_forecasts) {
2850
+ _assertClass(result, JsBootstrapResult);
2851
+ const ptr0 = passArrayF64ToWasm0(point_forecasts, wasm.__wbindgen_malloc);
2852
+ const len0 = WASM_VECTOR_LEN;
2853
+ const ret = wasm.jsbootstrappredictor_predictIntervals(this.__wbg_ptr, result.__wbg_ptr, ptr0, len0);
2854
+ return JsPredictionIntervals.__wrap(ret);
2855
+ }
2856
+ /**
2857
+ * Generate quantile forecasts at multiple quantile levels.
2858
+ *
2859
+ * Returns a serialized object with `quantiles` (levels) and `values` (matrix).
2860
+ *
2861
+ * @param result - A fitted JsBootstrapResult from fit()
2862
+ * @param pointForecasts - New point forecast values
2863
+ * @param levels - Quantile levels in (0, 1), e.g. [0.1, 0.25, 0.5, 0.75, 0.9]
2864
+ * @param {JsBootstrapResult} result
2865
+ * @param {Float64Array} point_forecasts
2866
+ * @param {Float64Array} levels
2867
+ * @returns {any}
2868
+ */
2869
+ predictQuantiles(result, point_forecasts, levels) {
2870
+ _assertClass(result, JsBootstrapResult);
2871
+ const ptr0 = passArrayF64ToWasm0(point_forecasts, wasm.__wbindgen_malloc);
2872
+ const len0 = WASM_VECTOR_LEN;
2873
+ const ptr1 = passArrayF64ToWasm0(levels, wasm.__wbindgen_malloc);
2874
+ const len1 = WASM_VECTOR_LEN;
2875
+ const ret = wasm.jsbootstrappredictor_predictQuantiles(this.__wbg_ptr, result.__wbg_ptr, ptr0, len0, ptr1, len1);
2876
+ if (ret[2]) {
2877
+ throw takeFromExternrefTable0(ret[1]);
2878
+ }
2879
+ return takeFromExternrefTable0(ret[0]);
2880
+ }
2881
+ /**
2882
+ * Fit the predictor on historical forecasts and actuals.
2883
+ *
2884
+ * Computes residuals and stores them for resampling.
2885
+ *
2886
+ * @param forecasts - Historical point forecast values
2887
+ * @param actuals - Corresponding actual observed values
2888
+ * @param {Float64Array} forecasts
2889
+ * @param {Float64Array} actuals
2890
+ * @returns {JsBootstrapResult}
2891
+ */
2892
+ fit(forecasts, actuals) {
2893
+ const ptr0 = passArrayF64ToWasm0(forecasts, wasm.__wbindgen_malloc);
2894
+ const len0 = WASM_VECTOR_LEN;
2895
+ const ptr1 = passArrayF64ToWasm0(actuals, wasm.__wbindgen_malloc);
2896
+ const len1 = WASM_VECTOR_LEN;
2897
+ const ret = wasm.jsbootstrappredictor_fit(this.__wbg_ptr, ptr0, len0, ptr1, len1);
2898
+ if (ret[2]) {
2899
+ throw takeFromExternrefTable0(ret[1]);
2900
+ }
2901
+ return JsBootstrapResult.__wrap(ret[0]);
2902
+ }
2903
+ /**
2904
+ * Create a bootstrap predictor with the given coverage level.
2905
+ *
2906
+ * @param coverage - Target coverage level in (0, 1), e.g. 0.90
2907
+ * @param {number} coverage
2908
+ */
2909
+ constructor(coverage) {
2910
+ const ret = wasm.jsbootstrappredictor_new(coverage);
2911
+ this.__wbg_ptr = ret >>> 0;
2912
+ JsBootstrapPredictorFinalization.register(this, this.__wbg_ptr, this);
2913
+ return this;
2914
+ }
2915
+ /**
2916
+ * Set random seed for reproducibility.
2917
+ *
2918
+ * @param seed - Random seed value
2919
+ * @param {bigint} seed
2920
+ * @returns {JsBootstrapPredictor}
2921
+ */
2922
+ seed(seed) {
2923
+ const ptr = this.__destroy_into_raw();
2924
+ const ret = wasm.jsbootstrappredictor_seed(ptr, seed);
2925
+ return JsBootstrapPredictor.__wrap(ret);
2926
+ }
2927
+ }
2928
+ if (Symbol.dispose) JsBootstrapPredictor.prototype[Symbol.dispose] = JsBootstrapPredictor.prototype.free;
2929
+
2930
+ /**
2931
+ * Bootstrap result — stores residuals and configuration from fitting.
2932
+ */
2933
+ export class JsBootstrapResult {
2934
+ static __wrap(ptr) {
2935
+ ptr = ptr >>> 0;
2936
+ const obj = Object.create(JsBootstrapResult.prototype);
2937
+ obj.__wbg_ptr = ptr;
2938
+ JsBootstrapResultFinalization.register(obj, obj.__wbg_ptr, obj);
2939
+ return obj;
2940
+ }
2941
+ __destroy_into_raw() {
2942
+ const ptr = this.__wbg_ptr;
2943
+ this.__wbg_ptr = 0;
2944
+ JsBootstrapResultFinalization.unregister(this);
2945
+ return ptr;
2946
+ }
2947
+ free() {
2948
+ const ptr = this.__destroy_into_raw();
2949
+ wasm.__wbg_jsbootstrapresult_free(ptr, 0);
2950
+ }
2951
+ /**
2952
+ * Get the number of replicates.
2953
+ * @returns {number}
2954
+ */
2955
+ get nReplicates() {
2956
+ const ret = wasm.jsbootstrapresult_nReplicates(this.__wbg_ptr);
2957
+ return ret >>> 0;
2958
+ }
2959
+ /**
2960
+ * Get the coverage level.
2961
+ * @returns {number}
2962
+ */
2963
+ get coverage() {
2964
+ const ret = wasm.jsbootstrapresult_coverage(this.__wbg_ptr);
2965
+ return ret;
2966
+ }
2967
+ /**
2968
+ * Get the residuals used for resampling.
2969
+ * @returns {Float64Array}
2970
+ */
2971
+ residuals() {
2972
+ const ret = wasm.jsbootstrapresult_residuals(this.__wbg_ptr);
2973
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
2974
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
2975
+ return v1;
2976
+ }
2977
+ }
2978
+ if (Symbol.dispose) JsBootstrapResult.prototype[Symbol.dispose] = JsBootstrapResult.prototype.free;
2979
+
2551
2980
  /**
2552
2981
  * Conformal predictor for distribution-free prediction intervals.
2553
2982
  *
@@ -2571,6 +3000,25 @@ export class JsConformalPredictor {
2571
3000
  const ptr = this.__destroy_into_raw();
2572
3001
  wasm.__wbg_jsconformalpredictor_free(ptr, 0);
2573
3002
  }
3003
+ /**
3004
+ * Fit per-horizon-step conformal intervals.
3005
+ *
3006
+ * Each horizon step gets its own interval half-width, allowing tighter
3007
+ * intervals for near-horizon steps and wider for far-horizon steps.
3008
+ *
3009
+ * @param foldForecasts - Per-fold forecast arrays (array of arrays), each of length `horizon`
3010
+ * @param foldActuals - Per-fold actual arrays (array of arrays), each of length `horizon`
3011
+ * @param {any} fold_forecasts
3012
+ * @param {any} fold_actuals
3013
+ * @returns {JsPerStepConformalResult}
3014
+ */
3015
+ fitPerStep(fold_forecasts, fold_actuals) {
3016
+ const ret = wasm.jsconformalpredictor_fitPerStep(this.__wbg_ptr, fold_forecasts, fold_actuals);
3017
+ if (ret[2]) {
3018
+ throw takeFromExternrefTable0(ret[1]);
3019
+ }
3020
+ return JsPerStepConformalResult.__wrap(ret[0]);
3021
+ }
2574
3022
  /**
2575
3023
  * Create a conformal predictor with the Jackknife+ method.
2576
3024
  *
@@ -2598,6 +3046,31 @@ export class JsConformalPredictor {
2598
3046
  const ret = wasm.jsconformalpredictor_predictIntervals(this.__wbg_ptr, result.__wbg_ptr, ptr0, len0);
2599
3047
  return JsPredictionIntervals.__wrap(ret);
2600
3048
  }
3049
+ /**
3050
+ * Generate quantile forecasts at multiple quantile levels.
3051
+ *
3052
+ * Returns a serialized object with `quantiles` (levels) and `values` (matrix).
3053
+ *
3054
+ * @param result - A fitted JsConformalResult from calibrate()
3055
+ * @param pointForecasts - New point forecast values
3056
+ * @param levels - Quantile levels in (0, 1), e.g. [0.1, 0.5, 0.9]
3057
+ * @param {JsConformalResult} result
3058
+ * @param {Float64Array} point_forecasts
3059
+ * @param {Float64Array} levels
3060
+ * @returns {any}
3061
+ */
3062
+ predictQuantiles(result, point_forecasts, levels) {
3063
+ _assertClass(result, JsConformalResult);
3064
+ const ptr0 = passArrayF64ToWasm0(point_forecasts, wasm.__wbindgen_malloc);
3065
+ const len0 = WASM_VECTOR_LEN;
3066
+ const ptr1 = passArrayF64ToWasm0(levels, wasm.__wbindgen_malloc);
3067
+ const len1 = WASM_VECTOR_LEN;
3068
+ const ret = wasm.jsconformalpredictor_predictQuantiles(this.__wbg_ptr, result.__wbg_ptr, ptr0, len0, ptr1, len1);
3069
+ if (ret[2]) {
3070
+ throw takeFromExternrefTable0(ret[1]);
3071
+ }
3072
+ return takeFromExternrefTable0(ret[0]);
3073
+ }
2601
3074
  /**
2602
3075
  * Create a split conformal predictor.
2603
3076
  *
@@ -2690,7 +3163,7 @@ export class JsConformalResult {
2690
3163
  * @returns {number}
2691
3164
  */
2692
3165
  get coverage() {
2693
- const ret = wasm.jsconformalresult_coverage(this.__wbg_ptr);
3166
+ const ret = wasm.jsbootstrapresult_coverage(this.__wbg_ptr);
2694
3167
  return ret;
2695
3168
  }
2696
3169
  }
@@ -2953,7 +3426,7 @@ export class JsModelDiagnostics {
2953
3426
  * @returns {number}
2954
3427
  */
2955
3428
  get heteroscedasticityPvalue() {
2956
- const ret = wasm.jsconformalresult_coverage(this.__wbg_ptr);
3429
+ const ret = wasm.jsbootstrapresult_coverage(this.__wbg_ptr);
2957
3430
  return ret;
2958
3431
  }
2959
3432
  /**
@@ -3090,6 +3563,92 @@ export class JsNormalResult {
3090
3563
  }
3091
3564
  if (Symbol.dispose) JsNormalResult.prototype[Symbol.dispose] = JsNormalResult.prototype.free;
3092
3565
 
3566
+ /**
3567
+ * Per-step conformal result — each horizon step has its own interval half-width.
3568
+ *
3569
+ * Step h=1 gets a tighter interval than step h=12 when forecast error grows
3570
+ * with horizon.
3571
+ */
3572
+ export class JsPerStepConformalResult {
3573
+ static __wrap(ptr) {
3574
+ ptr = ptr >>> 0;
3575
+ const obj = Object.create(JsPerStepConformalResult.prototype);
3576
+ obj.__wbg_ptr = ptr;
3577
+ JsPerStepConformalResultFinalization.register(obj, obj.__wbg_ptr, obj);
3578
+ return obj;
3579
+ }
3580
+ __destroy_into_raw() {
3581
+ const ptr = this.__wbg_ptr;
3582
+ this.__wbg_ptr = 0;
3583
+ JsPerStepConformalResultFinalization.unregister(this);
3584
+ return ptr;
3585
+ }
3586
+ free() {
3587
+ const ptr = this.__destroy_into_raw();
3588
+ wasm.__wbg_jsperstepconformalresult_free(ptr, 0);
3589
+ }
3590
+ /**
3591
+ * Get the per-step interval half-widths.
3592
+ * @returns {Float64Array}
3593
+ */
3594
+ get halfWidths() {
3595
+ const ret = wasm.jsperstepconformalresult_halfWidths(this.__wbg_ptr);
3596
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
3597
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
3598
+ return v1;
3599
+ }
3600
+ /**
3601
+ * Apply per-step intervals to a point forecast.
3602
+ *
3603
+ * Returns a JsPredictionIntervals with per-step lower and upper bounds.
3604
+ *
3605
+ * @param pointForecasts - Point forecast values (length must match horizon)
3606
+ * @param {Float64Array} point_forecasts
3607
+ * @returns {JsPredictionIntervals}
3608
+ */
3609
+ predictIntervals(point_forecasts) {
3610
+ const ptr0 = passArrayF64ToWasm0(point_forecasts, wasm.__wbindgen_malloc);
3611
+ const len0 = WASM_VECTOR_LEN;
3612
+ const ret = wasm.jsperstepconformalresult_predictIntervals(this.__wbg_ptr, ptr0, len0);
3613
+ return JsPredictionIntervals.__wrap(ret);
3614
+ }
3615
+ /**
3616
+ * Get the number of horizon steps.
3617
+ * @returns {number}
3618
+ */
3619
+ get horizon() {
3620
+ const ret = wasm.jsperstepconformalresult_horizon(this.__wbg_ptr);
3621
+ return ret >>> 0;
3622
+ }
3623
+ /**
3624
+ * Apply per-step intervals and return lower/upper as a plain object.
3625
+ *
3626
+ * Returns a serialized object with `lower` and `upper` arrays.
3627
+ *
3628
+ * @param pointForecasts - Point forecast values (length must match horizon)
3629
+ * @param {Float64Array} point_forecasts
3630
+ * @returns {any}
3631
+ */
3632
+ predict(point_forecasts) {
3633
+ const ptr0 = passArrayF64ToWasm0(point_forecasts, wasm.__wbindgen_malloc);
3634
+ const len0 = WASM_VECTOR_LEN;
3635
+ const ret = wasm.jsperstepconformalresult_predict(this.__wbg_ptr, ptr0, len0);
3636
+ if (ret[2]) {
3637
+ throw takeFromExternrefTable0(ret[1]);
3638
+ }
3639
+ return takeFromExternrefTable0(ret[0]);
3640
+ }
3641
+ /**
3642
+ * Get the coverage level.
3643
+ * @returns {number}
3644
+ */
3645
+ get coverage() {
3646
+ const ret = wasm.jsconformalresult_quantileValue(this.__wbg_ptr);
3647
+ return ret;
3648
+ }
3649
+ }
3650
+ if (Symbol.dispose) JsPerStepConformalResult.prototype[Symbol.dispose] = JsPerStepConformalResult.prototype.free;
3651
+
3093
3652
  /**
3094
3653
  * Point forecasts — a sequence of predicted values.
3095
3654
  *
@@ -3366,7 +3925,7 @@ if (Symbol.dispose) JsTrainedModel.prototype[Symbol.dispose] = JsTrainedModel.pr
3366
3925
  /**
3367
3926
  * Kalman filter forecaster for state-space models.
3368
3927
  *
3369
- * Supports local level and local linear trend models out of the box.
3928
+ * Supports local level, local linear trend, and custom state-space models.
3370
3929
  */
3371
3930
  export class KalmanForecaster {
3372
3931
  static __wrap(ptr) {
@@ -3399,6 +3958,22 @@ export class KalmanForecaster {
3399
3958
  const ret = wasm.kalmanforecaster_localLevel(obs_noise, state_noise);
3400
3959
  return KalmanForecaster.__wrap(ret);
3401
3960
  }
3961
+ /**
3962
+ * Compute the log-likelihood of the observations under the model.
3963
+ *
3964
+ * @param series - TimeSeries to evaluate
3965
+ * @returns Log-likelihood value
3966
+ * @param {TimeSeries} series
3967
+ * @returns {number}
3968
+ */
3969
+ logLikelihood(series) {
3970
+ _assertClass(series, TimeSeries);
3971
+ const ret = wasm.kalmanforecaster_logLikelihood(this.__wbg_ptr, series.__wbg_ptr);
3972
+ if (ret[2]) {
3973
+ throw takeFromExternrefTable0(ret[1]);
3974
+ }
3975
+ return ret[0];
3976
+ }
3402
3977
  /**
3403
3978
  * Create a local linear trend model.
3404
3979
  *
@@ -3460,9 +4035,52 @@ export class KalmanForecaster {
3460
4035
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
3461
4036
  }
3462
4037
  }
4038
+ /**
4039
+ * Get the number of observation dimensions.
4040
+ * @returns {number}
4041
+ */
4042
+ get nObs() {
4043
+ const ret = wasm.kalmanforecaster_nObs(this.__wbg_ptr);
4044
+ return ret >>> 0;
4045
+ }
4046
+ /**
4047
+ * Create a custom state-space model from matrices.
4048
+ *
4049
+ * @param transition - State transition matrix F (n_state x n_state), flat row-major
4050
+ * @param observation - Observation matrix H (n_obs x n_state), flat row-major
4051
+ * @param processNoise - Process noise covariance Q (n_state x n_state), flat row-major
4052
+ * @param observationNoise - Observation noise covariance R (n_obs x n_obs), flat row-major
4053
+ * @param nState - Number of state dimensions
4054
+ * @param nObs - Number of observation dimensions
4055
+ * @param {Float64Array} transition
4056
+ * @param {Float64Array} observation
4057
+ * @param {Float64Array} process_noise
4058
+ * @param {Float64Array} observation_noise
4059
+ * @param {number} n_state
4060
+ * @param {number} n_obs
4061
+ * @returns {KalmanForecaster}
4062
+ */
4063
+ static custom(transition, observation, process_noise, observation_noise, n_state, n_obs) {
4064
+ const ptr0 = passArrayF64ToWasm0(transition, wasm.__wbindgen_malloc);
4065
+ const len0 = WASM_VECTOR_LEN;
4066
+ const ptr1 = passArrayF64ToWasm0(observation, wasm.__wbindgen_malloc);
4067
+ const len1 = WASM_VECTOR_LEN;
4068
+ const ptr2 = passArrayF64ToWasm0(process_noise, wasm.__wbindgen_malloc);
4069
+ const len2 = WASM_VECTOR_LEN;
4070
+ const ptr3 = passArrayF64ToWasm0(observation_noise, wasm.__wbindgen_malloc);
4071
+ const len3 = WASM_VECTOR_LEN;
4072
+ const ret = wasm.kalmanforecaster_custom(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, n_state, n_obs);
4073
+ if (ret[2]) {
4074
+ throw takeFromExternrefTable0(ret[1]);
4075
+ }
4076
+ return KalmanForecaster.__wrap(ret[0]);
4077
+ }
3463
4078
  /**
3464
4079
  * Apply the Kalman smoother (RTS smoother) and return smoothed observations.
3465
4080
  *
4081
+ * Uses the same state-space model that was configured (local level, local linear
4082
+ * trend, or custom). Fits the filter first, then runs the RTS smoother.
4083
+ *
3466
4084
  * @param series - TimeSeries to smooth
3467
4085
  * @returns Array of smoothed observation values
3468
4086
  * @param {TimeSeries} series
@@ -3478,6 +4096,14 @@ export class KalmanForecaster {
3478
4096
  wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
3479
4097
  return v1;
3480
4098
  }
4099
+ /**
4100
+ * Get the number of state dimensions.
4101
+ * @returns {number}
4102
+ */
4103
+ get nState() {
4104
+ const ret = wasm.kalmanforecaster_nState(this.__wbg_ptr);
4105
+ return ret >>> 0;
4106
+ }
3481
4107
  /**
3482
4108
  * Predict future values.
3483
4109
  *
@@ -4706,6 +5332,26 @@ export class TimeSeries {
4706
5332
  }
4707
5333
  return TimeSeries.__wrap(ret[0]);
4708
5334
  }
5335
+ /**
5336
+ * Generate future timestamps by inferring the series frequency.
5337
+ *
5338
+ * Detects whether the data is daily, weekly, monthly, quarterly, or
5339
+ * yearly from the existing timestamps and extrapolates forward.
5340
+ *
5341
+ * @param horizon - Number of future timestamps to generate
5342
+ * @returns Array of timestamps as milliseconds since Unix epoch
5343
+ * @param {number} horizon
5344
+ * @returns {Float64Array}
5345
+ */
5346
+ futureTimestamps(horizon) {
5347
+ const ret = wasm.timeseries_futureTimestamps(this.__wbg_ptr, horizon);
5348
+ if (ret[3]) {
5349
+ throw takeFromExternrefTable0(ret[2]);
5350
+ }
5351
+ var v1 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
5352
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
5353
+ return v1;
5354
+ }
4709
5355
  /**
4710
5356
  * Check if the series has missing values (NaN).
4711
5357
  * @returns {boolean}
@@ -5201,6 +5847,31 @@ export function durbinWatson(residuals) {
5201
5847
  return takeFromExternrefTable0(ret[0]);
5202
5848
  }
5203
5849
 
5850
+ /**
5851
+ * Generate future timestamps starting after a given last timestamp.
5852
+ *
5853
+ * @param lastTimestampMs - Last known timestamp as milliseconds since epoch
5854
+ * @param frequency - Polars-style frequency string: "1d", "1w", "1mo",
5855
+ * "1q", "1y", "1h", "30m", "30s", etc.
5856
+ * @param horizon - Number of future timestamps to generate
5857
+ * @returns Float64Array of timestamps as milliseconds since epoch
5858
+ * @param {number} last_timestamp_ms
5859
+ * @param {string} frequency
5860
+ * @param {number} horizon
5861
+ * @returns {Float64Array}
5862
+ */
5863
+ export function generateFutureTimestamps(last_timestamp_ms, frequency, horizon) {
5864
+ const ptr0 = passStringToWasm0(frequency, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
5865
+ const len0 = WASM_VECTOR_LEN;
5866
+ const ret = wasm.generateFutureTimestamps(last_timestamp_ms, ptr0, len0, horizon);
5867
+ if (ret[3]) {
5868
+ throw takeFromExternrefTable0(ret[2]);
5869
+ }
5870
+ var v2 = getArrayF64FromWasm0(ret[0], ret[1]).slice();
5871
+ wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
5872
+ return v2;
5873
+ }
5874
+
5204
5875
  /**
5205
5876
  * Initialize the WASM module.
5206
5877
  *
@@ -5504,6 +6175,18 @@ function __wbg_get_imports() {
5504
6175
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
5505
6176
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
5506
6177
  };
6178
+ imports.wbg.__wbg___wbindgen_boolean_get_dea25b33882b895b = function(arg0) {
6179
+ const v = arg0;
6180
+ const ret = typeof(v) === 'boolean' ? v : undefined;
6181
+ return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
6182
+ };
6183
+ imports.wbg.__wbg___wbindgen_debug_string_adfb662ae34724b6 = function(arg0, arg1) {
6184
+ const ret = debugString(arg1);
6185
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
6186
+ const len1 = WASM_VECTOR_LEN;
6187
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
6188
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
6189
+ };
5507
6190
  imports.wbg.__wbg___wbindgen_is_function_8d400b8b1af978cd = function(arg0) {
5508
6191
  const ret = typeof(arg0) === 'function';
5509
6192
  return ret;
@@ -5521,6 +6204,16 @@ function __wbg_get_imports() {
5521
6204
  const ret = arg0 === undefined;
5522
6205
  return ret;
5523
6206
  };
6207
+ imports.wbg.__wbg___wbindgen_jsval_loose_eq_766057600fdd1b0d = function(arg0, arg1) {
6208
+ const ret = arg0 == arg1;
6209
+ return ret;
6210
+ };
6211
+ imports.wbg.__wbg___wbindgen_number_get_9619185a74197f95 = function(arg0, arg1) {
6212
+ const obj = arg1;
6213
+ const ret = typeof(obj) === 'number' ? obj : undefined;
6214
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
6215
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
6216
+ };
5524
6217
  imports.wbg.__wbg___wbindgen_string_get_a2a31e16edf96e42 = function(arg0, arg1) {
5525
6218
  const obj = arg1;
5526
6219
  const ret = typeof(obj) === 'string' ? obj : undefined;
@@ -5544,6 +6237,10 @@ function __wbg_get_imports() {
5544
6237
  const ret = arg0.crypto;
5545
6238
  return ret;
5546
6239
  };
6240
+ imports.wbg.__wbg_done_62ea16af4ce34b24 = function(arg0) {
6241
+ const ret = arg0.done;
6242
+ return ret;
6243
+ };
5547
6244
  imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
5548
6245
  arg0.getRandomValues(arg1);
5549
6246
  }, arguments) };
@@ -5555,6 +6252,20 @@ function __wbg_get_imports() {
5555
6252
  const ret = arg0[arg1 >>> 0];
5556
6253
  return ret;
5557
6254
  };
6255
+ imports.wbg.__wbg_get_af9dab7e9603ea93 = function() { return handleError(function (arg0, arg1) {
6256
+ const ret = Reflect.get(arg0, arg1);
6257
+ return ret;
6258
+ }, arguments) };
6259
+ imports.wbg.__wbg_instanceof_ArrayBuffer_f3320d2419cd0355 = function(arg0) {
6260
+ let result;
6261
+ try {
6262
+ result = arg0 instanceof ArrayBuffer;
6263
+ } catch (_) {
6264
+ result = false;
6265
+ }
6266
+ const ret = result;
6267
+ return ret;
6268
+ };
5558
6269
  imports.wbg.__wbg_instanceof_Float64Array_9fefccd7bfa2fefe = function(arg0) {
5559
6270
  let result;
5560
6271
  try {
@@ -5565,6 +6276,24 @@ function __wbg_get_imports() {
5565
6276
  const ret = result;
5566
6277
  return ret;
5567
6278
  };
6279
+ imports.wbg.__wbg_instanceof_Uint8Array_da54ccc9d3e09434 = function(arg0) {
6280
+ let result;
6281
+ try {
6282
+ result = arg0 instanceof Uint8Array;
6283
+ } catch (_) {
6284
+ result = false;
6285
+ }
6286
+ const ret = result;
6287
+ return ret;
6288
+ };
6289
+ imports.wbg.__wbg_isArray_51fd9e6422c0a395 = function(arg0) {
6290
+ const ret = Array.isArray(arg0);
6291
+ return ret;
6292
+ };
6293
+ imports.wbg.__wbg_iterator_27b7c8b35ab3e86b = function() {
6294
+ const ret = Symbol.iterator;
6295
+ return ret;
6296
+ };
5568
6297
  imports.wbg.__wbg_length_22ac23eaec9d8053 = function(arg0) {
5569
6298
  const ret = arg0.length;
5570
6299
  return ret;
@@ -5593,6 +6322,14 @@ function __wbg_get_imports() {
5593
6322
  const ret = new Array();
5594
6323
  return ret;
5595
6324
  };
6325
+ imports.wbg.__wbg_new_6421f6084cc5bc5a = function(arg0) {
6326
+ const ret = new Uint8Array(arg0);
6327
+ return ret;
6328
+ };
6329
+ imports.wbg.__wbg_new_b546ae120718850e = function() {
6330
+ const ret = new Map();
6331
+ return ret;
6332
+ };
5596
6333
  imports.wbg.__wbg_new_no_args_cb138f77cf6151ee = function(arg0, arg1) {
5597
6334
  const ret = new Function(getStringFromWasm0(arg0, arg1));
5598
6335
  return ret;
@@ -5609,6 +6346,14 @@ function __wbg_get_imports() {
5609
6346
  const ret = new Uint8Array(arg0 >>> 0);
5610
6347
  return ret;
5611
6348
  };
6349
+ imports.wbg.__wbg_next_138a17bbf04e926c = function(arg0) {
6350
+ const ret = arg0.next;
6351
+ return ret;
6352
+ };
6353
+ imports.wbg.__wbg_next_3cfe5c0fe2a4cc53 = function() { return handleError(function (arg0) {
6354
+ const ret = arg0.next();
6355
+ return ret;
6356
+ }, arguments) };
5612
6357
  imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {
5613
6358
  const ret = arg0.node;
5614
6359
  return ret;
@@ -5639,6 +6384,10 @@ function __wbg_get_imports() {
5639
6384
  imports.wbg.__wbg_set_7df433eea03a5c14 = function(arg0, arg1, arg2) {
5640
6385
  arg0[arg1 >>> 0] = arg2;
5641
6386
  };
6387
+ imports.wbg.__wbg_set_efaaf145b9377369 = function(arg0, arg1, arg2) {
6388
+ const ret = arg0.set(arg1, arg2);
6389
+ return ret;
6390
+ };
5642
6391
  imports.wbg.__wbg_static_accessor_GLOBAL_769e6b65d6557335 = function() {
5643
6392
  const ret = typeof global === 'undefined' ? null : global;
5644
6393
  return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
@@ -5659,6 +6408,10 @@ function __wbg_get_imports() {
5659
6408
  const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
5660
6409
  return ret;
5661
6410
  };
6411
+ imports.wbg.__wbg_value_57b7b035e117f7ee = function(arg0) {
6412
+ const ret = arg0.value;
6413
+ return ret;
6414
+ };
5662
6415
  imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {
5663
6416
  const ret = arg0.versions;
5664
6417
  return ret;