scm2cpp-lasso 0.10.0__tar.gz → 0.11.0__tar.gz

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.
Files changed (57) hide show
  1. {scm2cpp_lasso-0.10.0/src/scm2cpp_lasso.egg-info → scm2cpp_lasso-0.11.0}/PKG-INFO +24 -2
  2. scm2cpp_lasso-0.10.0/PKG-INFO → scm2cpp_lasso-0.11.0/README.md +22 -18
  3. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/pyproject.toml +2 -2
  4. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/__init__.py +360 -5
  5. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_classifiers.py +71 -0
  6. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_gramops_blas.py +25 -5
  7. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_gramops_loops.py +25 -5
  8. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/classifiers.cpp +8 -0
  9. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/classifiers.hpp +548 -0
  10. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/classifiers_capi.cpp +24 -0
  11. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_blas/gramops.cpp +2 -0
  12. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_blas/gramops.hpp +117 -12
  13. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_blas/gramops_capi.cpp +10 -4
  14. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_loops/gramops.cpp +2 -0
  15. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_loops/gramops.hpp +230 -111
  16. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/gramops_loops/gramops_capi.cpp +10 -4
  17. scm2cpp_lasso-0.10.0/README.md → scm2cpp_lasso-0.11.0/src/scm2cpp_lasso.egg-info/PKG-INFO +40 -0
  18. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/setup.cfg +0 -0
  19. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/setup.py +0 -0
  20. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/__init__.py +0 -0
  21. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader.py +0 -0
  22. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_derived_blas.py +0 -0
  23. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_derived_cublas.py +0 -0
  24. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_derived_loops.py +0 -0
  25. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_nmf_blas.py +0 -0
  26. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_nmf_cublas.py +0 -0
  27. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/_loader_nmf_loops.py +0 -0
  28. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_blas/lasso_design.cpp +0 -0
  29. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_blas/lasso_design.hpp +0 -0
  30. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_blas/lasso_design_capi.cpp +0 -0
  31. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_cublas/lasso_design.cpp +0 -0
  32. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_cublas/lasso_design.hpp +0 -0
  33. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_cublas/lasso_design_capi.cpp +0 -0
  34. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_loops/lasso_design.cpp +0 -0
  35. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_loops/lasso_design.hpp +0 -0
  36. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/derived_loops/lasso_design_capi.cpp +0 -0
  37. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/lasso_cov.cpp +0 -0
  38. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/lasso_cov.hpp +0 -0
  39. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/lasso_cov_capi.cpp +0 -0
  40. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_blas/nmf_cd.cpp +0 -0
  41. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_blas/nmf_cd.hpp +0 -0
  42. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_blas/nmf_cd_capi.cpp +0 -0
  43. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_cublas/nmf_cd.cpp +0 -0
  44. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_cublas/nmf_cd.hpp +0 -0
  45. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_cublas/nmf_cd_capi.cpp +0 -0
  46. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_loops/nmf_cd.cpp +0 -0
  47. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_loops/nmf_cd.hpp +0 -0
  48. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/nmf_loops/nmf_cd_capi.cpp +0 -0
  49. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/scm2cpp-blas.hpp +0 -0
  50. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/scm2cpp-cublas.hpp +0 -0
  51. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_generated/scm2cpp.hpp +0 -0
  52. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/_libfind.py +0 -0
  53. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso/batch_capi.cu +0 -0
  54. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso.egg-info/SOURCES.txt +0 -0
  55. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso.egg-info/dependency_links.txt +0 -0
  56. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso.egg-info/requires.txt +0 -0
  57. {scm2cpp_lasso-0.10.0 → scm2cpp_lasso-0.11.0}/src/scm2cpp_lasso.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scm2cpp-lasso
3
- Version: 0.10.0
4
- Summary: scikit-learn estimators (lasso, elastic net, ridge, ARD, SVM, SVR, logistic regression, Huber, NMF, Gaussian mixture, FastICA, PCA, graphical lasso, RANSAC, SGD, OMP, LARS) translated from Scheme to C++ by scm2cpp; GPU batch solver included
3
+ Version: 0.11.0
4
+ Summary: scikit-learn estimators (lasso, elastic net, ridge, ARD, SVM, SVR, logistic regression, GLMs, Huber, Theil-Sen, NMF, Gaussian mixture, FastICA, PCA, graphical lasso, RANSAC, SGD, OMP, LARS) translated from Scheme to C++ by scm2cpp; GPU batch solver included
5
5
  Author: Hirotaka Niitsuma
6
6
  License: MIT
7
7
  Project-URL: Homepage, https://github.com/niitsuma/scm2cpp
@@ -690,6 +690,28 @@ L1LinearSVM(C=1.0).fit(X, y).coef_
690
690
  Speed, from the repository README's table: SGD 1.2-3x, ARD 1.6-1.9x
691
691
  (3x with the Gram hoisted), LassoLarsIC 8-20x, the L1 SVM 1.1-1.5x.
692
692
 
693
+ ## GLMs, CV and Theil-Sen: `LBFGSPoissonRegressor`, `LBFGSGammaRegressor`, `LBFGSTweedieRegressor`, `LBFGSLogisticRegressionCV`, `GramLarsCV`, `GramLassoLarsCV`, `GramOMPCV`, `WeiszfeldTheilSen`
694
+
695
+ - The GLMs are `PoissonRegressor`, `GammaRegressor` and
696
+ `TweedieRegressor` (solver "lbfgs"), over the same L-BFGS-B as
697
+ `LBFGSLogisticRegression`.
698
+ - The CV classes reproduce `LogisticRegressionCV`, `LarsCV`,
699
+ `LassoLarsCV` and `OrthogonalMatchingPursuitCV`: the same folds (KFold
700
+ / StratifiedKFold without shuffling), the same choice of C, alpha or
701
+ number of columns, and the same refit.
702
+ - `WeiszfeldTheilSen` is `TheilSenRegressor` on scikit-learn's own
703
+ subsets.
704
+
705
+ ```python
706
+ from scm2cpp_lasso import LBFGSPoissonRegressor, LBFGSLogisticRegressionCV, GramLassoLarsCV
707
+ LBFGSPoissonRegressor(alpha=1e-3).fit(X, counts).predict(X_new)
708
+ LBFGSLogisticRegressionCV().fit(X, labels).C_
709
+ GramLassoLarsCV().fit(X, y).alpha_
710
+ ```
711
+
712
+ Speed, from the repository README's table: the GLMs 1.1-6x, the CV
713
+ estimators 1.6-6.6x, Theil-Sen 1.3-1.8x (its subset drawing dominates).
714
+
693
715
  ## Logistic regression with L1
