fastlowess-wasm 2.0.0 → 3.0.0

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
@@ -16,6 +16,7 @@
16
16
  <a href="https://anaconda.org/conda-forge/r-rfastlowess"><img src="https://img.shields.io/badge/rfastlowess_(R)-44A833?logo=anaconda&logoColor=white" alt="rfastlowess (R)"></a>
17
17
  <br>
18
18
  <a href="https://github.com/thisisamirv/lowess-project/actions/workflows/ci.yml"><img src="https://github.com/thisisamirv/lowess-project/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
19
+ <a href="https://github.com/ropensci/software-review/issues/769"><img src="https://badges.ropensci.org/769_status.svg" alt="Status at rOpenSci Software Peer Review"></a>
19
20
  </p>
20
21
 
21
22
  <p align="center">
@@ -47,6 +48,10 @@ The fastest, most robust, and most feature-complete language-agnostic LOWESS (Lo
47
48
  >
48
49
  > Currently available for R, Python, Rust, Julia, Node.js, WebAssembly, and C++. See the [Installation Guide](https://lowess.readthedocs.io/getting-started/installation/) for detailed installation instructions.
49
50
 
51
+ ### GPU Backend
52
+
53
+ In addition to `parallel = true` (multi-core CPU), the batch `Lowess` class in every binding — except WebAssembly — as well as the `fastLowess` Rust crate itself, can run on the GPU via `wgpu` (Vulkan/Metal/DX12). It's opt-in and worth enabling for high-throughput processing of large datasets (roughly 10k+ points); for smaller inputs the CPU backend is typically faster. `StreamingLowess`/`OnlineLowess` remain CPU-only. See the [GPU Backend guide](https://lowess.readthedocs.io/en/latest/user-guide/gpu-backend/) for installation instructions and usage.
54
+
50
55
  ## Documentation
51
56
 
52
57
  > [!NOTE]
@@ -57,7 +62,7 @@ The fastest, most robust, and most feature-complete language-agnostic LOWESS (Lo
57
62
 
58
63
  ## LOESS vs. LOWESS
59
64
 
60
- | Feature | LOESS (This Crate) | LOWESS |
65
+ | Feature | LOESS | LOWESS (This Crate) |
61
66
  | --- | --- | --- |
62
67
  | **Polynomial Degree** | Linear, Quadratic, Cubic, Quartic | Linear (Degree 1) |
63
68
  | **Dimensions** | Multivariate (n-D support) | Univariate (1-D only) |
@@ -131,11 +136,9 @@ A variety of features, supporting a range of use cases:
131
136
  | Prediction Intervals | yes | no | no |
132
137
  | Cross-Validation | 2 options | no | no |
133
138
  | Parallel Execution | yes | no | no |
134
- | GPU Acceleration | yes* | no | no |
139
+ | GPU Acceleration | yes | no | no |
135
140
  | `no-std` Support | yes | no | no |
136
141
 
137
- \* GPU acceleration is currently in beta and may not be available on all platforms.
138
-
139
142
  ## Validation
140
143
 
141
144
  All implementations are **numerical twins** of R's `lowess`:
@@ -176,7 +179,7 @@ model <- Lowess(
176
179
  parallel = TRUE
177
180
  )
178
181
  custom_weights <- rep(1, length(x))
179
- result <- model$fit(x, y, custom_weights = custom_weights)
182
+ result <- fit(model, x, y, custom_weights = custom_weights)
180
183
 
181
184
  # Result structure:
182
185
  result$x,
@@ -477,11 +480,11 @@ result.cv_scores()
477
480
 
478
481
  ## Contributing
479
482
 
480
- Contributions are welcome! Please see the [Contributing Guide](https://lowess.readthedocs.io/contributing/) for more information.
483
+ Contributions are welcome! Please see the [Contributing Guide](https://lowess.readthedocs.io/en/latest/contributing/) for more information.
481
484
 
482
485
  ## Changelog
483
486
 
484
- See the [Changelog](https://lowess.readthedocs.io/changelog/) for a history of changes.
487
+ See the [Changelog](https://lwoess.readthedocs.io/en/latest/changelog/) for a history of changes.
485
488
 
486
489
  ## License
487
490
 
@@ -87,15 +87,15 @@ export class StreamingLowess {
87
87
  export class OnlineLowess {
88
88
  free(): void;
89
89
  constructor(options?: SmoothOptions, onlineOpts?: OnlineOptions);
90
- /** Add a single point and get the smoothed output (or undefined if not enough points yet). */
91
- add_point(x: number, y: number): OnlineOutput | undefined;
90
+ /** Add a single point and get the smoothed output (or null if not enough points yet). */
91
+ add_point(x: number, y: number): OnlineOutput | null;
92
92
  }
93
93
 
94
94
  /** Result from a single online update step. */
95
95
  export class OnlineOutput {
96
96
  free(): void;
97
- get smoothed(): number;
98
- get std_error(): number | undefined;
97
+ get y(): number;
98
+ get standard_error(): number | undefined;
99
99
  get residual(): number | undefined;
100
100
  get robustness_weight(): number | undefined;
101
101
  get iterations_used(): number | undefined;
@@ -145,8 +145,8 @@ export class OnlineOutput {
145
145
  readonly iterations_used: number | undefined;
146
146
  readonly residual: number | undefined;
147
147
  readonly robustness_weight: number | undefined;
148
- readonly smoothed: number;
149
- readonly std_error: number | undefined;
148
+ readonly standard_error: number | undefined;
149
+ readonly y: number;
150
150
  }
151
151
 
152
152
  export function init_panic_hook(): void;
@@ -194,8 +194,8 @@ export interface InitOutput {
194
194
  readonly onlineoutput_iterations_used: (a: number) => number;
195
195
  readonly onlineoutput_residual: (a: number) => [number, number];
196
196
  readonly onlineoutput_robustness_weight: (a: number) => [number, number];
197
- readonly onlineoutput_smoothed: (a: number) => number;
198
- readonly onlineoutput_std_error: (a: number) => [number, number];
197
+ readonly onlineoutput_standard_error: (a: number) => [number, number];
198
+ readonly onlineoutput_y: (a: number) => number;
199
199
  readonly streaminglowess_finalize: (a: number) => [number, number, number];
200
200
  readonly streaminglowess_new: (a: any, b: any) => [number, number, number];
201
201
  readonly streaminglowess_process_chunk: (a: number, b: any, c: any) => [number, number, number];
@@ -276,14 +276,14 @@ export class OnlineLowess {
276
276
  /**
277
277
  * @param {number} x
278
278
  * @param {number} y
279
- * @returns {OnlineOutput | undefined}
279
+ * @returns {any}
280
280
  */
281
281
  add_point(x, y) {
282
282
  const ret = wasm.onlinelowess_add_point(this.__wbg_ptr, x, y);
283
283
  if (ret[2]) {
284
284
  throw takeFromExternrefTable0(ret[1]);
285
285
  }
286
- return ret[0] === 0 ? undefined : OnlineOutput.__wrap(ret[0]);
286
+ return takeFromExternrefTable0(ret[0]);
287
287
  }
288
288
  /**
289
289
  * @param {any} options
@@ -340,18 +340,18 @@ export class OnlineOutput {
340
340
  return ret[0] === 0 ? undefined : ret[1];
341
341
  }
342
342
  /**
343
- * @returns {number}
343
+ * @returns {number | undefined}
344
344
  */
345
- get smoothed() {
346
- const ret = wasm.onlineoutput_smoothed(this.__wbg_ptr);
347
- return ret;
345
+ get standard_error() {
346
+ const ret = wasm.onlineoutput_standard_error(this.__wbg_ptr);
347
+ return ret[0] === 0 ? undefined : ret[1];
348
348
  }
349
349
  /**
350
- * @returns {number | undefined}
350
+ * @returns {number}
351
351
  */
352
- get std_error() {
353
- const ret = wasm.onlineoutput_std_error(this.__wbg_ptr);
354
- return ret[0] === 0 ? undefined : ret[1];
352
+ get y() {
353
+ const ret = wasm.onlineoutput_y(this.__wbg_ptr);
354
+ return ret;
355
355
  }
356
356
  }
357
357
  if (Symbol.dispose) OnlineOutput.prototype[Symbol.dispose] = OnlineOutput.prototype.free;
@@ -411,72 +411,72 @@ export function init_panic_hook() {
411
411
  function __wbg_get_imports() {
412
412
  const import0 = {
413
413
  __proto__: null,
414
- __wbg_Error_92b29b0548f8b746: function(arg0, arg1) {
414
+ __wbg_Error_408e67f47ca7b58b: function(arg0, arg1) {
415
415
  const ret = Error(getStringFromWasm0(arg0, arg1));
416
416
  return ret;
417
417
  },
418
- __wbg_Number_9a4e0ecb0fa16705: function(arg0) {
418
+ __wbg_Number_3890faa6d3ff057d: function(arg0) {
419
419
  const ret = Number(arg0);
420
420
  return ret;
421
421
  },
422
- __wbg___wbindgen_bigint_get_as_i64_d968e41184ae354f: function(arg0, arg1) {
422
+ __wbg___wbindgen_bigint_get_as_i64_c4ecf48528083721: function(arg0, arg1) {
423
423
  const v = arg1;
424
424
  const ret = typeof(v) === 'bigint' ? v : undefined;
425
425
  getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
426
426
  getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
427
427
  },
428
- __wbg___wbindgen_boolean_get_fa956cfa2d1bd751: function(arg0) {
428
+ __wbg___wbindgen_boolean_get_c9c83ebd41b34df3: function(arg0) {
429
429
  const v = arg0;
430
430
  const ret = typeof(v) === 'boolean' ? v : undefined;
431
431
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
432
432
  },
433
- __wbg___wbindgen_debug_string_c25d447a39f5578f: function(arg0, arg1) {
433
+ __wbg___wbindgen_debug_string_a57024b9c6e4a48b: function(arg0, arg1) {
434
434
  const ret = debugString(arg1);
435
435
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
436
436
  const len1 = WASM_VECTOR_LEN;
437
437
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
438
438
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
439
439
  },
440
- __wbg___wbindgen_in_aca499c5de7ff5e5: function(arg0, arg1) {
440
+ __wbg___wbindgen_in_ac983077f137f2e6: function(arg0, arg1) {
441
441
  const ret = arg0 in arg1;
442
442
  return ret;
443
443
  },
444
- __wbg___wbindgen_is_bigint_2f76dc55065b4273: function(arg0) {
444
+ __wbg___wbindgen_is_bigint_8ffbbef442139384: function(arg0) {
445
445
  const ret = typeof(arg0) === 'bigint';
446
446
  return ret;
447
447
  },
448
- __wbg___wbindgen_is_function_1ff95bcc5517c252: function(arg0) {
448
+ __wbg___wbindgen_is_function_5e4570eb24ffa122: function(arg0) {
449
449
  const ret = typeof(arg0) === 'function';
450
450
  return ret;
451
451
  },
452
- __wbg___wbindgen_is_null_ea9085d691f535d3: function(arg0) {
452
+ __wbg___wbindgen_is_null_7d13f41e1a2d5140: function(arg0) {
453
453
  const ret = arg0 === null;
454
454
  return ret;
455
455
  },
456
- __wbg___wbindgen_is_object_a27215656b807791: function(arg0) {
456
+ __wbg___wbindgen_is_object_a2790eb24c211ea0: function(arg0) {
457
457
  const val = arg0;
458
458
  const ret = typeof(val) === 'object' && val !== null;
459
459
  return ret;
460
460
  },
461
- __wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) {
461
+ __wbg___wbindgen_is_undefined_6cff064c44e0d823: function(arg0) {
462
462
  const ret = arg0 === undefined;
463
463
  return ret;
464
464
  },
465
- __wbg___wbindgen_jsval_eq_e659fcf7b0e32763: function(arg0, arg1) {
465
+ __wbg___wbindgen_jsval_eq_0a18949a61670320: function(arg0, arg1) {
466
466
  const ret = arg0 === arg1;
467
467
  return ret;
468
468
  },
469
- __wbg___wbindgen_jsval_loose_eq_db4c3b15f63fc170: function(arg0, arg1) {
469
+ __wbg___wbindgen_jsval_loose_eq_acf2776254a8d832: function(arg0, arg1) {
470
470
  const ret = arg0 == arg1;
471
471
  return ret;
472
472
  },
473
- __wbg___wbindgen_number_get_394265ed1e1b84ee: function(arg0, arg1) {
473
+ __wbg___wbindgen_number_get_136b9679cab35cfb: function(arg0, arg1) {
474
474
  const obj = arg1;
475
475
  const ret = typeof(obj) === 'number' ? obj : undefined;
476
476
  getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
477
477
  getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
478
478
  },
479
- __wbg___wbindgen_string_get_b0ca35b86a603356: function(arg0, arg1) {
479
+ __wbg___wbindgen_string_get_d154f1e671052120: function(arg0, arg1) {
480
480
  const obj = arg1;
481
481
  const ret = typeof(obj) === 'string' ? obj : undefined;
482
482
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -484,18 +484,18 @@ function __wbg_get_imports() {
484
484
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
485
485
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
486
486
  },
487
- __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
487
+ __wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
488
488
  throw new Error(getStringFromWasm0(arg0, arg1));
489
489
  },
490
- __wbg_call_8a2dd23819f8a60a: function() { return handleError(function (arg0, arg1) {
490
+ __wbg_call_1c5886ab9c57d1c7: function() { return handleError(function (arg0, arg1) {
491
491
  const ret = arg0.call(arg1);
492
492
  return ret;
493
493
  }, arguments); },
494
- __wbg_done_89b2b13e91a60321: function(arg0) {
494
+ __wbg_done_669171204c3dcae2: function(arg0) {
495
495
  const ret = arg0.done;
496
496
  return ret;
497
497
  },
498
- __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
498
+ __wbg_error_757e9472f8410341: function(arg0, arg1) {
499
499
  let deferred0_0;
500
500
  let deferred0_1;
501
501
  try {
@@ -506,11 +506,11 @@ function __wbg_get_imports() {
506
506
  wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
507
507
  }
508
508
  },
509
- __wbg_get_c7eb1f358a7654df: function() { return handleError(function (arg0, arg1) {
509
+ __wbg_get_d173c0308df22d37: function() { return handleError(function (arg0, arg1) {
510
510
  const ret = Reflect.get(arg0, arg1);
511
511
  return ret;
512
512
  }, arguments); },
513
- __wbg_get_unchecked_6e0ad6d2a41b06f6: function(arg0, arg1) {
513
+ __wbg_get_unchecked_e20b893aeafc3fca: function(arg0, arg1) {
514
514
  const ret = arg0[arg1 >>> 0];
515
515
  return ret;
516
516
  },
@@ -518,7 +518,7 @@ function __wbg_get_imports() {
518
518
  const ret = arg0[arg1];
519
519
  return ret;
520
520
  },
521
- __wbg_instanceof_ArrayBuffer_4480b9e0068a8adb: function(arg0) {
521
+ __wbg_instanceof_ArrayBuffer_993d02d2d254cad1: function(arg0) {
522
522
  let result;
523
523
  try {
524
524
  result = arg0 instanceof ArrayBuffer;
@@ -528,7 +528,7 @@ function __wbg_get_imports() {
528
528
  const ret = result;
529
529
  return ret;
530
530
  },
531
- __wbg_instanceof_Uint8Array_309b927aaf7a3fc7: function(arg0) {
531
+ __wbg_instanceof_Uint8Array_f935dbb0aa7cdeed: function(arg0) {
532
532
  let result;
533
533
  try {
534
534
  result = arg0 instanceof Uint8Array;
@@ -538,27 +538,27 @@ function __wbg_get_imports() {
538
538
  const ret = result;
539
539
  return ret;
540
540
  },
541
- __wbg_isArray_0677c962b281d01a: function(arg0) {
541
+ __wbg_isArray_6339f732981044bf: function(arg0) {
542
542
  const ret = Array.isArray(arg0);
543
543
  return ret;
544
544
  },
545
- __wbg_isSafeInteger_04f36e4056f1b851: function(arg0) {
545
+ __wbg_isSafeInteger_f3d6cd19ccfe4512: function(arg0) {
546
546
  const ret = Number.isSafeInteger(arg0);
547
547
  return ret;
548
548
  },
549
- __wbg_iterator_6f722e4a93058b71: function() {
549
+ __wbg_iterator_5cebbb86e33c6dd6: function() {
550
550
  const ret = Symbol.iterator;
551
551
  return ret;
552
552
  },
553
- __wbg_length_0133fa10e3234c57: function(arg0) {
553
+ __wbg_length_36bd29c6848c2144: function(arg0) {
554
554
  const ret = arg0.length;
555
555
  return ret;
556
556
  },
557
- __wbg_length_1f0964f4a5e2c6d8: function(arg0) {
557
+ __wbg_length_46f80504ebb6ebb4: function(arg0) {
558
558
  const ret = arg0.length;
559
559
  return ret;
560
560
  },
561
- __wbg_length_370319915dc99107: function(arg0) {
561
+ __wbg_length_ecfa2c63d3d0d82c: function(arg0) {
562
562
  const ret = arg0.length;
563
563
  return ret;
564
564
  },
@@ -566,22 +566,26 @@ function __wbg_get_imports() {
566
566
  const ret = new Error();
567
567
  return ret;
568
568
  },
569
- __wbg_new_cd45aabdf6073e84: function(arg0) {
569
+ __wbg_new_77cc4f4f472aeb81: function(arg0) {
570
570
  const ret = new Uint8Array(arg0);
571
571
  return ret;
572
572
  },
573
- __wbg_next_6dbf2c0ac8cde20f: function(arg0) {
573
+ __wbg_next_42cf16ee0dafc9e2: function() { return handleError(function (arg0) {
574
+ const ret = arg0.next();
575
+ return ret;
576
+ }, arguments); },
577
+ __wbg_next_8f26b64fa5e9f64b: function(arg0) {
574
578
  const ret = arg0.next;
575
579
  return ret;
576
580
  },
577
- __wbg_next_71f2aa1cb3d1e37e: function() { return handleError(function (arg0) {
578
- const ret = arg0.next();
581
+ __wbg_onlineoutput_new: function(arg0) {
582
+ const ret = OnlineOutput.__wrap(arg0);
579
583
  return ret;
580
- }, arguments); },
581
- __wbg_prototypesetcall_21a175a0a8157491: function(arg0, arg1, arg2) {
584
+ },
585
+ __wbg_prototypesetcall_35505001a41def4c: function(arg0, arg1, arg2) {
582
586
  Float64Array.prototype.set.call(getArrayF64FromWasm0(arg0, arg1), arg2);
583
587
  },
584
- __wbg_prototypesetcall_4770620bbe4688a0: function(arg0, arg1, arg2) {
588
+ __wbg_prototypesetcall_de8e0d9553586985: function(arg0, arg1, arg2) {
585
589
  Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
586
590
  },
587
591
  __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
@@ -591,7 +595,7 @@ function __wbg_get_imports() {
591
595
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
592
596
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
593
597
  },
594
- __wbg_value_a5d5488a9589444a: function(arg0) {
598
+ __wbg_value_1e2369fab29b420e: function(arg0) {
595
599
  const ret = arg0.value;
596
600
  return ret;
597
601
  },
@@ -860,11 +864,15 @@ function __wbg_finalize_init(instance, module) {
860
864
 
861
865
  async function __wbg_load(module, imports) {
862
866
  if (typeof Response === 'function' && module instanceof Response) {
867
+ if (!module.ok) {
868
+ throw new Error(`failed to fetch Wasm: ${module.status} ${module.statusText} fetching '${module.url}'`);
869
+ }
870
+
863
871
  if (typeof WebAssembly.instantiateStreaming === 'function') {
864
872
  try {
865
873
  return await WebAssembly.instantiateStreaming(module, imports);
866
874
  } catch (e) {
867
- const validResponse = module.ok && expectedResponseType(module.type);
875
+ const validResponse = expectedResponseType(module.type);
868
876
 
869
877
  if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
870
878
  console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
Binary file
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Amir Valizadeh <thisisamirv@gmail.com>"
6
6
  ],
7
7
  "description": "High-performance LOWESS (Locally Weighted Scatterplot Smoothing)",
8
- "version": "2.0.0",
8
+ "version": "3.0.0",
9
9
  "license": "MIT OR Apache-2.0",
10
10
  "repository": {
11
11
  "type": "git",