fastlowess-wasm 0.99.8 β†’ 1.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
@@ -1,12 +1,20 @@
1
1
  <!-- markdownlint-disable MD024 MD033 -->
2
2
  # LOWESS Project
3
3
 
4
- [![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE-MIT)
5
- [![Docs](https://img.shields.io/badge/docs-readthedocs-blue.svg)](https://lowess.readthedocs.io/)
6
- [![Crates.io](https://img.shields.io/crates/v/lowess.svg)](https://crates.io/crates/lowess)
7
- [![PyPI](https://img.shields.io/pypi/v/fastlowess.svg)](https://pypi.org/project/fastlowess/)
8
- [![Conda](https://anaconda.org/conda-forge/fastlowess/badges/version.svg)](https://anaconda.org/conda-forge/fastlowess)
9
- [![R-universe](https://thisisamirv.r-universe.dev/badges/rfastlowess)](https://thisisamirv.r-universe.dev/rfastlowess)
4
+ <p align="center">
5
+ <a href="https://crates.io/crates/lowess"><img src="https://img.shields.io/badge/lowess-000000?logo=rust&logoColor=white" alt="lowess"></a>
6
+ <a href="https://crates.io/crates/fastLowess"><img src="https://img.shields.io/badge/fastLowess-000000?logo=rust&logoColor=white" alt="fastLowess"></a>
7
+ <a href="https://pypi.org/project/fastlowess/"><img src="https://img.shields.io/badge/PyPI-3775A9?logo=pypi&logoColor=white" alt="PyPI"></a>
8
+ <a href="https://thisisamirv.r-universe.dev/rfastlowess"><img src="https://img.shields.io/badge/R--universe-276DC3?logo=r&logoColor=white" alt="R-universe"></a>
9
+ <a href="https://www.npmjs.com/package/fastlowess"><img src="https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white" alt="npm"></a>
10
+ <a href="https://juliahub.com/ui/Packages/General/fastlowess_jll"><img src="https://img.shields.io/badge/Julia-9558B2?logo=julia&logoColor=white" alt="Julia"></a>
11
+ <a href="https://www.npmjs.com/package/fastlowess-wasm"><img src="https://img.shields.io/badge/WASM-654FF0?logo=webassembly&logoColor=white" alt="WASM"></a>
12
+ <a href="https://github.com/thisisamirv/lowess-project/releases/latest"><img src="https://img.shields.io/badge/C++-00599C?logo=cplusplus&logoColor=white" alt="C++"></a>
13
+ <br>
14
+ <a href="https://anaconda.org/conda-forge/fastlowess"><img src="https://img.shields.io/badge/fastlowess_(Python)-44A833?logo=anaconda&logoColor=white" alt="fastlowess (Python)"></a>
15
+ <a href="https://anaconda.org/conda-forge/libfastlowess"><img src="https://img.shields.io/badge/libfastlowess_(C++)-44A833?logo=anaconda&logoColor=white" alt="libfastlowess (C++)"></a>
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
+ </p>
10
18
 
11
19
  <p align="center">
12
20
  <img src="https://raw.githubusercontent.com/thisisamirv/lowess-project/main/dev/logo.png" alt="One LOWESS to Rule Them All" width="400">
@@ -20,14 +28,30 @@ The fastest, most robust, and most feature-complete language-agnostic LOWESS (Lo
20
28
  >
21
29
  > The `lowess-project` contains a complete ecosystem for LOWESS smoothing:
22
30
  >
23
- > - **[`lowess`](https://github.com/thisisamirv/lowess-project/tree/main/crates/lowess)** - Core single-threaded Rust implementation with `no_std` support
24
- > - **[`fastLowess`](https://github.com/thisisamirv/lowess-project/tree/main/crates/fastLowess)** - Parallel CPU and GPU-accelerated Rust wrapper with ndarray integration
25
- > - **[`R bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/r)** - extendr-based R package
26
- > - **[`Python bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/python)** - PyO3-based Python package
27
- > - **[`Julia bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/julia)** - Native Julia package with C FFI
28
- > - **[`JavaScript bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/nodejs)** - Node.js package
29
- > - **[`WebAssembly bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/wasm)** - WASM package
30
- > - **[`C++ bindings`](https://github.com/thisisamirv/lowess-project/tree/main/bindings/cpp)** - Native C++ package with CMake integration
31
+ > - **[`lowess`](https://crates.io/crates/lowess)** - Core single-threaded Rust implementation with `no_std` support
32
+ > - **[`fastLowess`](https://crates.io/crates/fastLowess)** - Parallel CPU and GPU-accelerated Rust wrapper with ndarray integration
33
+ > - **[`R bindings`](https://thisisamirv.r-universe.dev/rfastlowess)** - extendr-based R binding
34
+ > - **[`Python bindings`](https://pypi.org/project/fastlowess/)** - PyO3-based Python binding
35
+ > - **[`Julia bindings`](https://juliahub.com/ui/Packages/General/fastlowess_jll)** - Native Julia binding with C FFI
36
+ > - **[`JavaScript bindings`](https://www.npmjs.com/package/fastlowess)** - Node.js binding
37
+ > - **[`WebAssembly bindings`](https://www.npmjs.com/package/fastlowess-wasm)** - WASM binding
38
+ > - **[`C++ bindings`](https://github.com/thisisamirv/lowess-project/releases/latest)** - Native C++ binding with CMake integration
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ > [!NOTE]
45
+ >
46
+ > Currently available for R, Python, Rust, Julia, Node.js, WebAssembly, and C++. See [INSTALLATION.md](https://github.com/thisisamirv/lowess-project/blob/main/INSTALLATION.md) for detailed installation instructions.
47
+
48
+ ## Documentation
49
+
50
+ > [!NOTE]
51
+ >
52
+ > ### πŸ“š [View the full documentation](https://lowess.readthedocs.io/)
53
+
54
+ ---
31
55
 
32
56
  ## LOESS vs. LOWESS
33
57
 
@@ -43,38 +67,13 @@ The fastest, most robust, and most feature-complete language-agnostic LOWESS (Lo
43
67
 
44
68
  ---
45
69
 
46
- ## Documentation
47
-
48
- > [!NOTE]
49
- >
50
- > ### πŸ“š [View the full documentation](https://lowess.readthedocs.io/)
51
-
52
70
  ## Why this package?
53
71
 
54
72
  ### Speed
55
73
 
56
- The `lowess` project crushes the competition in terms of speed, wether in single-threaded or multi-threaded parallel execution.
57
-
58
- Speedup relative to Python's `statsmodels.lowess` (higher is better):
59
-
60
- | Category | statsmodels | R (stats) | Serial | Parallel | GPU |
61
- |---------------------------------|-------------|-----------|--------|----------|---------|
62
- | **Clustered** | 163ms | 83Γ— | 203Γ— | **433Γ—** | 32Γ— |
63
- | **Constant Y** | 134ms | 92Γ— | 212Γ— | **410Γ—** | 18Γ— |
64
- | **Delta** (large–none) | 105ms | 2Γ— | 4Γ— | 6Γ— | **16Γ—** |
65
- | **Extreme Outliers** | 489ms | 106Γ— | 201Γ— | **388Γ—** | 29Γ— |
66
- | **Financial** (500–10K) | 106ms | 105Γ— | 252Γ— | **293Γ—** | 12Γ— |
67
- | **Fraction** (0.05–0.67) | 221ms | 104Γ— | 228Γ— | **391Γ—** | 22Γ— |
68
- | **Genomic** (1K–50K) | 1833ms | 7Γ— | 9Γ— | 20Γ— | **95Γ—** |
69
- | **High Noise** | 435ms | 133Γ— | 134Γ— | **375Γ—** | 32Γ— |
70
- | **Iterations** (0–10) | 204ms | 115Γ— | 224Γ— | **386Γ—** | 18Γ— |
71
- | **Scale** (1K–50K) | 1841ms | 264Γ— | 487Γ— | **581Γ—** | 98Γ— |
72
- | **Scientific** (500–10K) | 167ms | 109Γ— | 205Γ— | **314Γ—** | 15Γ— |
73
- | **Scale Large**\* (100K–2M) | β€” | β€” | 1Γ— | **1.4Γ—** | 0.3Γ— |
74
-
75
- \*Scale Large benchmarks are relative to Serial (statsmodels cannot handle these sizes)
74
+ The `lowess` project beats the competition in terms of speed, whether in single-threaded or multi-threaded parallel execution. It is on average **200-327x faster** than Python's `statsmodels.lowess` and **2-3x faster** than R's `lowess`.
76
75
 
77
- *The numbers are the average across a range of scenarios for each category (e.g., Delta from none, to small, medium, and large).*
76
+ For more details on the performance comparison, see the [BENCHMARKS](https://github.com/thisisamirv/lowess-project/blob/main/BENCHMARKS.md) file.
78
77
 
79
78
  ### Robustness
80
79
 
@@ -145,185 +144,12 @@ All implementations are **numerical twins** of R's `lowess`:
145
144
  | **Consistency** | βœ… PERFECT | Multiple scenarios pass with strict tolerance |
146
145
  | **Robustness** | βœ… VERIFIED | Robust smoothing matches R exactly |
147
146
 
148
- ## Installation
149
-
150
- Currently available for R, Python, Julia, and Rust:
151
-
152
- **R** (from R-universe, recommended):
153
-
154
- ```r
155
- install.packages("rfastlowess", repos = "https://thisisamirv.r-universe.dev")
156
- ```
157
-
158
- **Python** (from PyPI):
159
-
160
- ```bash
161
- pip install fastlowess
162
- ```
163
-
164
- Or from conda-forge:
165
-
166
- ```bash
167
- conda install -c conda-forge fastlowess
168
- ```
169
-
170
- **Rust** (lowess, no_std compatible):
171
-
172
- ```toml
173
- [dependencies]
174
- lowess = "0.99"
175
- ```
176
-
177
- **Rust** (fastLowess, parallel + GPU):
178
-
179
- ```toml
180
- [dependencies]
181
- fastLowess = { version = "0.99", features = ["cpu"] }
182
- ```
183
-
184
- **Julia** (from Julia General Registry):
185
-
186
- ```julia
187
- using Pkg
188
- Pkg.add("fastLowess")
189
- ```
190
-
191
- **Node.js** (from npm):
192
-
193
- ```bash
194
- npm install fastlowess
195
- ```
196
-
197
- **WebAssembly** (from npm):
198
-
199
- ```bash
200
- npm install fastlowess-wasm
201
- ```
202
-
203
- Or via CDN:
204
-
205
- ```html
206
- <script type="module">
207
- import init, { smooth } from 'https://unpkg.com/fastlowess-wasm@latest';
208
- await init();
209
- </script>
210
- ```
211
-
212
- **C++** (build from source):
213
-
214
- ```bash
215
- make cpp
216
- # Links against libfastlowess_cpp.so
217
- ```
218
-
219
- ## Quick Example
220
-
221
- **R:**
222
-
223
- ```r
224
- library(rfastlowess)
225
-
226
- x <- c(1, 2, 3, 4, 5)
227
- y <- c(2.0, 4.1, 5.9, 8.2, 9.8)
228
-
229
- result <- fastlowess(x, y, fraction = 0.5, iterations = 3)
230
- print(result$y)
231
- ```
232
-
233
- **Python:**
234
-
235
- ```python
236
- import fastlowess as fl
237
- import numpy as np
238
-
239
- x = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
240
- y = np.array([2.0, 4.1, 5.9, 8.2, 9.8])
241
-
242
- result = fl.smooth(x, y, fraction=0.5, iterations=3)
243
- print(result["y"])
244
- ```
245
-
246
- **Rust:**
247
-
248
- ```rust
249
- use lowess::prelude::*;
250
-
251
- let x = vec![1.0, 2.0, 3.0, 4.0, 5.0];
252
- let y = vec![2.0, 4.1, 5.9, 8.2, 9.8];
253
-
254
- let model = Lowess::new()
255
- .fraction(0.5)
256
- .iterations(3)
257
- .adapter(Batch)
258
- .build()?;
259
-
260
- let result = model.fit(&x, &y)?;
261
- println!("{}", result);
262
- ```
263
-
264
- **Julia:**
265
-
266
- ```julia
267
- using fastlowess
268
-
269
- x = [1.0, 2.0, 3.0, 4.0, 5.0]
270
- y = [2.0, 4.1, 5.9, 8.2, 9.8]
271
-
272
- result = smooth(x, y, fraction=0.5, iterations=3)
273
- println(result.y)
274
- ```
275
-
276
- **Node.js:**
277
-
278
- ```javascript
279
- const { smooth } = require('fastlowess');
280
-
281
- const x = [1.0, 2.0, 3.0, 4.0, 5.0];
282
- const y = [2.0, 4.1, 5.9, 8.2, 9.8];
283
-
284
- const result = smooth(x, y, { fraction: 0.5, iterations: 3 });
285
- console.log(result.y);
286
- ```
287
-
288
- **WebAssembly:**
289
-
290
- ```javascript
291
- import init, { smooth } from 'fastlowess-wasm';
292
-
293
- await init();
294
-
295
- const x = new Float64Array([1.0, 2.0, 3.0, 4.0, 5.0]);
296
- const y = new Float64Array([2.0, 4.1, 5.9, 8.2, 9.8]);
297
-
298
- const result = smooth(x, y, { fraction: 0.5, iterations: 3 });
299
- console.log(result.y);
300
- ```
301
-
302
- **C++:**
303
-
304
- ```cpp
305
- #include <fastlowess.hpp>
306
-
307
- std::vector<double> x = {1.0, 2.0, 3.0, 4.0, 5.0};
308
- std::vector<double> y = {2.0, 4.1, 5.9, 8.2, 9.8};
309
-
310
- fastlowess::LowessOptions options;
311
- options.fraction = 0.5;
312
- options.iterations = 3;
313
-
314
- auto result = fastlowess::smooth(x, y, options);
315
- for (double val : result.y_vector()) std::cout << val << " ";
316
- ```
317
-
318
- ---
319
-
320
147
  ## API Reference
321
148
 
322
149
  **R:**
323
150
 
324
151
  ```r
325
- fastlowess(
326
- x, y,
152
+ Lowess(
327
153
  fraction = 0.5,
328
154
  iterations = 3L,
329
155
  delta = 0.01,
@@ -341,14 +167,30 @@ fastlowess(
341
167
  cv_k = 5L,
342
168
  auto_converge = 1e-4,
343
169
  parallel = TRUE
344
- )
170
+ )$fit(x, y)
171
+
172
+ # Result structure:
173
+ result$x,
174
+ result$y,
175
+ result$standard_errors,
176
+ result$confidence_lower,
177
+ result$confidence_upper,
178
+ result$prediction_lower,
179
+ result$prediction_upper,
180
+ result$residuals,
181
+ result$robustness_weights,
182
+ result$diagnostics,
183
+ result$iterations_used,
184
+ result$fraction_used,
185
+ result$cv_scores
345
186
  ```
346
187
 
347
188
  **Python:**
348
189
 
349
190
  ```python
350
- fastlowess.smooth(
351
- x, y,
191
+ from fastlowess import Lowess
192
+
193
+ model = Lowess(
352
194
  fraction=0.5,
353
195
  iterations=3,
354
196
  delta=0.01,
@@ -367,16 +209,32 @@ fastlowess.smooth(
367
209
  auto_converge=1e-4,
368
210
  parallel=True
369
211
  )
212
+ result = model.fit(x, y)
213
+
214
+ # Result structure:
215
+ result.x,
216
+ result.y,
217
+ result.standard_errors,
218
+ result.confidence_lower,
219
+ result.confidence_upper,
220
+ result.prediction_lower,
221
+ result.prediction_upper,
222
+ result.residuals,
223
+ result.robustness_weights,
224
+ result.diagnostics,
225
+ result.iterations_used,
226
+ result.fraction_used,
227
+ result.cv_scores
370
228
  ```
371
229
 
372
230
  **Rust:**
373
231
 
374
232
  ```rust
375
233
  Lowess::new()
376
- .fraction(0.5) // Smoothing span (0, 1]
377
- .iterations(3) // Robustness iterations
378
- .delta(0.01) // Interpolation threshold
379
- .weight_function(Tricube) // Kernel selection
234
+ .fraction(0.5)
235
+ .iterations(3)
236
+ .delta(0.01)
237
+ .weight_function(Tricube)
380
238
  .robustness_method(Bisquare)
381
239
  .zero_weight_fallback(UseLocalMean)
382
240
  .boundary_policy(Extend)
@@ -387,17 +245,35 @@ Lowess::new()
387
245
  .return_robustness_weights()
388
246
  .cross_validate(KFold(5, &[0.3, 0.5, 0.7]).seed(123))
389
247
  .auto_converge(1e-4)
390
- .adapter(Batch) // or Streaming, Online
248
+ .adapter(Batch)
391
249
  .parallel(true) // fastLowess only
392
250
  .backend(CPU) // fastLowess only: CPU or GPU
393
251
  .build()?;
252
+
253
+ let result = model.fit(x, y);
254
+
255
+ // Result structure:
256
+ pub struct LowessResult<T> {
257
+ pub x: Vec<T>, // Sorted x values
258
+ pub y: Vec<T>, // Smoothed y values
259
+ pub standard_errors: Option<Vec<T>>,
260
+ pub confidence_lower: Option<Vec<T>>,
261
+ pub confidence_upper: Option<Vec<T>>,
262
+ pub prediction_lower: Option<Vec<T>>,
263
+ pub prediction_upper: Option<Vec<T>>,
264
+ pub residuals: Option<Vec<T>>,
265
+ pub robustness_weights: Option<Vec<T>>,
266
+ pub diagnostics: Option<Diagnostics<T>>,
267
+ pub iterations_used: Option<usize>,
268
+ pub fraction_used: T,
269
+ pub cv_scores: Option<Vec<T>>,
270
+ }
394
271
  ```
395
272
 
396
273
  **Julia:**
397
274
 
398
275
  ```julia
399
- smooth(
400
- x, y,
276
+ Lowess(;
401
277
  fraction=0.5,
402
278
  iterations=3,
403
279
  delta=NaN, # NaN for auto
@@ -405,23 +281,38 @@ smooth(
405
281
  robustness_method="bisquare",
406
282
  zero_weight_fallback="use_local_mean",
407
283
  boundary_policy="extend",
408
- confidence_intervals=0.95,
409
- prediction_intervals=0.95,
284
+ confidence_intervals=NaN,
285
+ prediction_intervals=NaN,
410
286
  return_diagnostics=true,
411
287
  return_residuals=true,
412
288
  return_robustness_weights=true,
413
- cv_fractions=[0.3, 0.5, 0.7],
289
+ cv_fractions=Float64[], # e.g. [0.3, 0.5]
414
290
  cv_method="kfold",
415
291
  cv_k=5,
416
- auto_converge=1e-4,
292
+ auto_converge=NaN,
417
293
  parallel=true
418
294
  )
295
+
296
+ # Result structure:
297
+ result.x,
298
+ result.y,
299
+ result.standard_errors,
300
+ result.confidence_lower,
301
+ result.confidence_upper,
302
+ result.prediction_lower,
303
+ result.prediction_upper,
304
+ result.residuals,
305
+ result.robustness_weights,
306
+ result.diagnostics,
307
+ result.iterations_used,
308
+ result.fraction_used,
309
+ result.cv_scores
419
310
  ```
420
311
 
421
312
  **Node.js:**
422
313
 
423
314
  ```javascript
424
- smooth(x, y, {
315
+ new Lowess({
425
316
  fraction: 0.5,
426
317
  iterations: 3,
427
318
  delta: 0.01,
@@ -439,7 +330,22 @@ smooth(x, y, {
439
330
  cvK: 5,
440
331
  autoConverge: 1e-4,
441
332
  parallel: true
442
- })
333
+ }).fit(x, y)
334
+
335
+ // Result structure:
336
+ result.x,
337
+ result.y,
338
+ result.standardErrors,
339
+ result.confidenceLower,
340
+ result.confidenceUpper,
341
+ result.predictionLower,
342
+ result.predictionUpper,
343
+ result.residuals,
344
+ result.robustnessWeights,
345
+ result.diagnostics,
346
+ result.iterationsUsed,
347
+ result.fractionUsed,
348
+ result.cvScores
443
349
  ```
444
350
 
445
351
  **WebAssembly:**
@@ -461,8 +367,24 @@ smooth(x, y, {
461
367
  cvFractions: [0.3, 0.5, 0.7],
462
368
  cvMethod: "kfold",
463
369
  cvK: 5,
464
- autoConverge: 1e-4
370
+ autoConverge: 1e-4,
371
+ parallel: true
465
372
  })
373
+
374
+ // Result structure:
375
+ result.x,
376
+ result.y,
377
+ result.standardErrors,
378
+ result.confidenceLower,
379
+ result.confidenceUpper,
380
+ result.predictionLower,
381
+ result.predictionUpper,
382
+ result.residuals,
383
+ result.robustnessWeights,
384
+ result.diagnostics,
385
+ result.iterationsUsed,
386
+ result.fractionUsed,
387
+ result.cvScores
466
388
  ```
467
389
 
468
390
  **C++:**
@@ -487,99 +409,23 @@ options.cv_k = 5;
487
409
  options.auto_converge = 1e-4;
488
410
  options.parallel = true;
489
411
 
490
- auto result = fastlowess::smooth(x, y, options);
491
- ```
492
-
493
- ## Result Structure
494
-
495
- **R:**
496
-
497
- ```r
498
- result$x, result$y, result$standard_errors
499
- result$confidence_lower, result$confidence_upper
500
- result$prediction_lower, result$prediction_upper
501
- result$residuals, result$robustness_weights
502
- result$diagnostics, result$iterations_used
503
- result$fraction_used, result$cv_scores
504
- ```
505
-
506
- **Python:**
507
-
508
- ```python
509
- result.x, result.y, result.standard_errors
510
- result.confidence_lower, result.confidence_upper
511
- result.prediction_lower, result.prediction_upper
512
- result.residuals, result.robustness_weights
513
- result.diagnostics, result.iterations_used
514
- result.fraction_used, result.cv_scores
515
- ```
516
-
517
- **Rust:**
518
-
519
- ```rust
520
- pub struct LowessResult<T> {
521
- pub x: Vec<T>, // Sorted x values
522
- pub y: Vec<T>, // Smoothed y values
523
- pub standard_errors: Option<Vec<T>>,
524
- pub confidence_lower: Option<Vec<T>>,
525
- pub confidence_upper: Option<Vec<T>>,
526
- pub prediction_lower: Option<Vec<T>>,
527
- pub prediction_upper: Option<Vec<T>>,
528
- pub residuals: Option<Vec<T>>,
529
- pub robustness_weights: Option<Vec<T>>,
530
- pub diagnostics: Option<Diagnostics<T>>,
531
- pub iterations_used: Option<usize>,
532
- pub fraction_used: T,
533
- pub cv_scores: Option<Vec<T>>,
534
- }
535
- ```
536
-
537
- **Julia:**
538
-
539
- ```julia
540
- result.x, result.y, result.standard_errors
541
- result.confidence_lower, result.confidence_upper
542
- result.prediction_lower, result.prediction_upper
543
- result.residuals, result.robustness_weights
544
- result.diagnostics, result.iterations_used
545
- result.fraction_used
546
- ```
547
-
548
- **Node.js:**
549
-
550
- ```javascript
551
- result.x, result.y, result.standardErrors
552
- result.confidenceLower, result.confidenceUpper
553
- result.predictionLower, result.predictionUpper
554
- result.residuals, result.robustnessWeights
555
- result.diagnostics, result.iterationsUsed
556
- result.fractionUsed, result.cvScores
557
- ```
558
-
559
- **WebAssembly:**
560
-
561
- ```javascript
562
- result.x, result.y, result.standardErrors
563
- result.confidenceLower, result.confidenceUpper
564
- result.predictionLower, result.predictionUpper
565
- result.residuals, result.robustnessWeights
566
- result.diagnostics, result.iterationsUsed
567
- result.fractionUsed, result.cvScores
568
- ```
569
-
570
- **C++:**
571
-
572
- ```cpp
573
- result.y_vector() // std::vector<double>
574
- result.confidence_lower() // std::vector<double>
575
- result.confidence_upper() // std::vector<double>
576
- result.prediction_lower() // std::vector<double>
577
- result.prediction_upper() // std::vector<double>
578
- result.residuals() // std::vector<double>
579
- result.robustness_weights() // std::vector<double>
580
- result.diagnostics() // Diagnostics struct
581
- result.iterations_used() // size_t
582
- result.fraction_used() // double
412
+ fastlowess::Lowess model(options);
413
+ auto result = model.fit(x, y);
414
+
415
+ // Result structure:
416
+ result.x_vector(),
417
+ result.y_vector(),
418
+ result.standard_errors(),
419
+ result.confidence_lower(),
420
+ result.confidence_upper(),
421
+ result.prediction_lower(),
422
+ result.prediction_upper(),
423
+ result.residuals(),
424
+ result.robustness_weights(),
425
+ result.diagnostics(),
426
+ result.iterations_used(),
427
+ result.fraction_used(),
428
+ result.cv_scores()
583
429
  ```
584
430
 
585
431
  ---
@@ -590,17 +436,7 @@ Contributions are welcome! Please see the [CONTRIBUTING.md](https://github.com/t
590
436
 
591
437
  ## License
592
438
 
593
- Licensed under either of:
594
-
595
- - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
596
- - MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>)
597
-
598
- at your option.
599
-
600
- ## References
601
-
602
- - Cleveland, W.S. (1979). "Robust Locally Weighted Regression and Smoothing Scatterplots". *JASA*.
603
- - Cleveland, W.S. (1981). "LOWESS: A Program for Smoothing Scatterplots". *The American Statistician*.
439
+ Licensed under [MIT](https://github.com/thisisamirv/lowess-project/blob/main/LICENSE-MIT) or [Apache-2.0](https://github.com/thisisamirv/lowess-project/blob/main/LICENSE-APACHE).
604
440
 
605
441
  ## Citation
606
442