694
716
 
695
717
  `CovLogistic` solves L1-penalized logistic regression by
@@ -1,21 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: scm2cpp-lasso
3
- Version: 0.10.0
4
- Summary: scikit-learn estimators (lasso, elastic net, ridge, ARD, SVM, SVR, logistic regression, Huber, NMF, Gaussian mixture, FastICA, PCA, graphical lasso, RANSAC, SGD, OMP, LARS) translated from Scheme to C++ by scm2cpp; GPU batch solver included
5
- Author: Hirotaka Niitsuma
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/niitsuma/scm2cpp
8
- Project-URL: Source, https://github.com/niitsuma/scm2cpp/tree/master/python/scm2cpp-lasso
9
- Keywords: lasso,elastic-net,ridge,svm,logistic-regression,coordinate-descent,cuda,compiler
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: C++
13
- Classifier: Topic :: Scientific/Engineering :: Mathematics
14
- Classifier: Intended Audience :: Science/Research
15
- Requires-Python: >=3.8
16
- Description-Content-Type: text/markdown
17
- Requires-Dist: numpy>=1.17
18
-
19
1
  # scm2cpp-lasso
20
2
 
21
3
  *[Japanese (README.ja.md)](README.ja.md)*
@@ -690,6 +672,28 @@ L1LinearSVM(C=1.0).fit(X, y).coef_
690
672
  Speed, from the repository README's table: SGD 1.2-3x, ARD 1.6-1.9x
691
673
  (3x with the Gram hoisted), LassoLarsIC 8-20x, the L1 SVM 1.1-1.5x.
692
674
 
675
+ ## GLMs, CV and Theil-Sen: `LBFGSPoissonRegressor`, `LBFGSGammaRegressor`, `LBFGSTweedieRegressor`, `LBFGSLogisticRegressionCV`, `GramLarsCV`, `GramLassoLarsCV`, `GramOMPCV`, `WeiszfeldTheilSen`
676
+
677
+ - The GLMs are `PoissonRegressor`, `GammaRegressor` and
678
+ `TweedieRegressor` (solver "lbfgs"), over the same L-BFGS-B as
679
+ `LBFGSLogisticRegression`.
680
+ - The CV classes reproduce `LogisticRegressionCV`, `LarsCV`,
681
+ `LassoLarsCV` and `OrthogonalMatchingPursuitCV`: the same folds (KFold
682
+ / StratifiedKFold without shuffling), the same choice of C, alpha or
683
+ number of columns, and the same refit.
684
+ - `WeiszfeldTheilSen` is `TheilSenRegressor` on scikit-learn's own
685
+ subsets.
686
+
687
+ ```python
688
+ from scm2cpp_lasso import LBFGSPoissonRegressor, LBFGSLogisticRegressionCV, GramLassoLarsCV
689
+ LBFGSPoissonRegressor(alpha=1e-3).fit(X, counts).predict(X_new)
690
+ LBFGSLogisticRegressionCV().fit(X, labels).C_
691
+ GramLassoLarsCV().fit(X, y).alpha_
692
+ ```
693
+
694
+ Speed, from the repository README's table: the GLMs 1.1-6x, the CV
695
+ estimators 1.6-6.6x, Theil-Sen 1.3-1.8x (its subset drawing dominates).
696
+
693
697
  ## Logistic regression with L1
694
698
 
695
699
  `CovLogistic` solves L1-penalized logistic regression by
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scm2cpp-lasso"
7
- version = "0.10.0"
8
- description = "scikit-learn estimators (lasso, elastic net, ridge, ARD, SVM, SVR, logistic regression, Huber, NMF, Gaussian mixture, FastICA, PCA, graphical lasso, RANSAC, SGD, OMP, LARS) translated from Scheme to C++ by scm2cpp; GPU batch solver included"
7
+ version = "0.11.0"
8
+ description = "scikit-learn estimators (lasso, elastic net, ridge, ARD, SVM, SVR, logistic regression, GLMs, Huber, Theil-Sen, NMF, Gaussian mixture, FastICA, PCA, graphical lasso, RANSAC, SGD, OMP, LARS) translated from Scheme to C++ by scm2cpp; GPU batch solver included"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
11
11
  license = {text = "MIT"}
@@ -43,12 +43,14 @@ __all__ = ["CovLasso", "CovRidge", "CovBayesianRidge", "CovLogistic", "CovGroupL
43
43
  "LinearSVM", "KernelSVM", "LinearSVR", "KernelSVR", "L1LogisticRegression",
44
44
  "CDNMF", "nmf_backend", "CDGraphicalLasso", "LinearRANSAC",
45
45
  "SGDLinearClassifier", "SGDLinearRegressor", "SGDPerceptron", "GramOMP", "GramLars", "GramLassoLars", "GramLassoLarsIC",
46
- "LBFGSLogisticRegression", "LBFGSHuberRegressor",
46
+ "LBFGSLogisticRegression", "LBFGSHuberRegressor", "LBFGSLogisticRegressionCV",
47
+ "LBFGSPoissonRegressor", "LBFGSGammaRegressor", "LBFGSTweedieRegressor",
48
+ "GramLarsCV", "GramLassoLarsCV", "GramOMPCV",
47
49
  "EMGaussianMixture", "CovPCA", "ParallelFastICA", "CovARDRegression",
48
- "L1LinearSVM",
50
+ "L1LinearSVM", "WeiszfeldTheilSen",
49
51
  "CovMultiTaskLasso", "CovMultiTaskLassoCV", "DerivedLasso",
50
52
  "cuda_available", "derived_backend", "kernel"]
51
- __version__ = "0.10.0"
53
+ __version__ = "0.11.0"
52
54
 
53
55
  _BATCH = load_batch_lib()
54
56
  _DP = ctypes.POINTER(ctypes.c_double)
@@ -1305,7 +1307,7 @@ class GramOMP:
1305
1307
  k = max(int(0.1 * p), 1) if self.n_nonzero_coefs is None else int(self.n_nonzero_coefs)
1306
1308
  lib = importlib.import_module(f"{__name__}._generated._loader_gramops_{gramops_backend()}")
1307
1309
  self.coef_ = np.zeros(p)
1308
- self.n_iter_ = lib.omp(Xc, yc, self.coef_, k, n, p)
1310
+ self.n_iter_ = lib.omp(Xc, yc, self.coef_, np.zeros(1), 0, k, n, p)
1309
1311
  self.intercept_ = ym - float(xm @ self.coef_)
1310
1312
  return self
1311
1313
 
@@ -1374,6 +1376,186 @@ class LBFGSLogisticRegression:
1374
1376
  return self.classes_[np.argmax(z, axis=1)]
1375
1377
 
1376
1378
 
1379
+ def _kfold(n, k):
1380
+ """scikit-learn's KFold(k) without shuffling: contiguous test blocks,
1381
+ the first n % k of them one longer."""
1382
+ sizes = np.full(k, n // k)
1383
+ sizes[: n % k] += 1
1384
+ out, start = [], 0
1385
+ for sz in sizes:
1386
+ test = np.arange(start, start + sz)
1387
+ out.append((np.r_[np.arange(0, start), np.arange(start + sz, n)], test))
1388
+ start += sz
1389
+ return out
1390
+
1391
+
1392
+ def _stratified_kfold(y, k):
1393
+ """scikit-learn's StratifiedKFold(k) without shuffling: classes in
1394
+ order of first appearance, each spread over the folds as the sorted
1395
+ labels dealt k ways."""
1396
+ y = np.asarray(y)
1397
+ _, y_idx, y_inv = np.unique(y, return_index=True, return_inverse=True)
1398
+ _, class_perm = np.unique(y_idx, return_inverse=True)
1399
+ y_enc = class_perm[y_inv]
1400
+ nc = len(y_idx)
1401
+ y_order = np.sort(y_enc)
1402
+ alloc = np.asarray([np.bincount(y_order[i::k], minlength=nc) for i in range(k)])
1403
+ test_folds = np.empty(len(y), dtype=int)
1404
+ for c in range(nc):
1405
+ test_folds[y_enc == c] = np.arange(k).repeat(alloc[:, c])
1406
+ return [(np.flatnonzero(test_folds != f), np.flatnonzero(test_folds == f))
1407
+ for f in range(k)]
1408
+
1409
+
1410
+ class _LBFGSGLM:
1411
+ _family = None
1412
+
1413
+ def fit(self, X, y):
1414
+ X = np.ascontiguousarray(X, dtype=np.float64)
1415
+ y = np.ascontiguousarray(y, dtype=np.float64)
1416
+ n, p = X.shape
1417
+ coef = np.zeros(p + 1)
1418
+ out = np.zeros(2)
1419
+ fam, power = self._family_power()
1420
+ it = _gramops_kernels().glm(X, y, coef, out, fam, float(power), float(self.alpha),
1421
+ int(self.max_iter), float(self.tol),
1422
+ 1 if self.fit_intercept else 0, n, p)
1423
+ self.coef_, self.intercept_ = coef[:p].copy(), float(coef[p])
1424
+ self.n_iter_ = min(it, self.max_iter)
1425
+ return self
1426
+
1427
+ def _linear(self, X):
1428
+ return np.ascontiguousarray(X, dtype=np.float64) @ self.coef_ + self.intercept_
1429
+
1430
+ def predict(self, X):
1431
+ z = self._linear(X)
1432
+ return z if self._family_power() == (3, 0.0) else np.exp(z)
1433
+
1434
+
1435
+ class LBFGSPoissonRegressor(_LBFGSGLM):
1436
+ """scikit-learn's ``PoissonRegressor`` (solver "lbfgs") translated
1437
+ whole (``examples/kernel-only/glm.scm`` over ``lbfgs.scm``): the mean
1438
+ half Poisson deviance with the log link plus alpha |w|^2 / 2, from
1439
+ scikit-learn's start. Same iterations and coefficients to rounding.
1440
+
1441
+ Attributes after fit: coef_, intercept_, n_iter_.
1442
+ """
1443
+
1444
+ def __init__(self, *, alpha=1.0, fit_intercept=True, max_iter=100, tol=1e-4):
1445
+ self.alpha, self.fit_intercept, self.max_iter, self.tol = alpha, fit_intercept, max_iter, tol
1446
+
1447
+ def _family_power(self):
1448
+ return 0, 1.0
1449
+
1450
+
1451
+ class LBFGSGammaRegressor(LBFGSPoissonRegressor):
1452
+ """scikit-learn's ``GammaRegressor`` (solver "lbfgs"), as
1453
+ LBFGSPoissonRegressor with the half Gamma deviance.
1454
+
1455
+ Attributes after fit: coef_, intercept_, n_iter_.
1456
+ """
1457
+
1458
+ def _family_power(self):
1459
+ return 1, 2.0
1460
+
1461
+
1462
+ class LBFGSTweedieRegressor(_LBFGSGLM):
1463
+ """scikit-learn's ``TweedieRegressor`` (solver "lbfgs"): ``power`` 0
1464
+ with the identity link (the default), or a power of 1 or more with
1465
+ the log link, as link="auto" chooses.
1466
+
1467
+ Attributes after fit: coef_, intercept_, n_iter_.
1468
+ """
1469
+
1470
+ def __init__(self, *, power=0.0, alpha=1.0, fit_intercept=True, max_iter=100, tol=1e-4):
1471
+ self.power, self.alpha, self.fit_intercept = power, alpha, fit_intercept
1472
+ self.max_iter, self.tol = max_iter, tol
1473
+
1474
+ def _family_power(self):
1475
+ if self.power == 0:
1476
+ return 3, 0.0
1477
+ if self.power < 1:
1478
+ raise ValueError("power is 0 or at least 1 here")
1479
+ return 2, float(self.power)
1480
+
1481
+
1482
+ class LBFGSLogisticRegressionCV:
1483
+ """scikit-learn's ``LogisticRegressionCV`` with its defaults (the L2
1484
+ penalty, solver "lbfgs", Cs 10 values from 1e-4 to 1e4,
1485
+ StratifiedKFold(5) without shuffling, accuracy, refit): each fold's
1486
+ path over the Cs warm-started from the previous C by the translated
1487
+ LogisticRegression (``logistic-lbfgs.scm``), the C of the best summed
1488
+ score, and the refit from the folds' mean coefficients at that C, as
1489
+ scikit-learn starts it.
1490
+
1491
+ Attributes after fit: classes_, Cs_, C_, coef_, intercept_, scores_,
1492
+ n_iter_.
1493
+ """
1494
+
1495
+ def __init__(self, *, Cs=10, cv=5, tol=1e-4, max_iter=100, fit_intercept=True):
1496
+ self.Cs, self.cv, self.tol, self.max_iter = Cs, cv, tol, max_iter
1497
+ self.fit_intercept = fit_intercept
1498
+
1499
+ def _path(self, X, yi, Cs, coef, multi, k):
1500
+ n, p = X.shape
1501
+ lib = _gramops_kernels()
1502
+ coefs, iters = [], []
1503
+ out = np.zeros(2)
1504
+ for C in Cs:
1505
+ it = lib.logistic_lbfgs(X, yi, coef, out, float(C), int(self.max_iter),
1506
+ float(self.tol), multi, 1 if self.fit_intercept else 0,
1507
+ n, p, k)
1508
+ coefs.append(coef.copy())
1509
+ iters.append(min(it, self.max_iter))
1510
+ return coefs, iters
1511
+
1512
+ def fit(self, X, y):
1513
+ X = np.ascontiguousarray(X, dtype=np.float64)
1514
+ y = np.asarray(y)
1515
+ self.classes_, yi = np.unique(y, return_inverse=True)
1516
+ nc = len(self.classes_)
1517
+ multi = 1 if nc > 2 else 0
1518
+ k = nc if multi else 1
1519
+ n, p = X.shape
1520
+ Cs = np.logspace(-4, 4, self.Cs) if np.isscalar(self.Cs) else np.asarray(self.Cs, float)
1521
+ self.Cs_ = Cs
1522
+ yf = yi.astype(np.float64)
1523
+ folds = _stratified_kfold(y, int(self.cv))
1524
+ paths, scores, iters = [], [], []
1525
+ for train, test in folds:
1526
+ coefs, it = self._path(np.ascontiguousarray(X[train]), yf[train], Cs,
1527
+ np.zeros(k * (p + 1)), multi, k)
1528
+ paths.append(coefs)
1529
+ iters.append(it)
1530
+ sc = []
1531
+ for c in coefs:
1532
+ z = X[test] @ c[:k * p].reshape(k, p).T + c[k * p:]
1533
+ pred = (z[:, 0] > 0).astype(int) if k == 1 else np.argmax(z, axis=1)
1534
+ sc.append(float(np.mean(pred == yi[test])))
1535
+ scores.append(sc)
1536
+ scores = np.asarray(scores)
1537
+ best = int(np.argmax(scores.sum(axis=0)))
1538
+ self.C_ = float(Cs[best])
1539
+ start = np.mean([paths[f][best] for f in range(len(folds))], axis=0)
1540
+ coefs, it = self._path(X, yf, [self.C_], start.copy(), multi, k)
1541
+ c = coefs[0]
1542
+ self.coef_ = c[:k * p].reshape(k, p).copy()
1543
+ self.intercept_ = c[k * p:].copy()
1544
+ self.scores_ = scores
1545
+ self.n_iter_ = np.asarray(iters)
1546
+ return self
1547
+
1548
+ def decision_function(self, X):
1549
+ z = np.ascontiguousarray(X, dtype=np.float64) @ self.coef_.T + self.intercept_
1550
+ return z[:, 0] if z.shape[1] == 1 else z
1551
+
1552
+ def predict(self, X):
1553
+ z = self.decision_function(X)
1554
+ if z.ndim == 1:
1555
+ return self.classes_[(z > 0).astype(int)]
1556
+ return self.classes_[np.argmax(z, axis=1)]
1557
+
1558
+
1377
1559
  class LBFGSHuberRegressor:
1378
1560
  """The Huber regressor, scikit-learn's ``HuberRegressor`` translated
1379
1561
  whole (``examples/kernel-only/huber.scm`` over ``lbfgs.scm``): its
@@ -1671,6 +1853,127 @@ class GramLassoLars(_GramLarsBase):
1671
1853
  return self._fit_lars(X, y, 1, self.alpha, self.max_iter)
1672
1854
 
1673
1855
 
1856
+ class _GramLarsCVBase:
1857
+ """LarsCV / LassoLarsCV: KFold(cv) without shuffling; on each fold
1858
+ the whole path by the translated LARS over the training fold's Gram
1859
+ (centred on the training means), the test residuals interpolated
1860
+ onto the union of the folds' alphas as scikit-learn interpolates
1861
+ them (the path's coefficients interpolated, the residuals being
1862
+ affine in them, the mean square from the test fold's Gram); the
1863
+ alpha of the least mean square error, refitted on all the data."""
1864
+
1865
+ def __init__(self, *, fit_intercept=True, max_iter=500, cv=5, max_n_alphas=1000):
1866
+ self.fit_intercept, self.max_iter, self.cv = fit_intercept, int(max_iter), cv
1867
+ self.max_n_alphas = max_n_alphas
1868
+
1869
+ def _lars(self, Xc, yc, alpha_min, rec):
1870
+ n, p = Xc.shape
1871
+ G = np.ascontiguousarray(Xc.T @ Xc)
1872
+ cov = Xc.T @ yc
1873
+ coef = np.zeros(p)
1874
+ path = np.zeros((self.max_iter + 1, p)) if rec else np.zeros(1)
1875
+ alphas = np.zeros(self.max_iter + 1) if rec else np.zeros(1)
1876
+ it = _classifier_kernels().lars(G, cov, coef, path, alphas, 1 if rec else 0, float(n),
1877
+ float(alpha_min), self._method, self.max_iter,
1878
+ float(np.finfo(np.float64).eps), p)
1879
+ return it, coef, (path[:it + 1] if rec else None), (alphas[:it + 1] if rec else None)
1880
+
1881
+ def fit(self, X, y):
1882
+ X = np.ascontiguousarray(X, dtype=np.float64)
1883
+ y = np.ascontiguousarray(y, dtype=np.float64)
1884
+ n, p = X.shape
1885
+ folds = []
1886
+ for train, test in _kfold(n, int(self.cv)):
1887
+ Xtr, ytr, Xte, yte = X[train], y[train], X[test], y[test]
1888
+ if self.fit_intercept:
1889
+ xm, ym = Xtr.mean(axis=0), ytr.mean()
1890
+ Xtr, Xte, ytr, yte = Xtr - xm, Xte - xm, ytr - ym, yte - ym
1891
+ _, _, path, alphas = self._lars(np.ascontiguousarray(Xtr), ytr, 0.0, True)
1892
+ folds.append((alphas, path, Xte.T @ Xte, Xte.T @ yte, float(yte @ yte), len(test)))
1893
+ all_alphas = np.unique(np.concatenate([f[0] for f in folds]))
1894
+ stride = int(max(1, int(len(all_alphas) / float(self.max_n_alphas))))
1895
+ all_alphas = all_alphas[::stride]
1896
+ mse = np.empty((len(all_alphas), len(folds)))
1897
+ for j, (alphas, path, Gt, cyt, yy, nt) in enumerate(folds):
1898
+ a, c = alphas[::-1], path[::-1]
1899
+ if a[0] != 0:
1900
+ a, c = np.r_[0, a], np.r_[c[:1], c]
1901
+ if a[-1] != all_alphas[-1]:
1902
+ a, c = np.r_[a, all_alphas[-1]], np.r_[c, c[-1:]]
1903
+ ci = np.column_stack([np.interp(all_alphas, a, c[:, q]) for q in range(p)])
1904
+ mse[:, j] = (((ci @ Gt) * ci).sum(axis=1) - 2.0 * ci @ cyt + yy) / nt
1905
+ mask = np.all(np.isfinite(mse), axis=-1)
1906
+ all_alphas, mse = all_alphas[mask], mse[mask]
1907
+ self.alpha_ = float(all_alphas[int(np.argmin(mse.mean(axis=-1)))])
1908
+ self.cv_alphas_, self.mse_path_ = all_alphas, mse
1909
+ Xc, yc, xm, ym = _center(X, y, self.fit_intercept)
1910
+ self.n_iter_, self.coef_, _, _ = self._lars(Xc, yc, self.alpha_, False)
1911
+ self.intercept_ = ym - float(xm @ self.coef_)
1912
+ return self
1913
+
1914
+ def predict(self, X):
1915
+ return np.ascontiguousarray(X, dtype=np.float64) @ self.coef_ + self.intercept_
1916
+
1917
+
1918
+ class GramLarsCV(_GramLarsCVBase):
1919
+ """scikit-learn's ``LarsCV`` (method "lar") over the translated LARS;
1920
+ see _GramLarsCVBase. Attributes after fit: alpha_, coef_, intercept_,
1921
+ cv_alphas_, mse_path_, n_iter_."""
1922
+ _method = 0
1923
+
1924
+
1925
+ class GramLassoLarsCV(_GramLarsCVBase):
1926
+ """scikit-learn's ``LassoLarsCV`` (method "lasso") over the translated
1927
+ LARS; see _GramLarsCVBase. Attributes after fit: alpha_, coef_,
1928
+ intercept_, cv_alphas_, mse_path_, n_iter_."""
1929
+ _method = 1
1930
+
1931
+
1932
+ class GramOMPCV:
1933
+ """scikit-learn's ``OrthogonalMatchingPursuitCV``: KFold(cv) without
1934
+ shuffling; on each fold the path of the translated OMP (``omp.scm``,
1935
+ the path recorded) up to ``max_iter`` columns on the centred training
1936
+ fold, the test fold's mean square error after each column, the number
1937
+ of columns that minimises the folds' mean (over the shortest path),
1938
+ refitted as GramOMP. ``max_iter`` defaults, as there, to
1939
+ min(max(10% of p, 5), p).
1940
+
1941
+ Attributes after fit: n_nonzero_coefs_, coef_, intercept_, n_iter_.
1942
+ """
1943
+
1944
+ def __init__(self, *, fit_intercept=True, max_iter=None, cv=5):
1945
+ self.fit_intercept, self.max_iter, self.cv = fit_intercept, max_iter, cv
1946
+
1947
+ def fit(self, X, y):
1948
+ X = np.ascontiguousarray(X, dtype=np.float64)
1949
+ y = np.ascontiguousarray(y, dtype=np.float64)
1950
+ n, p = X.shape
1951
+ kmax = min(max(int(0.1 * p), 5), p) if self.max_iter is None else int(self.max_iter)
1952
+ lib = _gramops_kernels()
1953
+ mses = []
1954
+ for train, test in _kfold(n, int(self.cv)):
1955
+ Xtr, ytr, Xte, yte = X[train], y[train], X[test], y[test]
1956
+ if self.fit_intercept:
1957
+ xm, ym = Xtr.mean(axis=0), ytr.mean()
1958
+ Xtr, Xte, ytr, yte = Xtr - xm, Xte - xm, ytr - ym, yte - ym
1959
+ path = np.zeros((kmax, p))
1960
+ k = lib.omp(np.ascontiguousarray(Xtr), np.ascontiguousarray(ytr), np.zeros(p),
1961
+ path, 1, kmax, len(train), p)
1962
+ res = Xte @ path[:k].T - yte[:, None]
1963
+ mses.append((res ** 2).mean(axis=0))
1964
+ m = min(len(f) for f in mses)
1965
+ best = int(np.argmin(np.mean([f[:m] for f in mses], axis=0))) + 1
1966
+ self.n_nonzero_coefs_ = best
1967
+ Xc, yc, xm, ym = _center(X, y, self.fit_intercept)
1968
+ self.coef_ = np.zeros(p)
1969
+ self.n_iter_ = lib.omp(Xc, yc, self.coef_, np.zeros(1), 0, best, n, p)
1970
+ self.intercept_ = ym - float(xm @ self.coef_)
1971
+ return self
1972
+
1973
+ def predict(self, X):
1974
+ return np.ascontiguousarray(X, dtype=np.float64) @ self.coef_ + self.intercept_
1975
+
1976
+
1674
1977
  class GramLassoLarsIC:
1675
1978
  """LassoLars with the penalty chosen by AIC or BIC, scikit-learn's
1676
1979
  ``LassoLarsIC``: the whole "lasso" path by the translated
@@ -1705,7 +2008,7 @@ class GramLassoLarsIC:
1705
2008
  G0.copy(), cov0.copy(), coef, path, alphas, 1, float(n), 0.0, 1, self.max_iter,
1706
2009
  float(np.finfo(np.float64).eps), p)
1707
2010
  cp, al = path[:it + 1], alphas[:it + 1]
1708
- rss = yy - 2.0 * (cp @ cov0) + np.einsum("sj,jk,sk->s", cp, G0, cp)
2011
+ rss = yy - 2.0 * (cp @ cov0) + ((cp @ G0) * cp).sum(axis=1)
1709
2012
  df = (np.abs(cp) > np.finfo(np.float64).eps).sum(axis=1)
1710
2013
  if self.noise_variance is None:
1711
2014
  if n <= p + int(self.fit_intercept):
@@ -1731,6 +2034,58 @@ class GramLassoLarsIC:
1731
2034
  return np.ascontiguousarray(X, dtype=np.float64) @ self.coef_ + self.intercept_
1732
2035
 
1733
2036
 
2037
+ class WeiszfeldTheilSen:
2038
+ """scikit-learn's ``TheilSenRegressor`` translated whole
2039
+ (``examples/kernel-only/theilsen.scm``): the least squares fit of
2040
+ every subset of n_subsamples rows (p + 1 by default: each an exact
2041
+ solve, the minimum-norm fit for a singular one, as gelss gives it)
2042
+ and the spatial median of the fits by the modified Weiszfeld
2043
+ iteration. The subsets are scikit-learn's: all the combinations
2044
+ when there are at most ``max_subpopulation``, else
2045
+ ``RandomState(random_state).choice`` draws, made here the same way
2046
+ (and on large problems that drawing is most of the time, on both
2047
+ sides).
2048
+
2049
+ Attributes after fit: coef_, intercept_, n_iter_, n_subpopulation_,
2050
+ breakdown_.
2051
+ """
2052
+
2053
+ def __init__(self, *, fit_intercept=True, max_subpopulation=1e4, n_subsamples=None,
2054
+ max_iter=300, tol=1e-3, random_state=None):
2055
+ self.fit_intercept, self.max_subpopulation = fit_intercept, max_subpopulation
2056
+ self.n_subsamples, self.max_iter, self.tol = n_subsamples, max_iter, tol
2057
+ self.random_state = random_state
2058
+
2059
+ def fit(self, X, y):
2060
+ from itertools import combinations
2061
+ from math import comb
2062
+ X = np.ascontiguousarray(X, dtype=np.float64)
2063
+ y = np.ascontiguousarray(y, dtype=np.float64)
2064
+ n, p = X.shape
2065
+ fi = 1 if self.fit_intercept else 0
2066
+ ns = min(p + fi, n) if self.n_subsamples is None else int(self.n_subsamples)
2067
+ total = max(1, comb(n, ns))
2068
+ self.n_subpopulation_ = int(min(self.max_subpopulation, total))
2069
+ self.breakdown_ = 1 - (0.5 ** (1 / ns) * (n - ns + 1) + ns - 1) / n
2070
+ if total <= self.max_subpopulation:
2071
+ idx = np.array(list(combinations(range(n), ns)), dtype=np.int32)
2072
+ else:
2073
+ rs = np.random.RandomState(self.random_state)
2074
+ idx = np.array([rs.choice(n, size=ns, replace=False)
2075
+ for _ in range(self.n_subpopulation_)], dtype=np.int32)
2076
+ nsub = len(idx)
2077
+ w = np.zeros((nsub, p + fi))
2078
+ c = np.zeros(p + fi)
2079
+ self.n_iter_ = _classifier_kernels().theilsen(X, y, idx, w, c, nsub, ns, fi,
2080
+ int(self.max_iter), float(self.tol), p)
2081
+ self.intercept_ = float(c[0]) if fi else 0.0
2082
+ self.coef_ = c[fi:].copy()
2083
+ return self
2084
+
2085
+ def predict(self, X):
2086
+ return np.ascontiguousarray(X, dtype=np.float64) @ self.coef_ + self.intercept_
2087
+
2088
+
1734
2089
  class L1LinearSVM:
1735
2090
  """The L1-regularized L2-loss linear SVM by liblinear's own
1736
2091
  algorithm: ``examples/kernel-only/svm-l1.scm`` translated plainly,
@@ -208,3 +208,74 @@ _lib.scm2cpp_svm_l1_abs.argtypes = [ctypes.c_double]
208
208
  def svm_l1_abs(a):
209
209
  return _lib.scm2cpp_svm_l1_abs(a)
210
210
 
211
+ _lib.scm2cpp_eig_hypot.restype = ctypes.c_double
212
+ _lib.scm2cpp_eig_hypot.argtypes = [ctypes.c_double, ctypes.c_double]
213
+ def eig_hypot(a, b):
214
+ return _lib.scm2cpp_eig_hypot(a, b)
215
+
216
+ _lib.scm2cpp_sym_eigen.restype = ctypes.c_int
217
+ _lib.scm2cpp_sym_eigen.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int]
218
+ def sym_eigen(a, v, ev, e, m):
219
+ a = np.ascontiguousarray(a, dtype=np.float64)
220
+ v = np.ascontiguousarray(v, dtype=np.float64)
221
+ ev = np.ascontiguousarray(ev, dtype=np.float64)
222
+ e = np.ascontiguousarray(e, dtype=np.float64)
223
+ return _lib.scm2cpp_sym_eigen(a.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), v.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ev.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), e.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), m)
224
+
225
+ _lib.scm2cpp_eig_abs.restype = ctypes.c_double
226
+ _lib.scm2cpp_eig_abs.argtypes = [ctypes.c_double]
227
+ def eig_abs(a):
228
+ return _lib.scm2cpp_eig_abs(a)
229
+
230
+ _lib.scm2cpp_eig_order.restype = ctypes.c_int
231
+ _lib.scm2cpp_eig_order.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_int), ctypes.c_int]
232
+ def eig_order(ev, ord, m):
233
+ ev = np.ascontiguousarray(ev, dtype=np.float64)
234
+ ord = np.ascontiguousarray(ord, dtype=np.int32)
235
+ return _lib.scm2cpp_eig_order(ev.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ord.ctypes.data_as(ctypes.POINTER(ctypes.c_int)), m)
236
+
237
+ _lib.scm2cpp_ts_minnorm.restype = ctypes.c_int
238
+ _lib.scm2cpp_ts_minnorm.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
239
+ def ts_minnorm(x, y, idx, w, aa, v, ev, e, ab, s, ns, fitint, p, d):
240
+ x = np.ascontiguousarray(x, dtype=np.float64)
241
+ y = np.ascontiguousarray(y, dtype=np.float64)
242
+ idx = np.ascontiguousarray(idx, dtype=np.int32)
243
+ w = np.ascontiguousarray(w, dtype=np.float64)
244
+ aa = np.ascontiguousarray(aa, dtype=np.float64)
245
+ v = np.ascontiguousarray(v, dtype=np.float64)
246
+ ev = np.ascontiguousarray(ev, dtype=np.float64)
247
+ e = np.ascontiguousarray(e, dtype=np.float64)
248
+ ab = np.ascontiguousarray(ab, dtype=np.float64)
249
+ return _lib.scm2cpp_ts_minnorm(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), idx.ctypes.data_as(ctypes.POINTER(ctypes.c_int)), w.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), aa.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), v.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ev.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), e.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ab.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), s, ns, fitint, p, d)
250
+
251
+ _lib.scm2cpp_ts_fit.restype = ctypes.c_int
252
+ _lib.scm2cpp_ts_fit.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
253
+ def ts_fit(x, y, idx, w, a, b, aa, v, ev, e, ab, s, ns, fitint, p, d):
254
+ x = np.ascontiguousarray(x, dtype=np.float64)
255
+ y = np.ascontiguousarray(y, dtype=np.float64)
256
+ idx = np.ascontiguousarray(idx, dtype=np.int32)
257
+ w = np.ascontiguousarray(w, dtype=np.float64)
258
+ a = np.ascontiguousarray(a, dtype=np.float64)
259
+ b = np.ascontiguousarray(b, dtype=np.float64)
260
+ aa = np.ascontiguousarray(aa, dtype=np.float64)
261
+ v = np.ascontiguousarray(v, dtype=np.float64)
262
+ ev = np.ascontiguousarray(ev, dtype=np.float64)
263
+ e = np.ascontiguousarray(e, dtype=np.float64)
264
+ ab = np.ascontiguousarray(ab, dtype=np.float64)
265
+ return _lib.scm2cpp_ts_fit(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), idx.ctypes.data_as(ctypes.POINTER(ctypes.c_int)), w.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), a.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), b.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), aa.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), v.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ev.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), e.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), ab.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), s, ns, fitint, p, d)
266
+
267
+ _lib.scm2cpp_ts_abs.restype = ctypes.c_double
268
+ _lib.scm2cpp_ts_abs.argtypes = [ctypes.c_double]
269
+ def ts_abs(v):
270
+ return _lib.scm2cpp_ts_abs(v)
271
+
272
+ _lib.scm2cpp_theilsen.restype = ctypes.c_int
273
+ _lib.scm2cpp_theilsen.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_double, ctypes.c_int]
274
+ def theilsen(x, y, idx, w, coef, nsub, ns, fitint, maxiter, tol, p):
275
+ x = np.ascontiguousarray(x, dtype=np.float64)
276
+ y = np.ascontiguousarray(y, dtype=np.float64)
277
+ idx = np.ascontiguousarray(idx, dtype=np.int32)
278
+ w = np.ascontiguousarray(w, dtype=np.float64)
279
+ coef = np.ascontiguousarray(coef, dtype=np.float64)
280
+ return _lib.scm2cpp_theilsen(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), idx.ctypes.data_as(ctypes.POINTER(ctypes.c_int)), w.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), nsub, ns, fitint, maxiter, tol, p)
281
+
@@ -66,12 +66,13 @@ def graphical_lasso(emp, cov, prec, alpha, maxiter, tol, enettol, p):
66
66
  return _lib.scm2cpp_graphical_lasso(emp.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), cov.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), prec.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), alpha, maxiter, tol, enettol, p)
67
67
 
68
68
  _lib.scm2cpp_omp.restype = ctypes.c_int
69
- _lib.scm2cpp_omp.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.c_int]
70
- def omp(x, y, coef, kmax, n, p):
69
+ _lib.scm2cpp_omp.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
70
+ def omp(x, y, coef, path, rec, kmax, n, p):
71
71
  x = np.ascontiguousarray(x, dtype=np.float64)
72
72
  y = np.ascontiguousarray(y, dtype=np.float64)
73
73
  coef = np.ascontiguousarray(coef, dtype=np.float64)
74
- return _lib.scm2cpp_omp(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), kmax, n, p)
74
+ path = np.ascontiguousarray(path, dtype=np.float64)
75
+ return _lib.scm2cpp_omp(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), path.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), rec, kmax, n, p)
75
76
 
76
77
  _lib.scm2cpp_logistic_fg.restype = ctypes.c_double
77
78
  _lib.scm2cpp_logistic_fg.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_double, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
@@ -111,6 +112,25 @@ def huber(x, y, coef, out, epsilon, alpha, maxiter, tol, fitint, n, p):
111
112
  out = np.ascontiguousarray(out, dtype=np.float64)
112
113
  return _lib.scm2cpp_huber(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), epsilon, alpha, maxiter, tol, fitint, n, p)
113
114
 
115
+ _lib.scm2cpp_glm_fg.restype = ctypes.c_double
116
+ _lib.scm2cpp_glm_fg.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_double, ctypes.c_double, ctypes.c_int, ctypes.c_int, ctypes.c_int]
117
+ def glm_fg(coef, g, x, y, z, family, power, l2, fitint, n, p):
118
+ coef = np.ascontiguousarray(coef, dtype=np.float64)
119
+ g = np.ascontiguousarray(g, dtype=np.float64)
120
+ x = np.ascontiguousarray(x, dtype=np.float64)
121
+ y = np.ascontiguousarray(y, dtype=np.float64)
122
+ z = np.ascontiguousarray(z, dtype=np.float64)
123
+ return _lib.scm2cpp_glm_fg(coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), g.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), z.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), family, power, l2, fitint, n, p)
124
+
125
+ _lib.scm2cpp_glm.restype = ctypes.c_int
126
+ _lib.scm2cpp_glm.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_double, ctypes.c_double, ctypes.c_int, ctypes.c_double, ctypes.c_int, ctypes.c_int, ctypes.c_int]
127
+ def glm(x, y, coef, out, family, power, alpha, maxiter, tol, fitint, n, p):
128
+ x = np.ascontiguousarray(x, dtype=np.float64)
129
+ y = np.ascontiguousarray(y, dtype=np.float64)
130
+ coef = np.ascontiguousarray(coef, dtype=np.float64)
131
+ out = np.ascontiguousarray(out, dtype=np.float64)
132
+ return _lib.scm2cpp_glm(x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), coef.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), family, power, alpha, maxiter, tol, fitint, n, p)
133
+
114
134
  _lib.scm2cpp_lb_abs.restype = ctypes.c_double
115
135
  _lib.scm2cpp_lb_abs.argtypes = [ctypes.c_double]
116
136
  def lb_abs(a):
@@ -221,7 +241,7 @@ def lbfgs(kind, w, x, y, aux, work, out, m, maxiter, pgtol, ftol, maxls, ib, lbv
221
241
  x = np.ascontiguousarray(x, dtype=np.float64)
222
242
  y = np.ascontiguousarray(y, dtype=np.float64)
223
243
  aux = np.ascontiguousarray(aux, dtype=np.float64)
224
- assert aux.size == 3, "aux: expected 3 elements"
244
+ assert aux.size == 4, "aux: expected 4 elements"
225
245
  work = np.ascontiguousarray(work, dtype=np.float64)
226
246
  out = np.ascontiguousarray(out, dtype=np.float64)
227
247
  return _lib.scm2cpp_lbfgs(kind, w.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), aux.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), work.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), m, maxiter, pgtol, ftol, maxls, ib, lbv, nv, n, p, k)
@@ -234,7 +254,7 @@ def lbfgs_fg(kind, w, g, x, y, aux, work, n, p, k):
234
254
  x = np.ascontiguousarray(x, dtype=np.float64)
235
255
  y = np.ascontiguousarray(y, dtype=np.float64)
236
256
  aux = np.ascontiguousarray(aux, dtype=np.float64)
237
- assert aux.size == 3, "aux: expected 3 elements"
257
+ assert aux.size == 4, "aux: expected 4 elements"
238
258
  work = np.ascontiguousarray(work, dtype=np.float64)
239
259
  return _lib.scm2cpp_lbfgs_fg(kind, w.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), g.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), y.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), aux.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), work.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), n, p, k)
240
260