scm2cpp-lasso 0.13.2__py3-none-win_amd64.whl

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 (65) hide show
  1. scm2cpp_lasso/__init__.py +2808 -0
  2. scm2cpp_lasso/_classifiers.cp312-win_amd64.pyd +0 -0
  3. scm2cpp_lasso/_generated/__init__.py +0 -0
  4. scm2cpp_lasso/_generated/_loader.py +41 -0
  5. scm2cpp_lasso/_generated/_loader_accel_cublas.py +140 -0
  6. scm2cpp_lasso/_generated/_loader_classifiers.py +281 -0
  7. scm2cpp_lasso/_generated/_loader_derived_blas.py +29 -0
  8. scm2cpp_lasso/_generated/_loader_derived_cublas.py +29 -0
  9. scm2cpp_lasso/_generated/_loader_derived_loops.py +29 -0
  10. scm2cpp_lasso/_generated/_loader_gpu_cuda.py +294 -0
  11. scm2cpp_lasso/_generated/_loader_gramops_blas.py +496 -0
  12. scm2cpp_lasso/_generated/_loader_gramops_loops.py +496 -0
  13. scm2cpp_lasso/_generated/_loader_nmf_blas.py +29 -0
  14. scm2cpp_lasso/_generated/_loader_nmf_cublas.py +29 -0
  15. scm2cpp_lasso/_generated/_loader_nmf_loops.py +29 -0
  16. scm2cpp_lasso/_generated/accel_cublas/accel.cpp +20 -0
  17. scm2cpp_lasso/_generated/accel_cublas/accel.hpp +1023 -0
  18. scm2cpp_lasso/_generated/accel_cublas/accel_capi.cpp +64 -0
  19. scm2cpp_lasso/_generated/classifiers.cpp +34 -0
  20. scm2cpp_lasso/_generated/classifiers.hpp +2825 -0
  21. scm2cpp_lasso/_generated/classifiers_capi.cpp +106 -0
  22. scm2cpp_lasso/_generated/derived_blas/lasso_design.cpp +5 -0
  23. scm2cpp_lasso/_generated/derived_blas/lasso_design.hpp +153 -0
  24. scm2cpp_lasso/_generated/derived_blas/lasso_design_capi.cpp +19 -0
  25. scm2cpp_lasso/_generated/derived_cublas/lasso_design.cpp +5 -0
  26. scm2cpp_lasso/_generated/derived_cublas/lasso_design.hpp +155 -0
  27. scm2cpp_lasso/_generated/derived_cublas/lasso_design_capi.cpp +19 -0
  28. scm2cpp_lasso/_generated/derived_loops/lasso_design.cpp +5 -0
  29. scm2cpp_lasso/_generated/derived_loops/lasso_design.hpp +176 -0
  30. scm2cpp_lasso/_generated/derived_loops/lasso_design_capi.cpp +19 -0
  31. scm2cpp_lasso/_generated/gpu_cuda/gpu.cpp +35 -0
  32. scm2cpp_lasso/_generated/gpu_cuda/gpu.hpp +3715 -0
  33. scm2cpp_lasso/_generated/gpu_cuda/gpu_capi.cpp +289 -0
  34. scm2cpp_lasso/_generated/gramops_blas/gramops.cpp +57 -0
  35. scm2cpp_lasso/_generated/gramops_blas/gramops.hpp +3033 -0
  36. scm2cpp_lasso/_generated/gramops_blas/gramops_capi.cpp +175 -0
  37. scm2cpp_lasso/_generated/gramops_loops/gramops.cpp +57 -0
  38. scm2cpp_lasso/_generated/gramops_loops/gramops.hpp +3302 -0
  39. scm2cpp_lasso/_generated/gramops_loops/gramops_capi.cpp +175 -0
  40. scm2cpp_lasso/_generated/lasso_cov.cpp +7 -0
  41. scm2cpp_lasso/_generated/lasso_cov.hpp +152 -0
  42. scm2cpp_lasso/_generated/lasso_cov_capi.cpp +25 -0
  43. scm2cpp_lasso/_generated/nmf_blas/nmf_cd.cpp +5 -0
  44. scm2cpp_lasso/_generated/nmf_blas/nmf_cd.hpp +132 -0
  45. scm2cpp_lasso/_generated/nmf_blas/nmf_cd_capi.cpp +19 -0
  46. scm2cpp_lasso/_generated/nmf_cublas/nmf_cd.cpp +5 -0
  47. scm2cpp_lasso/_generated/nmf_cublas/nmf_cd.hpp +136 -0
  48. scm2cpp_lasso/_generated/nmf_cublas/nmf_cd_capi.cpp +19 -0
  49. scm2cpp_lasso/_generated/nmf_loops/nmf_cd.cpp +5 -0
  50. scm2cpp_lasso/_generated/nmf_loops/nmf_cd.hpp +167 -0
  51. scm2cpp_lasso/_generated/nmf_loops/nmf_cd_capi.cpp +19 -0
  52. scm2cpp_lasso/_generated/scm2cpp-blas.hpp +77 -0
  53. scm2cpp_lasso/_generated/scm2cpp-cublas.hpp +155 -0
  54. scm2cpp_lasso/_generated/scm2cpp-cuda.hpp +285 -0
  55. scm2cpp_lasso/_generated/scm2cpp.hpp +1627 -0
  56. scm2cpp_lasso/_gramops_loops.cp312-win_amd64.pyd +0 -0
  57. scm2cpp_lasso/_lasso_cov.cp312-win_amd64.pyd +0 -0
  58. scm2cpp_lasso/_lasso_derived_loops.cp312-win_amd64.pyd +0 -0
  59. scm2cpp_lasso/_libfind.py +149 -0
  60. scm2cpp_lasso/_nmf_loops.cp312-win_amd64.pyd +0 -0
  61. scm2cpp_lasso/batch_capi.cu +428 -0
  62. scm2cpp_lasso-0.13.2.dist-info/METADATA +920 -0
  63. scm2cpp_lasso-0.13.2.dist-info/RECORD +65 -0
  64. scm2cpp_lasso-0.13.2.dist-info/WHEEL +5 -0
  65. scm2cpp_lasso-0.13.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3033 @@
1
+
2
+ #ifndef GRAMOPS_HPP
3
+ #define GRAMOPS_HPP
4
+ #define SCM2CPP_MINIMAL
5
+ #include <cmath>
6
+ #include "scm2cpp-blas.hpp"
7
+ #include <array>
8
+ #include <math.h>
9
+ #include <vector>
10
+ #include "scm2cpp.hpp"
11
+
12
+ SCM2CPP_FN int
13
+ spd_inverse( scm2cpp::cspan<double> a, scm2cpp::span<double> inv, scm2cpp::span<double> l, scm2cpp::span<double> z, int p );
14
+ SCM2CPP_FN int
15
+ enet_gap( scm2cpp::cspan<double> w, scm2cpp::cspan<double> q, scm2cpp::cspan<double> qw, scm2cpp::span<double> xta, std::array<double,2> & out, double alpha, double ynorm2, int m );
16
+ SCM2CPP_FN int
17
+ enet_safe_rule( scm2cpp::span<double> w, scm2cpp::cspan<double> qm, scm2cpp::span<double> qw, scm2cpp::cspan<double> xta, scm2cpp::span<int> active, scm2cpp::span<int> excl, const std::array<double,2> & out, double alpha, int m );
18
+ SCM2CPP_FN int
19
+ enet_gram( scm2cpp::span<double> w, scm2cpp::cspan<double> qm, scm2cpp::cspan<double> q, scm2cpp::span<double> qw, scm2cpp::span<double> xta, scm2cpp::span<int> active, scm2cpp::span<int> excl, std::array<double,2> & out, double alpha, int maxiter, double tol, int m );
20
+ int
21
+ graphical_lasso( scm2cpp::cspan<double> emp, scm2cpp::span<double> cov, scm2cpp::span<double> prec, double alpha, int maxiter, double tol, double enettol, int p );
22
+ int
23
+ omp( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> path, int rec, int kmax, int n, int p );
24
+ SCM2CPP_FN double
25
+ logistic_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double l2, int multi, int fitint, int n, int p, int k );
26
+ int
27
+ logistic_lbfgs( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double c, int maxiter, double tol, int multi, int fitint, int n, int p, int k );
28
+ SCM2CPP_FN double
29
+ huber_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double epsilon, double alpha, int fitint, int n, int p );
30
+ int
31
+ huber( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double epsilon, double alpha, int maxiter, double tol, int fitint, int n, int p );
32
+ SCM2CPP_FN double
33
+ glm_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, int family, double power, double l2, int fitint, int n, int p );
34
+ int
35
+ glm( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, int family, double power, double alpha, int maxiter, double tol, int fitint, int n, int p );
36
+ SCM2CPP_FN double
37
+ lb_abs( double a );
38
+ SCM2CPP_FN double
39
+ lb_max( double a, double b );
40
+ SCM2CPP_FN double
41
+ lb_min( double a, double b );
42
+ SCM2CPP_FN int
43
+ lb_dcstep( std::array<double,8> & cs, double fp, double dp, double stpmin, double stpmax );
44
+ SCM2CPP_FN int
45
+ lb_search_start( std::array<double,16> & ls, double f, double g, double stp, double stpmin, double stpmax, double ftol );
46
+ SCM2CPP_FN int
47
+ lb_search_step( std::array<double,16> & ls, std::array<double,8> & cs, double f, double g, double ftol, double gtol, double xtol, double stpmin, double stpmax );
48
+ SCM2CPP_FN double
49
+ lb_dot( scm2cpp::cspan<double> a, scm2cpp::cspan<double> b, int nv );
50
+ SCM2CPP_FN double
51
+ lb_dot_row( scm2cpp::cspan<double> mem, int slot, scm2cpp::cspan<double> v, int nv );
52
+ SCM2CPP_FN double
53
+ lb_dot_rows( scm2cpp::cspan<double> a, int ra, scm2cpp::cspan<double> b, int rb, int nv );
54
+ SCM2CPP_FN double
55
+ lb_projgr( scm2cpp::cspan<double> g, scm2cpp::cspan<double> w, int ib, double lbv, int nv );
56
+ SCM2CPP_FN int
57
+ lb_hv( scm2cpp::span<double> q, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, double theta, int col, int head, int m, int nv );
58
+ SCM2CPP_FN double
59
+ lb_vbv( scm2cpp::cspan<double> v, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int nv );
60
+ SCM2CPP_FN int
61
+ lb_direction( scm2cpp::cspan<double> w, scm2cpp::cspan<double> g, scm2cpp::span<double> d, scm2cpp::span<double> q, scm2cpp::span<double> e, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int ib, double lbv, int nv );
62
+ int
63
+ lbfgs( int kind, scm2cpp::span<double> w, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, scm2cpp::span<double> out, int m, int maxiter, double pgtol, double ftol, int maxls, int ib, double lbv, int nv, int n, int p, int k );
64
+ SCM2CPP_FN double
65
+ lbfgs_fg( int kind, scm2cpp::cspan<double> w, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, int n, int p, int k );
66
+ SCM2CPP_FN int
67
+ gmm_mstep( scm2cpp::cspan<double> x, scm2cpp::cspan<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> dw, scm2cpp::span<double> cov, scm2cpp::span<double> l, scm2cpp::span<double> u, double reg, int norm, int n, int p, int kc );
68
+ SCM2CPP_FN double
69
+ gmm_estep( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::cspan<double> weights, scm2cpp::cspan<double> means, scm2cpp::cspan<double> prec, scm2cpp::span<double> wlp, scm2cpp::span<double> y, scm2cpp::span<double> u, scm2cpp::span<double> mu, int n, int p, int kc );
70
+ SCM2CPP_FN double
71
+ gmm_abs( double a );
72
+ int
73
+ gmm( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> labels, scm2cpp::span<double> out, int maxiter, double tol, double reg, int n, int p, int kc );
74
+ SCM2CPP_FN double
75
+ eig_hypot( double a, double b );
76
+ SCM2CPP_FN int
77
+ sym_eigen( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m );
78
+ SCM2CPP_FN double
79
+ eig_abs( double a );
80
+ SCM2CPP_FN int
81
+ eig_order( scm2cpp::cspan<double> ev, scm2cpp::span<int> ord, int m );
82
+ SCM2CPP_FN double
83
+ ica_tanh( double x );
84
+ SCM2CPP_FN int
85
+ ica_sym( scm2cpp::span<double> w, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::span<double> t, int m );
86
+ int
87
+ fastica( scm2cpp::cspan<double> x, scm2cpp::cspan<double> winit, scm2cpp::span<double> comps, scm2cpp::span<double> white, scm2cpp::span<double> unmix, scm2cpp::span<double> mean, int maxiter, double tol, int n, int p, int nc );
88
+ int
89
+ pca( scm2cpp::cspan<double> x, scm2cpp::span<double> comps, scm2cpp::span<double> ev, scm2cpp::span<double> sv, scm2cpp::span<double> mean, int n, int p );
90
+ SCM2CPP_FN int
91
+ ard_pinvh( scm2cpp::span<double> a, scm2cpp::span<double> s, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int k );
92
+ SCM2CPP_FN int
93
+ ard_sigma_coef( scm2cpp::cspan<double> xy, scm2cpp::cspan<int> idx, scm2cpp::cspan<double> lam, scm2cpp::span<double> coef, scm2cpp::span<double> sigma, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::cspan<double> gk, double alpha, int k );
94
+ int
95
+ ard( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> sigma, scm2cpp::span<double> lam, scm2cpp::span<double> out, int maxiter, double tol, double alpha1, double alpha2, double lambda1, double lambda2, double thresh, int hoist, int n, int p );
96
+ int
97
+ f_regression( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> r, scm2cpp::span<double> f, int center, int n, int p, int q );
98
+ int
99
+ f_classif( scm2cpp::cspan<double> x, scm2cpp::cspan<int> lab, scm2cpp::span<double> f, int n, int p, int k );
100
+ SCM2CPP_FN double
101
+ min_pos( scm2cpp::cspan<double> v, int m );
102
+ SCM2CPP_FN double
103
+ round_even( double y );
104
+ SCM2CPP_FN int
105
+ cholesky_delete( scm2cpp::span<double> l, int go, int n, int k );
106
+ SCM2CPP_FN int
107
+ swap_rc( scm2cpp::span<double> g, int a, int b, int p );
108
+ int
109
+ lars( scm2cpp::span<double> g, scm2cpp::cspan<double> cov, scm2cpp::span<double> coef, scm2cpp::span<double> path, scm2cpp::span<double> alphas, int rec, double nsamples, double alphamin, int method, int maxiter, double eps, int p );
110
+ SCM2CPP_FN int
111
+ rfe_chol( scm2cpp::cspan<double> g, scm2cpp::cspan<int> idx, scm2cpp::span<double> l, double alpha, int k, int p );
112
+ SCM2CPP_FN int
113
+ rfe_solve( scm2cpp::cspan<double> c, scm2cpp::cspan<int> idx, scm2cpp::span<double> w, scm2cpp::cspan<double> l, int k, int p );
114
+ int
115
+ rfe( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<int> support, scm2cpp::span<int> ranking, double alpha, int nsel, int step, int n, int p );
116
+ SCM2CPP_FN int
117
+ gram_xx( scm2cpp::cspan<double> x, scm2cpp::span<double> g, int n, int p );
118
+ SCM2CPP_FN int
119
+ gram_xy( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> c, int n, int p, int q );
120
+
121
+
122
+
123
+ SCM2CPP_FN inline int
124
+ spd_inverse( scm2cpp::cspan<double> a, scm2cpp::span<double> inv, scm2cpp::span<double> l, scm2cpp::span<double> z, int p )
125
+ { for( int j = 0 ; !(j == p) ; j = (j+1) ) {
126
+ double s = a[((j*p)+j)];
127
+ for( int k = 0 ; !(k == j) ; k = (k+1) ) {
128
+ s = (s-(l[((j*p)+k)]*l[((j*p)+k)])) ;
129
+ } ;
130
+ l[ ((j*p)+j) ] = sqrt(s) ;
131
+ for( int i = (j+1) ; !(i >= p) ; i = (i+1) ) {
132
+ double t = a[((i*p)+j)];
133
+ for( int k = 0 ; !(k == j) ; k = (k+1) ) {
134
+ t = (t-(l[((i*p)+k)]*l[((j*p)+k)])) ;
135
+ } ;
136
+ l[ ((i*p)+j) ] = (t/l[((j*p)+j)]) ;
137
+ ;
138
+ } ;
139
+ ;
140
+ } ;
141
+ for( int c = 0 ; !(c == p) ; c = (c+1) ) {
142
+ for( int i = 0 ; !(i == p) ; i = (i+1) ) {
143
+ double t = ( ( i == c ) ? (1.0) : (0.0) );
144
+ for( int k = 0 ; !(k == i) ; k = (k+1) ) {
145
+ t = (t-(l[((i*p)+k)]*z[k])) ;
146
+ } ;
147
+ z[ i ] = (t/l[((i*p)+i)]) ;
148
+ ;
149
+ } ;
150
+ for( int ii = 0 ; !(ii == p) ; ii = (ii+1) ) {
151
+ int i = ((p-1)-ii);
152
+ double t = z[i];
153
+ for( int k = (i+1) ; !(k >= p) ; k = (k+1) ) {
154
+ t = (t-(l[((k*p)+i)]*inv[((k*p)+c)])) ;
155
+ } ;
156
+ inv[ ((i*p)+c) ] = (t/l[((i*p)+i)]) ;
157
+ ;
158
+ ;
159
+ } ;
160
+ } ;
161
+ return 0 ;
162
+ }
163
+
164
+
165
+ SCM2CPP_FN inline int
166
+ enet_gap( scm2cpp::cspan<double> w, scm2cpp::cspan<double> q, scm2cpp::cspan<double> qw, scm2cpp::span<double> xta, std::array<double,2> & out, double alpha, double ynorm2, int m )
167
+ { double qdotw = 0.0;
168
+ double wqw = 0.0;
169
+ double l1 = 0.0;
170
+ double dn = 0.0;
171
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
172
+ double wj = w[j];
173
+ qdotw = (qdotw+(wj*q[j])) ;
174
+ wqw = (wqw+(wj*qw[j])) ;
175
+ l1 = (l1+( ( wj < 0.0 ) ? ((0.0-wj)) : (wj) )) ;
176
+ double x = (q[j]-qw[j]);
177
+ xta[ j ] = x ;
178
+ double ax = ( ( x < 0.0 ) ? ((0.0-x)) : (x) );
179
+ if( ax > dn ) {
180
+ dn = ax ;
181
+ } else {
182
+ 0 ;
183
+ } ;
184
+ ;
185
+ ;
186
+ ;
187
+ } ;
188
+ double rnorm2 = ((ynorm2+wqw)-(2.0*qdotw));
189
+ double ry = (ynorm2-qdotw);
190
+ double scale = ( ( dn > alpha ) ? ((alpha/dn)) : (1.0) );
191
+ out[ 0 ] = (((0.5*rnorm2)+(alpha*l1))-((-0.5*((scale*scale)*rnorm2))+(scale*ry))) ;
192
+ out[ 1 ] = dn ;
193
+ ;
194
+ ;
195
+ ;
196
+ return 0 ;
197
+ }
198
+
199
+
200
+ SCM2CPP_FN inline int
201
+ enet_safe_rule( scm2cpp::span<double> w, scm2cpp::cspan<double> qm, scm2cpp::span<double> qw, scm2cpp::cspan<double> xta, scm2cpp::span<int> active, scm2cpp::span<int> excl, const std::array<double,2> & out, double alpha, int m )
202
+ {
203
+ struct let17063 {
204
+ let17063() {}
205
+ double operator()( double g )
206
+ {
207
+ if( g < 0.0 ) {
208
+ return (0.0-g) ;
209
+ }
210
+ else {
211
+ return g ;
212
+ }
213
+ }
214
+ } ;
215
+ double radius = (sqrt((2.0*let17063()(out[0])))/alpha);
216
+ double dn = out[1];
217
+ int nact = 0;
218
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
219
+ if( excl[j] == 0 ) {
220
+ double xjt = (xta[j]/( ( alpha > dn ) ? (alpha) : (dn) ));
221
+ double dj = ((1.0-( ( xjt < 0.0 ) ? ((0.0-xjt)) : (xjt) ))/sqrt(qm[((j*m)+j)]));
222
+ if( dj <= radius ) {
223
+ active[ nact ] = j ;
224
+ nact = (nact+1) ;
225
+ } else {
226
+ if( !(w[j] == 0.0) ) {
227
+ double wj = w[j];
228
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
229
+ qw[ r ] = (qw[r]-(wj*qm[((j*m)+r)])) ;
230
+ } ;
231
+ w[ j ] = 0.0 ;
232
+ ;
233
+ } else {
234
+ 0 ;
235
+ } ;
236
+ excl[ j ] = 1 ;
237
+ } ;
238
+ ;
239
+ ;
240
+ } else {
241
+ 0 ;
242
+ } ;
243
+ } ;
244
+ return nact ;
245
+ }
246
+
247
+
248
+ SCM2CPP_FN inline int
249
+ enet_gram( scm2cpp::span<double> w, scm2cpp::cspan<double> qm, scm2cpp::cspan<double> q, scm2cpp::span<double> qw, scm2cpp::span<double> xta, scm2cpp::span<int> active, scm2cpp::span<int> excl, std::array<double,2> & out, double alpha, int maxiter, double tol, int m )
250
+ { double ynorm2 = 0.0;
251
+ double dwtol = tol;
252
+ int nact = 0;
253
+ int done = 0;
254
+ int iter = 0;
255
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
256
+ ynorm2 = (ynorm2+(q[j]*q[j])) ;
257
+ excl[ j ] = 0 ;
258
+ } ;
259
+ scm2cpp::blas_gemv(qw, qm, w, 1.0, 0.0, 0, m, m) ;
260
+ double gtol = (tol*ynorm2);
261
+ enet_gap(w,q,qw,xta,out,alpha,ynorm2,m) ;
262
+ if( (out[0] >= 0.0 && out[0] <= gtol) ) {
263
+ done = 1 ;
264
+ } else {
265
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
266
+ if( qm[((j*m)+j)] == 0.0 ) {
267
+ w[ j ] = 0.0 ;
268
+ excl[ j ] = 1 ;
269
+ } else {
270
+ 0 ;
271
+ } ;
272
+ } ;
273
+ nact = enet_safe_rule(w,qm,qw,xta,active,excl,out,alpha,m) ;
274
+ } ;
275
+ for( ; !((done == 1 || iter >= maxiter)) ; ) {
276
+ double wmax = 0.0;
277
+ double dwmax = 0.0;
278
+ for( int f = 0 ; !(f == nact) ; f = (f+1) ) {
279
+ int j = active[f];
280
+ double qjj = qm[((j*m)+j)];
281
+ if( !(qjj == 0.0) ) {
282
+ double wj = w[j];
283
+ double tmp = ((q[j]-qw[j])+(wj*qjj));
284
+ double mag = (( ( tmp < 0.0 ) ? ((0.0-tmp)) : (tmp) )-alpha);
285
+ double wn = ( ( mag > 0.0 ) ? ((( ( tmp < 0.0 ) ? ((0.0-mag)) : (mag) )/qjj)) : (0.0) );
286
+ w[ j ] = wn ;
287
+ if( !(wn == wj) ) {
288
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
289
+ qw[ r ] = (qw[r]+((wn-wj)*qm[((j*m)+r)])) ;
290
+ } ;
291
+ } else {
292
+ 0 ;
293
+ } ;
294
+ double dw = ( ( wn < wj ) ? ((wj-wn)) : ((wn-wj)) );
295
+ double aw = ( ( wn < 0.0 ) ? ((0.0-wn)) : (wn) );
296
+ if( dw > dwmax ) {
297
+ dwmax = dw ;
298
+ } else {
299
+ 0 ;
300
+ } ;
301
+ if( aw > wmax ) {
302
+ wmax = aw ;
303
+ } else {
304
+ 0 ;
305
+ } ;
306
+ ;
307
+ ;
308
+ ;
309
+ ;
310
+ ;
311
+ } else {
312
+ 0 ;
313
+ } ;
314
+ ;
315
+ ;
316
+ } ;
317
+ if( (wmax == 0.0 || (dwmax/wmax) <= dwtol || iter == (maxiter-1)) ) {
318
+ enet_gap(w,q,qw,xta,out,alpha,ynorm2,m) ;
319
+ if( out[0] <= gtol ) {
320
+ done = 1 ;
321
+ } else {
322
+ nact = enet_safe_rule(w,qm,qw,xta,active,excl,out,alpha,m) ;
323
+ } ;
324
+ } else {
325
+ 0 ;
326
+ } ;
327
+ iter = (iter+1) ;
328
+ ;
329
+ } ;
330
+ ;
331
+ return iter ;
332
+ }
333
+
334
+
335
+ inline int
336
+ graphical_lasso( scm2cpp::cspan<double> emp, scm2cpp::span<double> cov, scm2cpp::span<double> prec, double alpha, int maxiter, double tol, double enettol, int p )
337
+ { int m = (p-1);
338
+ std::vector<double> sub((m*m),0.0);
339
+ std::vector<double> row(m,0.0);
340
+ std::vector<double> b(m,0.0);
341
+ std::vector<double> bnew(m,0.0);
342
+ std::vector<double> qw(m,0.0);
343
+ std::vector<double> xta(m,0.0);
344
+ std::vector<int> active(m,0);
345
+ std::vector<int> excl(m,0);
346
+ std::array<double,2> out = scm2cpp::filled_array<double,2>(0.0);
347
+ std::vector<double> l((p*p),0.0);
348
+ std::vector<double> z(p,0.0);
349
+ int done = 0;
350
+ int it = 0;
351
+ int innermax = ( ( maxiter > 20 ) ? (maxiter) : (20) );
352
+ for( int i = 0 ; !(i == p) ; i = (i+1) ) {
353
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
354
+ cov[ ((i*p)+j) ] = ( ( i == j ) ? (emp[((i*p)+j)]) : ((0.95*emp[((i*p)+j)])) ) ;
355
+ } ;
356
+ } ;
357
+ spd_inverse(cov,prec,l,z,p) ;
358
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
359
+ for( int idx = 0 ; !(idx == p) ; idx = (idx+1) ) {
360
+ if( idx > 0 ) {
361
+ int di = (idx-1);
362
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
363
+ int o = ( ( s < idx ) ? (s) : ((s+1)) );
364
+ sub[ ((di*m)+s) ] = cov[((di*p)+o)] ;
365
+ sub[ ((s*m)+di) ] = cov[((o*p)+di)] ;
366
+ ;
367
+ } ;
368
+ ;
369
+ } else {
370
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
371
+ for( int t = 0 ; !(t == m) ; t = (t+1) ) {
372
+ sub[ ((s*m)+t) ] = cov[(((s+1)*p)+(t+1))] ;
373
+ } ;
374
+ } ;
375
+ } ;
376
+ double pii = prec[((idx*p)+idx)];
377
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
378
+ int o = ( ( s < idx ) ? (s) : ((s+1)) );
379
+ row[ s ] = emp[((idx*p)+o)] ;
380
+ b[ s ] = (0.0-(prec[((o*p)+idx)]/(pii+(1000.0*2.220446049250313e-16)))) ;
381
+ ;
382
+ } ;
383
+ ;
384
+ enet_gram(b,sub,row,qw,xta,active,excl,out,alpha,innermax,enettol,m) ;
385
+ double acc = 0.0;
386
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
387
+ int o = ( ( s < idx ) ? (s) : ((s+1)) );
388
+ acc = (acc+(cov[((o*p)+idx)]*b[s])) ;
389
+ ;
390
+ } ;
391
+ double pnew = (1.0/(cov[((idx*p)+idx)]-acc));
392
+ prec[ ((idx*p)+idx) ] = pnew ;
393
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
394
+ int o = ( ( s < idx ) ? (s) : ((s+1)) );
395
+ prec[ ((o*p)+idx) ] = (0.0-(pnew*b[s])) ;
396
+ prec[ ((idx*p)+o) ] = (0.0-(pnew*b[s])) ;
397
+ ;
398
+ } ;
399
+ ;
400
+ ;
401
+ scm2cpp::blas_gemv(bnew, sub, b, 1.0, 0.0, 0, m, m) ;
402
+ for( int s = 0 ; !(s == m) ; s = (s+1) ) {
403
+ int o = ( ( s < idx ) ? (s) : ((s+1)) );
404
+ cov[ ((idx*p)+o) ] = bnew[s] ;
405
+ cov[ ((o*p)+idx) ] = bnew[s] ;
406
+ ;
407
+ } ;
408
+ } ;
409
+ double tr = 0.0;
410
+ double offl1 = 0.0;
411
+ for( int i = 0 ; !(i == p) ; i = (i+1) ) {
412
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
413
+ double t = prec[((i*p)+j)];
414
+ tr = (tr+(emp[((i*p)+j)]*t)) ;
415
+ if( !(i == j) ) {
416
+ offl1 = (offl1+( ( t < 0.0 ) ? ((0.0-t)) : (t) )) ;
417
+ } else {
418
+ 0 ;
419
+ } ;
420
+ ;
421
+ } ;
422
+ } ;
423
+ double gap = ((tr-(1.0*p))+(alpha*offl1));
424
+ it = (it+1) ;
425
+ if( ( ( gap < 0.0 ) ? ((0.0-gap)) : (gap) ) < tol ) {
426
+ done = 1 ;
427
+ } else {
428
+ 0 ;
429
+ } ;
430
+ ;
431
+ ;
432
+ } ;
433
+ return it ;
434
+ }
435
+
436
+
437
+ inline int
438
+ omp( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> path, int rec, int kmax, int n, int p )
439
+ { std::vector<double> g((p*p),0.0);
440
+ std::vector<double> xy(p,0.0);
441
+ std::vector<double> alpha(p,0.0);
442
+ std::vector<double> beta(p,0.0);
443
+ std::vector<int> index(p,0);
444
+ std::vector<double> l((kmax*kmax),0.0);
445
+ std::vector<double> gamma(kmax,0.0);
446
+ std::vector<double> z(kmax,0.0);
447
+ double eps = 2.220446049250313e-16;
448
+ int na = 0;
449
+ int done = 0;
450
+ scm2cpp::blas_syrk(g, x, 1.0, 0.0, 1, p, n) ;
451
+ scm2cpp::blas_gemv(xy, x, y, 1.0, 0.0, 1, p, n) ;
452
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
453
+ index[ j ] = j ;
454
+ alpha[ j ] = xy[j] ;
455
+ } ;
456
+ for( ; !(done == 1) ; ) {
457
+ int lam = 0;
458
+ double best = -1.0;
459
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
460
+ double a = alpha[j];
461
+ double aa = ( ( a < 0.0 ) ? ((0.0-a)) : (a) );
462
+ if( aa > best ) {
463
+ best = aa ;
464
+ lam = j ;
465
+ } else {
466
+ 0 ;
467
+ } ;
468
+ ;
469
+ ;
470
+ } ;
471
+ if( (lam < na || (alpha[lam]*alpha[lam]) < eps) ) {
472
+ done = 1 ;
473
+ } else {
474
+ if( na > 0 ) {
475
+ double v = 0.0;
476
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
477
+ double t = g[((lam*p)+i)];
478
+ for( int s = 0 ; !(s == i) ; s = (s+1) ) {
479
+ t = (t-(l[((i*kmax)+s)]*l[((na*kmax)+s)])) ;
480
+ } ;
481
+ double li = (t/l[((i*kmax)+i)]);
482
+ l[ ((na*kmax)+i) ] = li ;
483
+ v = (v+(li*li)) ;
484
+ ;
485
+ ;
486
+ } ;
487
+ double lkk = (g[((lam*p)+lam)]-v);
488
+ if( lkk <= eps ) {
489
+ done = 1 ;
490
+ } else {
491
+ l[ ((na*kmax)+na) ] = sqrt(lkk) ;
492
+ } ;
493
+ ;
494
+ ;
495
+ } else {
496
+ l[ 0 ] = sqrt(g[((lam*p)+lam)]) ;
497
+ } ;
498
+ if( done == 0 ) {
499
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
500
+ double grow = g[((na*p)+j)];
501
+ g[ ((na*p)+j) ] = g[((lam*p)+j)] ;
502
+ g[ ((lam*p)+j) ] = grow ;
503
+ ;
504
+ } ;
505
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
506
+ double gcol = g[((j*p)+na)];
507
+ g[ ((j*p)+na) ] = g[((j*p)+lam)] ;
508
+ g[ ((j*p)+lam) ] = gcol ;
509
+ ;
510
+ } ;
511
+ int itmp = index[na];
512
+ index[ na ] = index[lam] ;
513
+ index[ lam ] = itmp ;
514
+ ;
515
+ double xtmp = xy[na];
516
+ xy[ na ] = xy[lam] ;
517
+ xy[ lam ] = xtmp ;
518
+ ;
519
+ na = (na+1) ;
520
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
521
+ double t = xy[i];
522
+ for( int s = 0 ; !(s == i) ; s = (s+1) ) {
523
+ t = (t-(l[((i*kmax)+s)]*z[s])) ;
524
+ } ;
525
+ z[ i ] = (t/l[((i*kmax)+i)]) ;
526
+ ;
527
+ } ;
528
+ for( int ii = 0 ; !(ii == na) ; ii = (ii+1) ) {
529
+ int i = ((na-1)-ii);
530
+ double t = z[i];
531
+ for( int s = (i+1) ; !(s >= na) ; s = (s+1) ) {
532
+ t = (t-(l[((s*kmax)+i)]*gamma[s])) ;
533
+ } ;
534
+ gamma[ i ] = (t/l[((i*kmax)+i)]) ;
535
+ ;
536
+ ;
537
+ } ;
538
+ if( rec == 1 ) {
539
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
540
+ path[ (((na-1)*p)+j) ] = 0.0 ;
541
+ } ;
542
+ for( int s = 0 ; !(s == na) ; s = (s+1) ) {
543
+ path[ (((na-1)*p)+index[s]) ] = gamma[s] ;
544
+ } ;
545
+ } else {
546
+ 0 ;
547
+ } ;
548
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
549
+ double acc = 0.0;
550
+ for( int s = 0 ; !(s == na) ; s = (s+1) ) {
551
+ acc = (acc+(g[((j*p)+s)]*gamma[s])) ;
552
+ } ;
553
+ beta[ j ] = acc ;
554
+ alpha[ j ] = (xy[j]-acc) ;
555
+ ;
556
+ } ;
557
+ if( na == kmax ) {
558
+ done = 1 ;
559
+ } else {
560
+ 0 ;
561
+ } ;
562
+ } else {
563
+ 0 ;
564
+ } ;
565
+ } ;
566
+ ;
567
+ } ;
568
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
569
+ coef[ j ] = 0.0 ;
570
+ } ;
571
+ for( int s = 0 ; !(s == na) ; s = (s+1) ) {
572
+ coef[ index[s] ] = gamma[s] ;
573
+ } ;
574
+ return na ;
575
+ }
576
+
577
+
578
+ SCM2CPP_FN inline double
579
+ logistic_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double l2, int multi, int fitint, int n, int p, int k )
580
+ { double loss = 0.0;
581
+ double pen = 0.0;
582
+ scm2cpp::blas_gemm(z, x, coef, 1.0, 0.0, 0, 1, n, k, p) ;
583
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
584
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
585
+ z[ ((i*k)+c) ] = (z[((i*k)+c)]+coef[((k*p)+c)]) ;
586
+ } ;
587
+ } ;
588
+ if( multi == 0 ) {
589
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
590
+ double zi = z[i];
591
+ double yi = y[i];
592
+ if( zi <= -2.0 ) {
593
+ double e1 = exp(zi);
594
+ if( zi <= -37.0 ) {
595
+ loss = (loss+(e1-(yi*zi))) ;
596
+ z[ i ] = (e1-yi) ;
597
+ } else {
598
+ loss = (loss+(log((1.0+e1))-(yi*zi))) ;
599
+ z[ i ] = ((((1.0-yi)*e1)-yi)/(1.0+e1)) ;
600
+ } ;
601
+ ;
602
+ } else {
603
+ double e2 = exp((0.0-zi));
604
+ loss = (loss+(( ( zi <= 18.0 ) ? (log((1.0+e2))) : (e2) )+((1.0-yi)*zi))) ;
605
+ z[ i ] = (((1.0-yi)-(yi*e2))/(1.0+e2)) ;
606
+ ;
607
+ } ;
608
+ ;
609
+ } ;
610
+ } else {
611
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
612
+ double zmax = z[(i*k)];
613
+ double se = 0.0;
614
+ double yc = y[i];
615
+ for( int c = 1 ; !(c == k) ; c = (c+1) ) {
616
+ if( z[((i*k)+c)] > zmax ) {
617
+ zmax = z[((i*k)+c)] ;
618
+ } else {
619
+ 0 ;
620
+ } ;
621
+ } ;
622
+ loss = (loss-z[((i*k)+int(yc))]) ;
623
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
624
+ double ec = exp((z[((i*k)+c)]-zmax));
625
+ z[ ((i*k)+c) ] = ec ;
626
+ se = (se+ec) ;
627
+ ;
628
+ } ;
629
+ loss = (loss+(zmax+log(se))) ;
630
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
631
+ z[ ((i*k)+c) ] = (z[((i*k)+c)]/se) ;
632
+ } ;
633
+ int iy = ((i*k)+int(yc));
634
+ z[ iy ] = (z[iy]-1.0) ;
635
+ ;
636
+ ;
637
+ } ;
638
+ } ;
639
+ scm2cpp::blas_gemm(g, z, x, 1.0, 0.0, 1, 0, k, p, n) ;
640
+ for( int t = 0 ; !(t == (k*p)) ; t = (t+1) ) {
641
+ double wt = coef[t];
642
+ pen = (pen+(wt*wt)) ;
643
+ g[ t ] = ((g[t]/double(n))+(l2*wt)) ;
644
+ ;
645
+ } ;
646
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
647
+ double acc = 0.0;
648
+ if( fitint == 1 ) {
649
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
650
+ acc = (acc+z[((i*k)+c)]) ;
651
+ } ;
652
+ } else {
653
+ 0 ;
654
+ } ;
655
+ g[ ((k*p)+c) ] = (acc/double(n)) ;
656
+ ;
657
+ } ;
658
+ return ((loss/double(n))+(0.5*(l2*pen))) ;
659
+ }
660
+
661
+
662
+ inline int
663
+ logistic_lbfgs( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double c, int maxiter, double tol, int multi, int fitint, int n, int p, int k )
664
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
665
+ std::vector<double> work((n*k),0.0);
666
+ aux[ 0 ] = (1.0/(c*double(n))) ;
667
+ aux[ 1 ] = ( ( multi == 1 ) ? (1.0) : (0.0) ) ;
668
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
669
+ return lbfgs(0,coef,x,y,aux,work,out,10,maxiter,tol,(64.0*2.220446049250313e-16),50,-1,0.0,(k*(p+1)),n,p,k) ;
670
+ }
671
+
672
+
673
+ SCM2CPP_FN inline double
674
+ huber_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double epsilon, double alpha, int fitint, int n, int p )
675
+ { double b = coef[p];
676
+ double sigma = coef[(p+1)];
677
+ int nout = 0;
678
+ double outsum = 0.0;
679
+ double sq = 0.0;
680
+ double csum = 0.0;
681
+ double ww = 0.0;
682
+ scm2cpp::blas_gemv(z, x, coef, 1.0, 0.0, 0, n, p) ;
683
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
684
+ double r = ((y[i]-z[i])-b);
685
+ double a = lb_abs(r);
686
+ if( a > (epsilon*sigma) ) {
687
+ nout = (nout+1) ;
688
+ outsum = (outsum+a) ;
689
+ z[ i ] = (-2.0*(epsilon*( ( r < 0.0 ) ? (-1.0) : (1.0) ))) ;
690
+ } else {
691
+ sq = (sq+(r*r)) ;
692
+ z[ i ] = ((-2.0*r)/sigma) ;
693
+ } ;
694
+ csum = (csum+z[i]) ;
695
+ ;
696
+ ;
697
+ } ;
698
+ scm2cpp::blas_gemv(g, x, z, 1.0, 0.0, 1, p, n) ;
699
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
700
+ double wj = coef[j];
701
+ ww = (ww+(wj*wj)) ;
702
+ g[ j ] = (g[j]+(2.0*(alpha*wj))) ;
703
+ ;
704
+ } ;
705
+ g[ p ] = ( ( fitint == 1 ) ? (csum) : (0.0) ) ;
706
+ double sqloss = (sq/sigma);
707
+ double eps2 = (epsilon*epsilon);
708
+ g[ (p+1) ] = ((double(n)-(double(nout)*eps2))-(sqloss/sigma)) ;
709
+ return ((((double(n)*sigma)+sqloss)+((2.0*(epsilon*outsum))-(sigma*(double(nout)*eps2))))+(alpha*ww)) ;
710
+ }
711
+
712
+
713
+ inline int
714
+ huber( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double epsilon, double alpha, int maxiter, double tol, int fitint, int n, int p )
715
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
716
+ std::vector<double> work(n,0.0);
717
+ aux[ 0 ] = epsilon ;
718
+ aux[ 1 ] = alpha ;
719
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
720
+ return lbfgs(1,coef,x,y,aux,work,out,10,maxiter,tol,(10000000.0*2.220446049250313e-16),20,(p+1),(10.0*2.220446049250313e-16),(p+2),n,p,1) ;
721
+ }
722
+
723
+
724
+ SCM2CPP_FN inline double
725
+ glm_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, int family, double power, double l2, int fitint, int n, int p )
726
+ { double loss = 0.0;
727
+ double pen = 0.0;
728
+ double b = coef[p];
729
+ scm2cpp::blas_gemv(z, x, coef, 1.0, 0.0, 0, n, p) ;
730
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
731
+ double zi = (z[i]+b);
732
+ double yi = y[i];
733
+ if( (family == 0 || (family == 2 && power == 1.0)) ) {
734
+ double e = exp(zi);
735
+ loss = (loss+(e-(yi*zi))) ;
736
+ z[ i ] = (e-yi) ;
737
+ ;
738
+ } else {
739
+ if( (family == 1 || (family == 2 && power == 2.0)) ) {
740
+ double e2 = exp((0.0-zi));
741
+ loss = (loss+(zi+(yi*e2))) ;
742
+ z[ i ] = (1.0-(yi*e2)) ;
743
+ ;
744
+ } else {
745
+ if( family == 3 ) {
746
+ double r = (zi-yi);
747
+ loss = (loss+(0.5*(r*r))) ;
748
+ z[ i ] = r ;
749
+ ;
750
+ } else {
751
+ if( power == 0.0 ) {
752
+ double e3 = exp(zi);
753
+ loss = (loss+(0.5*((e3-yi)*(e3-yi)))) ;
754
+ z[ i ] = (e3*(e3-yi)) ;
755
+ ;
756
+ } else {
757
+ double e1 = exp(((1.0-power)*zi));
758
+ double e4 = exp(((2.0-power)*zi));
759
+ loss = (loss+((e4/(2.0-power))-((yi*e1)/(1.0-power)))) ;
760
+ z[ i ] = (e4-(yi*e1)) ;
761
+ ;
762
+ } ;
763
+ } ;
764
+ } ;
765
+ } ;
766
+ ;
767
+ } ;
768
+ scm2cpp::blas_gemv(g, x, z, 1.0, 0.0, 1, p, n) ;
769
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
770
+ double wj = coef[j];
771
+ pen = (pen+(wj*wj)) ;
772
+ g[ j ] = ((g[j]/double(n))+(l2*wj)) ;
773
+ ;
774
+ } ;
775
+ double acc = 0.0;
776
+ if( fitint == 1 ) {
777
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
778
+ acc = (acc+z[i]) ;
779
+ } ;
780
+ } else {
781
+ 0 ;
782
+ } ;
783
+ g[ p ] = (acc/double(n)) ;
784
+ ;
785
+ return ((loss/double(n))+(0.5*(l2*pen))) ;
786
+ }
787
+
788
+
789
+ inline int
790
+ glm( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, int family, double power, double alpha, int maxiter, double tol, int fitint, int n, int p )
791
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
792
+ std::vector<double> work(n,0.0);
793
+ double ym = 0.0;
794
+ aux[ 0 ] = alpha ;
795
+ aux[ 1 ] = double(family) ;
796
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
797
+ aux[ 3 ] = power ;
798
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
799
+ coef[ j ] = 0.0 ;
800
+ } ;
801
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
802
+ ym = (ym+y[i]) ;
803
+ } ;
804
+ ym = (ym/double(n)) ;
805
+ coef[ p ] = ( ( fitint == 1 ) ? (( ( family == 3 ) ? (ym) : (log(ym)) )) : (0.0) ) ;
806
+ return lbfgs(2,coef,x,y,aux,work,out,10,maxiter,tol,(64.0*2.220446049250313e-16),50,-1,0.0,(p+1),n,p,1) ;
807
+ }
808
+
809
+
810
+ SCM2CPP_FN inline double
811
+ lb_abs( double a )
812
+ {
813
+ if( a < 0.0 ) {
814
+ return (0.0-a) ;
815
+ }
816
+ else {
817
+ return a ;
818
+ }
819
+ }
820
+
821
+
822
+ SCM2CPP_FN inline double
823
+ lb_max( double a, double b )
824
+ {
825
+ if( a > b ) {
826
+ return a ;
827
+ }
828
+ else {
829
+ return b ;
830
+ }
831
+ }
832
+
833
+
834
+ SCM2CPP_FN inline double
835
+ lb_min( double a, double b )
836
+ {
837
+ if( a < b ) {
838
+ return a ;
839
+ }
840
+ else {
841
+ return b ;
842
+ }
843
+ }
844
+
845
+
846
+ SCM2CPP_FN inline int
847
+ lb_dcstep( std::array<double,8> & cs, double fp, double dp, double stpmin, double stpmax )
848
+ { double stx = cs[0];
849
+ double fx = cs[1];
850
+ double dx = cs[2];
851
+ double sty = cs[3];
852
+ double fy = cs[4];
853
+ double dy = cs[5];
854
+ double stp = cs[6];
855
+ double brackt = cs[7];
856
+ double stpf = 0.0;
857
+ double sgnd = (dp*(dx/lb_abs(dx)));
858
+ if( fp > fx ) {
859
+ double th1 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
860
+ double s1 = lb_max(lb_abs(th1),lb_max(lb_abs(dx),lb_abs(dp)));
861
+ double ga1 = (s1*sqrt((((th1/s1)*(th1/s1))-((dx/s1)*(dp/s1)))));
862
+ double gm1 = ( ( stp < stx ) ? ((0.0-ga1)) : (ga1) );
863
+ double r1 = (((gm1-dx)+th1)/(((gm1-dx)+gm1)+dp));
864
+ double stpc1 = (stx+(r1*(stp-stx)));
865
+ double stpq1 = (stx+(((dx/(((fx-fp)/(stp-stx))+dx))/2.0)*(stp-stx)));
866
+ if( lb_abs(double((stpc1-stx))) < lb_abs(double((stpq1-stx))) ) {
867
+ stpf = stpc1 ;
868
+ } else {
869
+ stpf = (stpc1+((stpq1-stpc1)/2.0)) ;
870
+ } ;
871
+ brackt = 1.0 ;
872
+ ;
873
+ ;
874
+ ;
875
+ ;
876
+ ;
877
+ ;
878
+ 0 ;
879
+ } else {
880
+ if( sgnd < 0.0 ) {
881
+ double th2 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
882
+ double s2 = lb_max(lb_abs(th2),lb_max(lb_abs(dx),lb_abs(dp)));
883
+ double ga2 = (s2*sqrt((((th2/s2)*(th2/s2))-((dx/s2)*(dp/s2)))));
884
+ double gm2 = ( ( stp > stx ) ? ((0.0-ga2)) : (ga2) );
885
+ double r2 = (((gm2-dp)+th2)/(((gm2-dp)+gm2)+dx));
886
+ double stpc2 = (stp+(r2*(stx-stp)));
887
+ double stpq2 = (stp+((dp/(dp-dx))*(stx-stp)));
888
+ if( lb_abs(double((stpc2-stp))) > lb_abs(double((stpq2-stp))) ) {
889
+ stpf = stpc2 ;
890
+ } else {
891
+ stpf = stpq2 ;
892
+ } ;
893
+ brackt = 1.0 ;
894
+ ;
895
+ ;
896
+ ;
897
+ ;
898
+ ;
899
+ ;
900
+ 0 ;
901
+ } else {
902
+ if( lb_abs(dp) < lb_abs(dx) ) {
903
+ double th3 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
904
+ double s3 = lb_max(lb_abs(th3),lb_max(lb_abs(dx),lb_abs(dp)));
905
+ double ga3 = (s3*sqrt(lb_max(0.0,double((((th3/s3)*(th3/s3))-((dx/s3)*(dp/s3)))))));
906
+ double gm3 = ( ( stp > stx ) ? ((0.0-ga3)) : (ga3) );
907
+ double r3 = (((gm3-dp)+th3)/((gm3+(dx-dp))+gm3));
908
+ double stpc3 = ( ( (r3 < 0.0 && !(gm3 == 0.0)) ) ? ((stp+(r3*(stx-stp)))) : (( ( stp > stx ) ? (stpmax) : (stpmin) )) );
909
+ double stpq3 = (stp+((dp/(dp-dx))*(stx-stp)));
910
+ if( brackt == 1.0 ) {
911
+ if( lb_abs(double((stpc3-stp))) < lb_abs(double((stpq3-stp))) ) {
912
+ stpf = stpc3 ;
913
+ } else {
914
+ stpf = stpq3 ;
915
+ } ;
916
+ if( stp > stx ) {
917
+ stpf = lb_min(double((stp+(0.66*(sty-stp)))),stpf) ;
918
+ } else {
919
+ stpf = lb_max(double((stp+(0.66*(sty-stp)))),stpf) ;
920
+ } ;
921
+ } else {
922
+ if( lb_abs(double((stpc3-stp))) > lb_abs(double((stpq3-stp))) ) {
923
+ stpf = stpc3 ;
924
+ } else {
925
+ stpf = stpq3 ;
926
+ } ;
927
+ stpf = lb_min(stpmax,stpf) ;
928
+ stpf = lb_max(stpmin,stpf) ;
929
+ } ;
930
+ ;
931
+ ;
932
+ ;
933
+ ;
934
+ ;
935
+ ;
936
+ 0 ;
937
+ } else {
938
+ if( brackt == 1.0 ) {
939
+ double th4 = ((((3.0*(fp-fy))/(sty-stp))+dy)+dp);
940
+ double s4 = lb_max(lb_abs(th4),lb_max(lb_abs(dy),lb_abs(dp)));
941
+ double ga4 = (s4*sqrt((((th4/s4)*(th4/s4))-((dy/s4)*(dp/s4)))));
942
+ double gm4 = ( ( stp > sty ) ? ((0.0-ga4)) : (ga4) );
943
+ double r4 = (((gm4-dp)+th4)/(((gm4-dp)+gm4)+dy));
944
+ stpf = (stp+(r4*(sty-stp))) ;
945
+ ;
946
+ ;
947
+ ;
948
+ ;
949
+ ;
950
+ 0 ;
951
+ } else {
952
+ if( stp > stx ) {
953
+ stpf = stpmax ;
954
+ } else {
955
+ stpf = stpmin ;
956
+ } ;
957
+ } ;
958
+ } ;
959
+ } ;
960
+ } ;
961
+ if( fp > fx ) {
962
+ cs[ 3 ] = stp ;
963
+ cs[ 4 ] = fp ;
964
+ cs[ 5 ] = dp ;
965
+ } else {
966
+ if( sgnd < 0.0 ) {
967
+ cs[ 3 ] = stx ;
968
+ cs[ 4 ] = fx ;
969
+ cs[ 5 ] = dx ;
970
+ } else {
971
+ 0 ;
972
+ } ;
973
+ cs[ 0 ] = stp ;
974
+ cs[ 1 ] = fp ;
975
+ cs[ 2 ] = dp ;
976
+ } ;
977
+ cs[ 6 ] = stpf ;
978
+ cs[ 7 ] = brackt ;
979
+ return 0 ;
980
+ }
981
+
982
+
983
+ SCM2CPP_FN inline int
984
+ lb_search_start( std::array<double,16> & ls, double f, double g, double stp, double stpmin, double stpmax, double ftol )
985
+ { ls[ 0 ] = 0.0 ;
986
+ ls[ 1 ] = f ;
987
+ ls[ 2 ] = g ;
988
+ ls[ 3 ] = 0.0 ;
989
+ ls[ 4 ] = f ;
990
+ ls[ 5 ] = g ;
991
+ ls[ 6 ] = 0.0 ;
992
+ ls[ 7 ] = 1.0 ;
993
+ ls[ 8 ] = f ;
994
+ ls[ 9 ] = g ;
995
+ ls[ 10 ] = (ftol*g) ;
996
+ ls[ 11 ] = (stpmax-stpmin) ;
997
+ ls[ 12 ] = ((stpmax-stpmin)/0.5) ;
998
+ ls[ 13 ] = 0.0 ;
999
+ ls[ 14 ] = (stp+(4.0*stp)) ;
1000
+ ls[ 15 ] = stp ;
1001
+ return 0 ;
1002
+ }
1003
+
1004
+
1005
+ SCM2CPP_FN inline int
1006
+ lb_search_step( std::array<double,16> & ls, std::array<double,8> & cs, double f, double g, double ftol, double gtol, double xtol, double stpmin, double stpmax )
1007
+ { double stp = ls[15];
1008
+ double finit = ls[8];
1009
+ double ginit = ls[9];
1010
+ double gtest = ls[10];
1011
+ int task = 0;
1012
+ double ftest = (finit+(stp*gtest));
1013
+ if( (ls[7] == 1.0 && (f <= ftest && g >= 0.0)) ) {
1014
+ ls[ 7 ] = 2.0 ;
1015
+ } else {
1016
+ 0 ;
1017
+ } ;
1018
+ if( (ls[6] == 1.0 && (stp <= ls[13] || stp >= ls[14])) ) {
1019
+ task = 2 ;
1020
+ } else {
1021
+ 0 ;
1022
+ } ;
1023
+ if( (ls[6] == 1.0 && (ls[14]-ls[13]) <= (xtol*ls[14])) ) {
1024
+ task = 2 ;
1025
+ } else {
1026
+ 0 ;
1027
+ } ;
1028
+ if( (stp == stpmax && (f <= ftest && g <= gtest)) ) {
1029
+ task = 2 ;
1030
+ } else {
1031
+ 0 ;
1032
+ } ;
1033
+ if( (stp == stpmin && (f > ftest || g >= gtest)) ) {
1034
+ task = 2 ;
1035
+ } else {
1036
+ 0 ;
1037
+ } ;
1038
+ if( (f <= ftest && lb_abs(g) <= (gtol*(0.0-ginit))) ) {
1039
+ task = 1 ;
1040
+ } else {
1041
+ 0 ;
1042
+ } ;
1043
+ if( task == 0 ) {
1044
+ cs[ 0 ] = ls[0] ;
1045
+ cs[ 3 ] = ls[3] ;
1046
+ cs[ 6 ] = stp ;
1047
+ cs[ 7 ] = ls[6] ;
1048
+ if( (ls[7] == 1.0 && (f <= ls[1] && f > ftest)) ) {
1049
+ cs[ 1 ] = (ls[1]-(ls[0]*gtest)) ;
1050
+ cs[ 2 ] = (ls[2]-gtest) ;
1051
+ cs[ 4 ] = (ls[4]-(ls[3]*gtest)) ;
1052
+ cs[ 5 ] = (ls[5]-gtest) ;
1053
+ lb_dcstep(cs,double((f-(stp*gtest))),double((g-gtest)),ls[13],ls[14]) ;
1054
+ ls[ 1 ] = (cs[1]+(cs[0]*gtest)) ;
1055
+ ls[ 2 ] = (cs[2]+gtest) ;
1056
+ ls[ 4 ] = (cs[4]+(cs[3]*gtest)) ;
1057
+ ls[ 5 ] = (cs[5]+gtest) ;
1058
+ } else {
1059
+ cs[ 1 ] = ls[1] ;
1060
+ cs[ 2 ] = ls[2] ;
1061
+ cs[ 4 ] = ls[4] ;
1062
+ cs[ 5 ] = ls[5] ;
1063
+ lb_dcstep(cs,f,g,ls[13],ls[14]) ;
1064
+ ls[ 1 ] = cs[1] ;
1065
+ ls[ 2 ] = cs[2] ;
1066
+ ls[ 4 ] = cs[4] ;
1067
+ ls[ 5 ] = cs[5] ;
1068
+ } ;
1069
+ ls[ 0 ] = cs[0] ;
1070
+ ls[ 3 ] = cs[3] ;
1071
+ ls[ 6 ] = cs[7] ;
1072
+ double nstp = cs[6];
1073
+ double stx = cs[0];
1074
+ double sty = cs[3];
1075
+ if( ls[6] == 1.0 ) {
1076
+ if( lb_abs(double((sty-stx))) >= (0.66*ls[12]) ) {
1077
+ nstp = (stx+(0.5*(sty-stx))) ;
1078
+ } else {
1079
+ 0 ;
1080
+ } ;
1081
+ ls[ 12 ] = ls[11] ;
1082
+ ls[ 11 ] = lb_abs(double((sty-stx))) ;
1083
+ } else {
1084
+ 0 ;
1085
+ } ;
1086
+ if( ls[6] == 1.0 ) {
1087
+ ls[ 13 ] = lb_min(stx,sty) ;
1088
+ ls[ 14 ] = lb_max(stx,sty) ;
1089
+ } else {
1090
+ ls[ 13 ] = (nstp+(1.1*(nstp-stx))) ;
1091
+ ls[ 14 ] = (nstp+(4.0*(nstp-stx))) ;
1092
+ } ;
1093
+ nstp = lb_max(nstp,stpmin) ;
1094
+ nstp = lb_min(nstp,stpmax) ;
1095
+ if( (ls[6] == 1.0 && ((nstp <= ls[13] || nstp >= ls[14]) || (ls[14]-ls[13]) <= (xtol*ls[14]))) ) {
1096
+ nstp = stx ;
1097
+ } else {
1098
+ 0 ;
1099
+ } ;
1100
+ ls[ 15 ] = nstp ;
1101
+ ;
1102
+ } else {
1103
+ 0 ;
1104
+ } ;
1105
+ return task ;
1106
+ }
1107
+
1108
+
1109
+ SCM2CPP_FN inline double
1110
+ lb_dot( scm2cpp::cspan<double> a, scm2cpp::cspan<double> b, int nv )
1111
+ { double acc = 0.0;
1112
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1113
+ acc = (acc+(a[j]*b[j])) ;
1114
+ } ;
1115
+ return acc ;
1116
+ }
1117
+
1118
+
1119
+ SCM2CPP_FN inline double
1120
+ lb_dot_row( scm2cpp::cspan<double> mem, int slot, scm2cpp::cspan<double> v, int nv )
1121
+ { double acc = 0.0;
1122
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1123
+ acc = (acc+(mem[((slot*nv)+j)]*v[j])) ;
1124
+ } ;
1125
+ return acc ;
1126
+ }
1127
+
1128
+
1129
+ SCM2CPP_FN inline double
1130
+ lb_dot_rows( scm2cpp::cspan<double> a, int ra, scm2cpp::cspan<double> b, int rb, int nv )
1131
+ { double acc = 0.0;
1132
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1133
+ acc = (acc+(a[((ra*nv)+j)]*b[((rb*nv)+j)])) ;
1134
+ } ;
1135
+ return acc ;
1136
+ }
1137
+
1138
+
1139
+ SCM2CPP_FN inline double
1140
+ lb_projgr( scm2cpp::cspan<double> g, scm2cpp::cspan<double> w, int ib, double lbv, int nv )
1141
+ { double acc = 0.0;
1142
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1143
+ double gj = g[j];
1144
+ double gp = ( ( (j == ib && gj >= 0.0) ) ? (lb_min(double((w[j]-lbv)),gj)) : (gj) );
1145
+ double v = lb_abs(gp);
1146
+ if( v > acc ) {
1147
+ acc = v ;
1148
+ } else {
1149
+ 0 ;
1150
+ } ;
1151
+ ;
1152
+ ;
1153
+ ;
1154
+ } ;
1155
+ return acc ;
1156
+ }
1157
+
1158
+
1159
+ SCM2CPP_FN inline int
1160
+ lb_hv( scm2cpp::span<double> q, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, double theta, int col, int head, int m, int nv )
1161
+ { for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
1162
+ int slot = ((head+((col-1)-ii)) % m);
1163
+ double a = (rho[slot]*lb_dot_row(smem,slot,q,nv));
1164
+ al[ slot ] = a ;
1165
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1166
+ q[ j ] = (q[j]-(a*ymem[((slot*nv)+j)])) ;
1167
+ } ;
1168
+ ;
1169
+ ;
1170
+ } ;
1171
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1172
+ q[ j ] = (q[j]/theta) ;
1173
+ } ;
1174
+ for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
1175
+ int slot2 = ((head+ii) % m);
1176
+ double bb = (rho[slot2]*lb_dot_row(ymem,slot2,q,nv));
1177
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1178
+ q[ j ] = (q[j]+((al[slot2]-bb)*smem[((slot2*nv)+j)])) ;
1179
+ } ;
1180
+ ;
1181
+ ;
1182
+ } ;
1183
+ return 0 ;
1184
+ }
1185
+
1186
+
1187
+ SCM2CPP_FN inline double
1188
+ lb_vbv( scm2cpp::cspan<double> v, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int nv )
1189
+ { for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
1190
+ int si = ((head+ii) % m);
1191
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1192
+ bm[ ((ii*nv)+j) ] = (theta*smem[((si*nv)+j)]) ;
1193
+ } ;
1194
+ for( int jj = 0 ; !(jj == ii) ; jj = (jj+1) ) {
1195
+ int sj = ((head+jj) % m);
1196
+ double cb = (lb_dot_rows(bm,jj,smem,si,nv)/sb[jj]);
1197
+ double cy = (rho[sj]*lb_dot_rows(ymem,sj,smem,si,nv));
1198
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1199
+ bm[ ((ii*nv)+j) ] = ((bm[((ii*nv)+j)]-(cb*bm[((jj*nv)+j)]))+(cy*ymem[((sj*nv)+j)])) ;
1200
+ } ;
1201
+ ;
1202
+ ;
1203
+ } ;
1204
+ sb[ ii ] = lb_dot_rows(bm,ii,smem,si,nv) ;
1205
+ ;
1206
+ } ;
1207
+ double acc = (theta*lb_dot(v,v,nv));
1208
+ for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
1209
+ int si2 = ((head+ii) % m);
1210
+ double bv = lb_dot_row(bm,ii,v,nv);
1211
+ double yv = lb_dot_row(ymem,si2,v,nv);
1212
+ acc = ((acc-((bv*bv)/sb[ii]))+(rho[si2]*(yv*yv))) ;
1213
+ ;
1214
+ ;
1215
+ } ;
1216
+ return acc ;
1217
+ }
1218
+
1219
+
1220
+ SCM2CPP_FN inline int
1221
+ lb_direction( scm2cpp::cspan<double> w, scm2cpp::cspan<double> g, scm2cpp::span<double> d, scm2cpp::span<double> q, scm2cpp::span<double> e, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int ib, double lbv, int nv )
1222
+ { for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1223
+ q[ j ] = g[j] ;
1224
+ } ;
1225
+ lb_hv(q,smem,ymem,rho,al,theta,col,head,m,nv) ;
1226
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1227
+ d[ j ] = (0.0-q[j]) ;
1228
+ } ;
1229
+ if( ib >= 0 ) {
1230
+ double gs = g[ib];
1231
+ double tl = (w[ib]-lbv);
1232
+ int fixed = 0;
1233
+ double delta = 0.0;
1234
+ double dtm = 0.0;
1235
+ if( (tl <= 0.0 && gs >= 0.0) ) {
1236
+ fixed = 1 ;
1237
+ } else {
1238
+ dtm = (lb_dot(g,g,nv)/lb_vbv(g,smem,ymem,rho,bm,sb,theta,col,head,m,nv)) ;
1239
+ if( (gs > 0.0 && dtm >= (tl/gs)) ) {
1240
+ fixed = 1 ;
1241
+ delta = (0.0-tl) ;
1242
+ } else {
1243
+ 0 ;
1244
+ } ;
1245
+ } ;
1246
+ if( fixed == 1 ) {
1247
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1248
+ e[ j ] = 0.0 ;
1249
+ } ;
1250
+ e[ ib ] = 1.0 ;
1251
+ lb_hv(e,smem,ymem,rho,al,theta,col,head,m,nv) ;
1252
+ double lam = ((delta+q[ib])/e[ib]);
1253
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1254
+ d[ j ] = (d[j]+(lam*e[j])) ;
1255
+ } ;
1256
+ ;
1257
+ d[ ib ] = delta ;
1258
+ } else {
1259
+ if( (w[ib]+d[ib]) < lbv ) {
1260
+ double ddp = ((lb_dot(d,g,nv)-(d[ib]*gs))+((lbv-w[ib])*gs));
1261
+ if( ddp > 0.0 ) {
1262
+ double dus = (d[ib]-((0.0-dtm)*gs));
1263
+ double xcps = (w[ib]-(dtm*gs));
1264
+ double alpha = 1.0;
1265
+ if( dus < 0.0 ) {
1266
+ double temp2 = (lbv-xcps);
1267
+ if( temp2 >= 0.0 ) {
1268
+ alpha = 0.0 ;
1269
+ } else {
1270
+ if( dus < temp2 ) {
1271
+ alpha = (temp2/dus) ;
1272
+ } else {
1273
+ 0 ;
1274
+ } ;
1275
+ } ;
1276
+ ;
1277
+ } else {
1278
+ 0 ;
1279
+ } ;
1280
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1281
+ double xcpj = ((0.0-dtm)*g[j]);
1282
+ d[ j ] = (xcpj+(alpha*(d[j]-xcpj))) ;
1283
+ ;
1284
+ } ;
1285
+ if( alpha < 1.0 ) {
1286
+ d[ ib ] = (lbv-w[ib]) ;
1287
+ } else {
1288
+ 0 ;
1289
+ } ;
1290
+ ;
1291
+ } else {
1292
+ d[ ib ] = (lbv-w[ib]) ;
1293
+ } ;
1294
+ ;
1295
+ } else {
1296
+ 0 ;
1297
+ } ;
1298
+ } ;
1299
+ ;
1300
+ } else {
1301
+ 0 ;
1302
+ } ;
1303
+ return 0 ;
1304
+ }
1305
+
1306
+
1307
+ inline int
1308
+ lbfgs( int kind, scm2cpp::span<double> w, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, scm2cpp::span<double> out, int m, int maxiter, double pgtol, double ftol, int maxls, int ib, double lbv, int nv, int n, int p, int k )
1309
+ { std::vector<double> g(nv,0.0);
1310
+ std::vector<double> gold(nv,0.0);
1311
+ std::vector<double> d(nv,0.0);
1312
+ std::vector<double> t(nv,0.0);
1313
+ std::vector<double> q(nv,0.0);
1314
+ std::vector<double> e(nv,0.0);
1315
+ std::vector<double> smem((m*nv),0.0);
1316
+ std::vector<double> ymem((m*nv),0.0);
1317
+ std::vector<double> bm((m*nv),0.0);
1318
+ std::vector<double> rho(m,0.0);
1319
+ std::vector<double> sb(m,0.0);
1320
+ std::vector<double> al(m,0.0);
1321
+ std::array<double,16> ls = scm2cpp::filled_array<double,16>(0.0);
1322
+ std::array<double,8> cs = scm2cpp::filled_array<double,8>(0.0);
1323
+ double eps = 2.220446049250313e-16;
1324
+ int iter = 0;
1325
+ int col = 0;
1326
+ int head = 0;
1327
+ double theta = 1.0;
1328
+ int nfg = 0;
1329
+ int done = 0;
1330
+ double f = lbfgs_fg(kind,w,g,x,y,aux,work,n,p,k);
1331
+ nfg = 1 ;
1332
+ if( lb_projgr(g,w,ib,lbv,nv) <= pgtol ) {
1333
+ done = 1 ;
1334
+ } else {
1335
+ 0 ;
1336
+ } ;
1337
+ for( ; !(done == 1) ; ) {
1338
+ lb_direction(w,g,d,q,e,smem,ymem,rho,al,bm,sb,theta,col,head,m,ib,lbv,nv) ;
1339
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1340
+ t[ j ] = w[j] ;
1341
+ gold[ j ] = g[j] ;
1342
+ } ;
1343
+ double fold = f;
1344
+ double dnorm = sqrt(lb_dot(d,d,nv));
1345
+ double gdold = lb_dot(g,d,nv);
1346
+ double stpmx = 10000000000.0;
1347
+ double gd = 0.0;
1348
+ int task = 0;
1349
+ int ifun = 0;
1350
+ int fail = 0;
1351
+ if( ib >= 0 ) {
1352
+ if( iter == 0 ) {
1353
+ stpmx = 1.0 ;
1354
+ } else {
1355
+ if( d[ib] < 0.0 ) {
1356
+ double a2 = (lbv-w[ib]);
1357
+ if( a2 >= 0.0 ) {
1358
+ stpmx = 0.0 ;
1359
+ } else {
1360
+ if( (d[ib]*stpmx) < a2 ) {
1361
+ stpmx = (a2/d[ib]) ;
1362
+ } else {
1363
+ 0 ;
1364
+ } ;
1365
+ } ;
1366
+ ;
1367
+ } else {
1368
+ 0 ;
1369
+ } ;
1370
+ } ;
1371
+ } else {
1372
+ 0 ;
1373
+ } ;
1374
+ if( gdold >= 0.0 ) {
1375
+ fail = 1 ;
1376
+ } else {
1377
+ lb_search_start(ls,f,gdold,( ( iter == 0 ) ? (lb_min(double((1.0/dnorm)),stpmx)) : (1.0) ),0.0,stpmx,0.001) ;
1378
+ for( ; !((fail == 1 || !(task == 0))) ; ) {
1379
+ ifun = (ifun+1) ;
1380
+ if( ifun > maxls ) {
1381
+ fail = 1 ;
1382
+ } else {
1383
+ double stp = ls[15];
1384
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1385
+ w[ j ] = (t[j]+(stp*d[j])) ;
1386
+ } ;
1387
+ f = lbfgs_fg(kind,w,g,x,y,aux,work,n,p,k) ;
1388
+ nfg = (nfg+1) ;
1389
+ gd = lb_dot(g,d,nv) ;
1390
+ task = lb_search_step(ls,cs,f,gd,0.001,0.9,0.1,0.0,stpmx) ;
1391
+ ;
1392
+ } ;
1393
+ } ;
1394
+ } ;
1395
+ if( fail == 1 ) {
1396
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1397
+ w[ j ] = t[j] ;
1398
+ g[ j ] = gold[j] ;
1399
+ } ;
1400
+ f = fold ;
1401
+ if( col == 0 ) {
1402
+ done = 1 ;
1403
+ } else {
1404
+ col = 0 ;
1405
+ head = 0 ;
1406
+ theta = 1.0 ;
1407
+ } ;
1408
+ } else {
1409
+ double stp2 = ls[15];
1410
+ iter = (iter+1) ;
1411
+ if( iter >= maxiter ) {
1412
+ done = 1 ;
1413
+ } else {
1414
+ 0 ;
1415
+ } ;
1416
+ if( lb_projgr(g,w,ib,lbv,nv) <= pgtol ) {
1417
+ done = 1 ;
1418
+ } else {
1419
+ 0 ;
1420
+ } ;
1421
+ if( (fold-f) <= (ftol*lb_max(lb_max(lb_abs(fold),lb_abs(f)),1.0)) ) {
1422
+ done = 1 ;
1423
+ } else {
1424
+ 0 ;
1425
+ } ;
1426
+ if( done == 0 ) {
1427
+ double dr = ((gd-gdold)*stp2);
1428
+ double ddum = ((0.0-gdold)*stp2);
1429
+ if( dr > (eps*ddum) ) {
1430
+ int slot3 = ( ( col < m ) ? (((head+col) % m)) : (head) );
1431
+ double rr = 0.0;
1432
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
1433
+ double yj = (g[j]-gold[j]);
1434
+ smem[ ((slot3*nv)+j) ] = (stp2*d[j]) ;
1435
+ ymem[ ((slot3*nv)+j) ] = yj ;
1436
+ rr = (rr+(yj*yj)) ;
1437
+ ;
1438
+ } ;
1439
+ rho[ slot3 ] = (1.0/dr) ;
1440
+ theta = (rr/dr) ;
1441
+ if( col < m ) {
1442
+ col = (col+1) ;
1443
+ } else {
1444
+ head = ((head+1) % m) ;
1445
+ } ;
1446
+ ;
1447
+ ;
1448
+ 0 ;
1449
+ } else {
1450
+ 0 ;
1451
+ } ;
1452
+ ;
1453
+ } else {
1454
+ 0 ;
1455
+ } ;
1456
+ ;
1457
+ } ;
1458
+ ;
1459
+ } ;
1460
+ out[ 0 ] = f ;
1461
+ out[ 1 ] = double(nfg) ;
1462
+ return iter ;
1463
+ }
1464
+
1465
+
1466
+ SCM2CPP_FN inline double
1467
+ lbfgs_fg( int kind, scm2cpp::cspan<double> w, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, int n, int p, int k )
1468
+ {
1469
+ if( kind == 0 ) {
1470
+ return logistic_fg(w,g,x,y,work,aux[0],( ( aux[1] == 1.0 ) ? (1) : (0) ),( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p,k) ;
1471
+ }
1472
+ else {
1473
+ if( kind == 1 ) {
1474
+ return huber_fg(w,g,x,y,work,aux[0],aux[1],( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p) ;
1475
+ }
1476
+ else {
1477
+ return glm_fg(w,g,x,y,work,int(aux[1]),aux[3],aux[0],( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p) ;
1478
+ }
1479
+ }
1480
+ }
1481
+
1482
+
1483
+ SCM2CPP_FN inline int
1484
+ gmm_mstep( scm2cpp::cspan<double> x, scm2cpp::cspan<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> dw, scm2cpp::span<double> cov, scm2cpp::span<double> l, scm2cpp::span<double> u, double reg, int norm, int n, int p, int kc )
1485
+ { double tot = 0.0;
1486
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1487
+ weights[ c ] = 0.0 ;
1488
+ } ;
1489
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1490
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1491
+ weights[ c ] = (weights[c]+resp[((i*kc)+c)]) ;
1492
+ } ;
1493
+ } ;
1494
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1495
+ weights[ c ] = (weights[c]+(10.0*2.220446049250313e-16)) ;
1496
+ tot = (tot+weights[c]) ;
1497
+ } ;
1498
+ scm2cpp::blas_gemm(means, resp, x, 1.0, 0.0, 1, 0, kc, p, n) ;
1499
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1500
+ double nk = weights[c];
1501
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1502
+ means[ ((c*p)+j) ] = (means[((c*p)+j)]/nk) ;
1503
+ } ;
1504
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1505
+ double r = resp[((i*kc)+c)];
1506
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1507
+ double dv = (x[((i*p)+j)]-means[((c*p)+j)]);
1508
+ u[ ((i*p)+j) ] = dv ;
1509
+ dw[ ((i*p)+j) ] = (r*dv) ;
1510
+ ;
1511
+ } ;
1512
+ ;
1513
+ } ;
1514
+ scm2cpp::blas_gemm(cov, dw, u, 1.0, 0.0, 1, 0, p, p, n) ;
1515
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1516
+ cov[ t ] = (cov[t]/nk) ;
1517
+ } ;
1518
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1519
+ cov[ ((j*p)+j) ] = (cov[((j*p)+j)]+reg) ;
1520
+ } ;
1521
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1522
+ double s = cov[((j*p)+j)];
1523
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
1524
+ s = (s-(l[((j*p)+m)]*l[((j*p)+m)])) ;
1525
+ } ;
1526
+ l[ ((j*p)+j) ] = sqrt(s) ;
1527
+ for( int i = (j+1) ; !(i >= p) ; i = (i+1) ) {
1528
+ double t2 = cov[((i*p)+j)];
1529
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
1530
+ t2 = (t2-(l[((i*p)+m)]*l[((j*p)+m)])) ;
1531
+ } ;
1532
+ l[ ((i*p)+j) ] = (t2/l[((j*p)+j)]) ;
1533
+ ;
1534
+ } ;
1535
+ ;
1536
+ } ;
1537
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1538
+ prec[ ((c*(p*p))+t) ] = 0.0 ;
1539
+ } ;
1540
+ for( int e = 0 ; !(e == p) ; e = (e+1) ) {
1541
+ for( int i = e ; !(i == p) ; i = (i+1) ) {
1542
+ double t3 = ( ( i == e ) ? (1.0) : (0.0) );
1543
+ for( int m = e ; !(m == i) ; m = (m+1) ) {
1544
+ t3 = (t3-(l[((i*p)+m)]*prec[((c*(p*p))+((e*p)+m))])) ;
1545
+ } ;
1546
+ prec[ ((c*(p*p))+((e*p)+i)) ] = (t3/l[((i*p)+i)]) ;
1547
+ ;
1548
+ } ;
1549
+ } ;
1550
+ ;
1551
+ } ;
1552
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1553
+ weights[ c ] = (weights[c]/( ( norm == 1 ) ? (double(n)) : (tot) )) ;
1554
+ } ;
1555
+ return 0 ;
1556
+ }
1557
+
1558
+
1559
+ SCM2CPP_FN inline double
1560
+ gmm_estep( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::cspan<double> weights, scm2cpp::cspan<double> means, scm2cpp::cspan<double> prec, scm2cpp::span<double> wlp, scm2cpp::span<double> y, scm2cpp::span<double> u, scm2cpp::span<double> mu, int n, int p, int kc )
1561
+ { for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1562
+ double logdet = 0.0;
1563
+ double lw = log(weights[c]);
1564
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1565
+ u[ t ] = prec[((c*(p*p))+t)] ;
1566
+ } ;
1567
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1568
+ logdet = (logdet+log(u[((j*p)+j)])) ;
1569
+ double acc = 0.0;
1570
+ for( int m = 0 ; !(m == p) ; m = (m+1) ) {
1571
+ acc = (acc+(means[((c*p)+m)]*u[((m*p)+j)])) ;
1572
+ } ;
1573
+ mu[ j ] = acc ;
1574
+ ;
1575
+ } ;
1576
+ scm2cpp::blas_gemm(y, x, u, 1.0, 0.0, 0, 0, n, p, p) ;
1577
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1578
+ double sq = 0.0;
1579
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1580
+ double v = (y[((i*p)+j)]-mu[j]);
1581
+ sq = (sq+(v*v)) ;
1582
+ ;
1583
+ } ;
1584
+ wlp[ ((i*kc)+c) ] = (((-0.5*((double(p)*1.8378770664093453)+sq))+logdet)+lw) ;
1585
+ ;
1586
+ } ;
1587
+ ;
1588
+ } ;
1589
+ double lb = 0.0;
1590
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1591
+ double amax = wlp[(i*kc)];
1592
+ double se = 0.0;
1593
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
1594
+ if( wlp[((i*kc)+c)] > amax ) {
1595
+ amax = wlp[((i*kc)+c)] ;
1596
+ } else {
1597
+ 0 ;
1598
+ } ;
1599
+ } ;
1600
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1601
+ se = (se+exp((wlp[((i*kc)+c)]-amax))) ;
1602
+ } ;
1603
+ double lse = (log(se)+amax);
1604
+ lb = (lb+lse) ;
1605
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1606
+ resp[ ((i*kc)+c) ] = exp((wlp[((i*kc)+c)]-lse)) ;
1607
+ } ;
1608
+ ;
1609
+ ;
1610
+ } ;
1611
+ return (lb/double(n)) ;
1612
+ }
1613
+
1614
+
1615
+ SCM2CPP_FN inline double
1616
+ gmm_abs( double a )
1617
+ {
1618
+ if( a < 0.0 ) {
1619
+ return (0.0-a) ;
1620
+ }
1621
+ else {
1622
+ return a ;
1623
+ }
1624
+ }
1625
+
1626
+
1627
+ inline int
1628
+ gmm( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> labels, scm2cpp::span<double> out, int maxiter, double tol, double reg, int n, int p, int kc )
1629
+ { std::vector<double> dw((n*p),0.0);
1630
+ std::vector<double> y((n*p),0.0);
1631
+ std::vector<double> wlp((n*kc),0.0);
1632
+ std::vector<double> cov((p*p),0.0);
1633
+ std::vector<double> l((p*p),0.0);
1634
+ std::vector<double> u((p*p),0.0);
1635
+ std::vector<double> mu(p,0.0);
1636
+ double lb = -1e+300;
1637
+ int it = 0;
1638
+ int conv = 0;
1639
+ int done = 0;
1640
+ gmm_mstep(x,resp,weights,means,prec,dw,cov,l,y,reg,1,n,p,kc) ;
1641
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
1642
+ double prev = lb;
1643
+ lb = gmm_estep(x,resp,weights,means,prec,wlp,y,u,mu,n,p,kc) ;
1644
+ gmm_mstep(x,resp,weights,means,prec,dw,cov,l,y,reg,0,n,p,kc) ;
1645
+ it = (it+1) ;
1646
+ if( (it > 1 && gmm_abs(double((lb-prev))) < tol) ) {
1647
+ conv = 1 ;
1648
+ done = 1 ;
1649
+ } else {
1650
+ 0 ;
1651
+ } ;
1652
+ ;
1653
+ } ;
1654
+ gmm_estep(x,resp,weights,means,prec,wlp,y,u,mu,n,p,kc) ;
1655
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1656
+ int best = 0;
1657
+ double bv = resp[(i*kc)];
1658
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
1659
+ if( resp[((i*kc)+c)] > bv ) {
1660
+ bv = resp[((i*kc)+c)] ;
1661
+ best = c ;
1662
+ } else {
1663
+ 0 ;
1664
+ } ;
1665
+ } ;
1666
+ labels[ i ] = double(best) ;
1667
+ ;
1668
+ } ;
1669
+ out[ 0 ] = lb ;
1670
+ out[ 1 ] = double(conv) ;
1671
+ return it ;
1672
+ }
1673
+
1674
+
1675
+ SCM2CPP_FN inline double
1676
+ eig_hypot( double a, double b )
1677
+ {
1678
+ double aa = ( ( a < 0.0 ) ? ((0.0-a)) : (a) );
1679
+ double bb = ( ( b < 0.0 ) ? ((0.0-b)) : (b) );
1680
+ if( aa > bb ) {
1681
+ return (aa*sqrt((1.0+((bb/aa)*(bb/aa))))) ;
1682
+ }
1683
+ else {
1684
+ if( bb == 0.0 ) {
1685
+ return 0.0 ;
1686
+ }
1687
+ else {
1688
+ return (bb*sqrt((1.0+((aa/bb)*(aa/bb))))) ;
1689
+ }
1690
+ }
1691
+ }
1692
+
1693
+
1694
+ SCM2CPP_FN inline int
1695
+ sym_eigen( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m )
1696
+ { for( int ii = 0 ; !(ii == (m-1)) ; ii = (ii+1) ) {
1697
+ int i = ((m-1)-ii);
1698
+ int l = (i-1);
1699
+ double h = 0.0;
1700
+ double scale = 0.0;
1701
+ if( l > 0 ) {
1702
+ for( int k = 0 ; !(k > l) ; k = (k+1) ) {
1703
+ double ak = a[((i*m)+k)];
1704
+ scale = (scale+( ( ak < 0.0 ) ? ((0.0-ak)) : (ak) )) ;
1705
+ ;
1706
+ } ;
1707
+ if( scale == 0.0 ) {
1708
+ e[ i ] = a[((i*m)+l)] ;
1709
+ } else {
1710
+ for( int k = 0 ; !(k > l) ; k = (k+1) ) {
1711
+ a[ ((i*m)+k) ] = (a[((i*m)+k)]/scale) ;
1712
+ h = (h+(a[((i*m)+k)]*a[((i*m)+k)])) ;
1713
+ } ;
1714
+ double f = a[((i*m)+l)];
1715
+ double g = ( ( f >= 0.0 ) ? ((0.0-sqrt(h))) : (sqrt(h)) );
1716
+ e[ i ] = (scale*g) ;
1717
+ h = (h-(f*g)) ;
1718
+ a[ ((i*m)+l) ] = (f-g) ;
1719
+ double ff = 0.0;
1720
+ for( int j = 0 ; !(j > l) ; j = (j+1) ) {
1721
+ a[ ((j*m)+i) ] = (a[((i*m)+j)]/h) ;
1722
+ double gg = 0.0;
1723
+ for( int k = 0 ; !(k > j) ; k = (k+1) ) {
1724
+ gg = (gg+(a[((j*m)+k)]*a[((i*m)+k)])) ;
1725
+ } ;
1726
+ for( int k = (j+1) ; !(k > l) ; k = (k+1) ) {
1727
+ gg = (gg+(a[((k*m)+j)]*a[((i*m)+k)])) ;
1728
+ } ;
1729
+ e[ j ] = (gg/h) ;
1730
+ ff = (ff+(e[j]*a[((i*m)+j)])) ;
1731
+ ;
1732
+ } ;
1733
+ double hh = (ff/(h+h));
1734
+ for( int j = 0 ; !(j > l) ; j = (j+1) ) {
1735
+ double f2 = a[((i*m)+j)];
1736
+ double g2 = (e[j]-(hh*f2));
1737
+ e[ j ] = g2 ;
1738
+ for( int k = 0 ; !(k > j) ; k = (k+1) ) {
1739
+ a[ ((j*m)+k) ] = (a[((j*m)+k)]-((f2*e[k])+(g2*a[((i*m)+k)]))) ;
1740
+ } ;
1741
+ ;
1742
+ ;
1743
+ } ;
1744
+ ;
1745
+ ;
1746
+ ;
1747
+ ;
1748
+ } ;
1749
+ } else {
1750
+ e[ i ] = a[((i*m)+l)] ;
1751
+ } ;
1752
+ ev[ i ] = h ;
1753
+ ;
1754
+ ;
1755
+ } ;
1756
+ ev[ 0 ] = 0.0 ;
1757
+ e[ 0 ] = 0.0 ;
1758
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1759
+ if( !(ev[i] == 0.0) ) {
1760
+ for( int j = 0 ; !(j == i) ; j = (j+1) ) {
1761
+ double g3 = 0.0;
1762
+ for( int k = 0 ; !(k == i) ; k = (k+1) ) {
1763
+ g3 = (g3+(a[((i*m)+k)]*a[((k*m)+j)])) ;
1764
+ } ;
1765
+ for( int k = 0 ; !(k == i) ; k = (k+1) ) {
1766
+ a[ ((k*m)+j) ] = (a[((k*m)+j)]-(g3*a[((k*m)+i)])) ;
1767
+ } ;
1768
+ ;
1769
+ } ;
1770
+ } else {
1771
+ 0 ;
1772
+ } ;
1773
+ ev[ i ] = a[((i*m)+i)] ;
1774
+ a[ ((i*m)+i) ] = 1.0 ;
1775
+ for( int j = 0 ; !(j == i) ; j = (j+1) ) {
1776
+ a[ ((j*m)+i) ] = 0.0 ;
1777
+ a[ ((i*m)+j) ] = 0.0 ;
1778
+ } ;
1779
+ } ;
1780
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1781
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1782
+ v[ ((j*m)+i) ] = a[((i*m)+j)] ;
1783
+ } ;
1784
+ } ;
1785
+ for( int i = 1 ; !(i == m) ; i = (i+1) ) {
1786
+ e[ (i-1) ] = e[i] ;
1787
+ } ;
1788
+ e[ (m-1) ] = 0.0 ;
1789
+ for( int l = 0 ; !(l == m) ; l = (l+1) ) {
1790
+ int fin = 0;
1791
+ int iter = 0;
1792
+ for( ; !((fin == 1 || iter > 60)) ; ) {
1793
+ int mm = l;
1794
+ int found = 0;
1795
+ for( ; !((found == 1 || mm >= (m-1))) ; ) {
1796
+ double dd = (eig_abs(ev[mm])+eig_abs(ev[(mm+1)]));
1797
+ if( (eig_abs(e[mm])+dd) == dd ) {
1798
+ found = 1 ;
1799
+ } else {
1800
+ mm = (mm+1) ;
1801
+ } ;
1802
+ ;
1803
+ } ;
1804
+ if( mm == l ) {
1805
+ fin = 1 ;
1806
+ } else {
1807
+ iter = (iter+1) ;
1808
+ double g = ((ev[(l+1)]-ev[l])/(2.0*e[l]));
1809
+ double r = eig_hypot(g,1.0);
1810
+ double g4 = ((ev[mm]-ev[l])+(e[l]/(g+( ( g >= 0.0 ) ? (eig_abs(r)) : ((0.0-eig_abs(r))) ))));
1811
+ double s = 1.0;
1812
+ double c = 1.0;
1813
+ double pp = 0.0;
1814
+ double gq = g4;
1815
+ int under = 0;
1816
+ int i = (mm-1);
1817
+ for( ; !((under == 1 || i < l)) ; ) {
1818
+ double f = (s*e[i]);
1819
+ double b = (c*e[i]);
1820
+ double r2 = eig_hypot(f,gq);
1821
+ e[ (i+1) ] = r2 ;
1822
+ if( r2 == 0.0 ) {
1823
+ ev[ (i+1) ] = (ev[(i+1)]-pp) ;
1824
+ e[ mm ] = 0.0 ;
1825
+ under = 1 ;
1826
+ } else {
1827
+ s = (f/r2) ;
1828
+ c = (gq/r2) ;
1829
+ double g5 = (ev[(i+1)]-pp);
1830
+ double r3 = (((ev[i]-g5)*s)+(2.0*(c*b)));
1831
+ pp = (s*r3) ;
1832
+ ev[ (i+1) ] = (g5+pp) ;
1833
+ gq = ((c*r3)-b) ;
1834
+ ;
1835
+ ;
1836
+ for( int k = 0 ; !(k == m) ; k = (k+1) ) {
1837
+ double zf = v[(((i+1)*m)+k)];
1838
+ double zi = v[((i*m)+k)];
1839
+ v[ (((i+1)*m)+k) ] = ((s*zi)+(c*zf)) ;
1840
+ v[ ((i*m)+k) ] = ((c*zi)-(s*zf)) ;
1841
+ ;
1842
+ } ;
1843
+ i = (i-1) ;
1844
+ } ;
1845
+ ;
1846
+ ;
1847
+ } ;
1848
+ if( under == 0 ) {
1849
+ ev[ l ] = (ev[l]-pp) ;
1850
+ e[ l ] = gq ;
1851
+ e[ mm ] = 0.0 ;
1852
+ } else {
1853
+ 0 ;
1854
+ } ;
1855
+ ;
1856
+ ;
1857
+ ;
1858
+ ;
1859
+ } ;
1860
+ ;
1861
+ } ;
1862
+ ;
1863
+ } ;
1864
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1865
+ for( int j = (i+1) ; !(j >= m) ; j = (j+1) ) {
1866
+ double tmp = v[((i*m)+j)];
1867
+ v[ ((i*m)+j) ] = v[((j*m)+i)] ;
1868
+ v[ ((j*m)+i) ] = tmp ;
1869
+ ;
1870
+ } ;
1871
+ } ;
1872
+ return 0 ;
1873
+ }
1874
+
1875
+
1876
+ SCM2CPP_FN inline double
1877
+ eig_abs( double a )
1878
+ {
1879
+ if( a < 0.0 ) {
1880
+ return (0.0-a) ;
1881
+ }
1882
+ else {
1883
+ return a ;
1884
+ }
1885
+ }
1886
+
1887
+
1888
+ SCM2CPP_FN inline int
1889
+ eig_order( scm2cpp::cspan<double> ev, scm2cpp::span<int> ord, int m )
1890
+ { for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1891
+ ord[ j ] = j ;
1892
+ } ;
1893
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1894
+ int best = j;
1895
+ for( int r = (j+1) ; !(r >= m) ; r = (r+1) ) {
1896
+ if( ev[ord[r]] > ev[ord[best]] ) {
1897
+ best = r ;
1898
+ } else {
1899
+ 0 ;
1900
+ } ;
1901
+ } ;
1902
+ int tmp = ord[j];
1903
+ ord[ j ] = ord[best] ;
1904
+ ord[ best ] = tmp ;
1905
+ ;
1906
+ ;
1907
+ } ;
1908
+ return 0 ;
1909
+ }
1910
+
1911
+
1912
+ SCM2CPP_FN inline double
1913
+ ica_tanh( double x )
1914
+ {
1915
+ return (1.0-(2.0/(exp((2.0*x))+1.0))) ;
1916
+ }
1917
+
1918
+
1919
+ SCM2CPP_FN inline int
1920
+ ica_sym( scm2cpp::span<double> w, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::span<double> t, int m )
1921
+ { for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1922
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1923
+ double acc = 0.0;
1924
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
1925
+ acc = (acc+(w[((i*m)+r)]*w[((j*m)+r)])) ;
1926
+ } ;
1927
+ a[ ((i*m)+j) ] = acc ;
1928
+ ;
1929
+ } ;
1930
+ } ;
1931
+ sym_eigen(a,v,ev,e,m) ;
1932
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1933
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1934
+ double acc = 0.0;
1935
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
1936
+ double sr = ( ( ev[r] < 2.2250738585072014e-308 ) ? (2.2250738585072014e-308) : (ev[r]) );
1937
+ acc = (acc+((v[((i*m)+r)]/sqrt(sr))*v[((j*m)+r)])) ;
1938
+ ;
1939
+ } ;
1940
+ t[ ((i*m)+j) ] = acc ;
1941
+ ;
1942
+ } ;
1943
+ } ;
1944
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
1945
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
1946
+ double acc = 0.0;
1947
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
1948
+ acc = (acc+(t[((i*m)+r)]*w[((r*m)+j)])) ;
1949
+ } ;
1950
+ a[ ((i*m)+j) ] = acc ;
1951
+ ;
1952
+ } ;
1953
+ } ;
1954
+ for( int t2 = 0 ; !(t2 == (m*m)) ; t2 = (t2+1) ) {
1955
+ w[ t2 ] = a[t2] ;
1956
+ } ;
1957
+ return 0 ;
1958
+ }
1959
+
1960
+
1961
+ inline int
1962
+ fastica( scm2cpp::cspan<double> x, scm2cpp::cspan<double> winit, scm2cpp::span<double> comps, scm2cpp::span<double> white, scm2cpp::span<double> unmix, scm2cpp::span<double> mean, int maxiter, double tol, int n, int p, int nc )
1963
+ { std::vector<double> xc((n*p),0.0);
1964
+ std::vector<double> g((p*p),0.0);
1965
+ std::vector<double> u((p*p),0.0);
1966
+ std::vector<double> ev(p,0.0);
1967
+ std::vector<int> ord(p,0);
1968
+ std::vector<double> x1((nc*n),0.0);
1969
+ std::vector<double> gw((nc*n),0.0);
1970
+ std::vector<double> w1((nc*nc),0.0);
1971
+ std::vector<double> gx(nc,0.0);
1972
+ std::vector<double> sa((nc*nc),0.0);
1973
+ std::vector<double> sv((nc*nc),0.0);
1974
+ std::vector<double> se(nc,0.0);
1975
+ std::vector<double> se2(nc,0.0);
1976
+ std::vector<double> pe(p,0.0);
1977
+ std::vector<double> st((nc*nc),0.0);
1978
+ int it = 0;
1979
+ int done = 0;
1980
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1981
+ mean[ j ] = 0.0 ;
1982
+ } ;
1983
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1984
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1985
+ mean[ j ] = (mean[j]+x[((i*p)+j)]) ;
1986
+ } ;
1987
+ } ;
1988
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1989
+ mean[ j ] = (mean[j]/double(n)) ;
1990
+ } ;
1991
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1992
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1993
+ xc[ ((i*p)+j) ] = (x[((i*p)+j)]-mean[j]) ;
1994
+ } ;
1995
+ } ;
1996
+ scm2cpp::blas_syrk(g, xc, 1.0, 0.0, 1, p, n) ;
1997
+ sym_eigen(g,u,ev,pe,p) ;
1998
+ eig_order(ev,ord,p) ;
1999
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2000
+ int col = ord[c];
2001
+ double sg = ( ( u[col] < 0.0 ) ? (-1.0) : (( ( u[col] > 0.0 ) ? (1.0) : (0.0) )) );
2002
+ double d = sqrt(ev[col]);
2003
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2004
+ white[ ((c*p)+j) ] = ((sg*u[((j*p)+col)])/d) ;
2005
+ } ;
2006
+ ;
2007
+ ;
2008
+ } ;
2009
+ scm2cpp::blas_gemm(x1, white, xc, 1.0, 0.0, 0, 1, nc, n, p) ;
2010
+ double sn = sqrt(double(n));
2011
+ for( int t = 0 ; !(t == (nc*n)) ; t = (t+1) ) {
2012
+ x1[ t ] = (x1[t]*sn) ;
2013
+ } ;
2014
+ ;
2015
+ for( int t = 0 ; !(t == (nc*nc)) ; t = (t+1) ) {
2016
+ unmix[ t ] = winit[t] ;
2017
+ } ;
2018
+ ica_sym(unmix,sa,sv,se,se2,st,nc) ;
2019
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
2020
+ scm2cpp::blas_gemm(gw, unmix, x1, 1.0, 0.0, 0, 0, nc, n, nc) ;
2021
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2022
+ double acc = 0.0;
2023
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2024
+ double th = ica_tanh(gw[((c*n)+i)]);
2025
+ gw[ ((c*n)+i) ] = th ;
2026
+ acc = (acc+(1.0-(th*th))) ;
2027
+ ;
2028
+ } ;
2029
+ gx[ c ] = (acc/double(n)) ;
2030
+ ;
2031
+ } ;
2032
+ scm2cpp::blas_gemm(w1, gw, x1, 1.0, 0.0, 0, 1, nc, nc, n) ;
2033
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2034
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
2035
+ w1[ ((c*nc)+j) ] = ((w1[((c*nc)+j)]/double(n))-(gx[c]*unmix[((c*nc)+j)])) ;
2036
+ } ;
2037
+ } ;
2038
+ ica_sym(w1,sa,sv,se,se2,st,nc) ;
2039
+ double lim = 0.0;
2040
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2041
+ double acc = 0.0;
2042
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
2043
+ acc = (acc+(w1[((c*nc)+j)]*unmix[((c*nc)+j)])) ;
2044
+ } ;
2045
+ double dv = (( ( acc < 0.0 ) ? ((0.0-acc)) : (acc) )-1.0);
2046
+ double av = ( ( dv < 0.0 ) ? ((0.0-dv)) : (dv) );
2047
+ if( av > lim ) {
2048
+ lim = av ;
2049
+ } else {
2050
+ 0 ;
2051
+ } ;
2052
+ ;
2053
+ ;
2054
+ ;
2055
+ } ;
2056
+ for( int t = 0 ; !(t == (nc*nc)) ; t = (t+1) ) {
2057
+ unmix[ t ] = w1[t] ;
2058
+ } ;
2059
+ it = (it+1) ;
2060
+ if( lim < tol ) {
2061
+ done = 1 ;
2062
+ } else {
2063
+ 0 ;
2064
+ } ;
2065
+ ;
2066
+ } ;
2067
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2068
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2069
+ double acc = 0.0;
2070
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
2071
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
2072
+ } ;
2073
+ comps[ ((c*p)+j) ] = acc ;
2074
+ ;
2075
+ } ;
2076
+ } ;
2077
+ scm2cpp::blas_gemm(gw, comps, xc, 1.0, 0.0, 0, 1, nc, n, p) ;
2078
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2079
+ double m1 = 0.0;
2080
+ double v1 = 0.0;
2081
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2082
+ m1 = (m1+gw[((c*n)+i)]) ;
2083
+ } ;
2084
+ m1 = (m1/double(n)) ;
2085
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2086
+ double dd = (gw[((c*n)+i)]-m1);
2087
+ v1 = (v1+(dd*dd)) ;
2088
+ ;
2089
+ } ;
2090
+ double sd = sqrt((v1/double(n)));
2091
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
2092
+ unmix[ ((c*nc)+j) ] = (unmix[((c*nc)+j)]/sd) ;
2093
+ } ;
2094
+ ;
2095
+ ;
2096
+ } ;
2097
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
2098
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2099
+ double acc = 0.0;
2100
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
2101
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
2102
+ } ;
2103
+ comps[ ((c*p)+j) ] = acc ;
2104
+ ;
2105
+ } ;
2106
+ } ;
2107
+ return it ;
2108
+ }
2109
+
2110
+
2111
+ inline int
2112
+ pca( scm2cpp::cspan<double> x, scm2cpp::span<double> comps, scm2cpp::span<double> ev, scm2cpp::span<double> sv, scm2cpp::span<double> mean, int n, int p )
2113
+ { std::vector<double> c((p*p),0.0);
2114
+ std::vector<double> v((p*p),0.0);
2115
+ std::vector<double> e(p,0.0);
2116
+ std::vector<double> sc(p,0.0);
2117
+ std::vector<int> ord(p,0);
2118
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2119
+ mean[ j ] = 0.0 ;
2120
+ } ;
2121
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2122
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2123
+ mean[ j ] = (mean[j]+x[((i*p)+j)]) ;
2124
+ } ;
2125
+ } ;
2126
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2127
+ mean[ j ] = (mean[j]/double(n)) ;
2128
+ } ;
2129
+ scm2cpp::blas_syrk(c, x, 1.0, 0.0, 1, p, n) ;
2130
+ for( int i = 0 ; !(i == p) ; i = (i+1) ) {
2131
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2132
+ c[ ((i*p)+j) ] = ((c[((i*p)+j)]-(double(n)*(mean[i]*mean[j])))/double((n-1))) ;
2133
+ } ;
2134
+ } ;
2135
+ sym_eigen(c,v,e,sc,p) ;
2136
+ eig_order(e,ord,p) ;
2137
+ for( int r = 0 ; !(r == p) ; r = (r+1) ) {
2138
+ int col = ord[r];
2139
+ double lam = ( ( e[col] < 0.0 ) ? (0.0) : (e[col]) );
2140
+ int big = 0;
2141
+ double bv = -1.0;
2142
+ ev[ r ] = lam ;
2143
+ sv[ r ] = sqrt((lam*double((n-1)))) ;
2144
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2145
+ double a = v[((j*p)+col)];
2146
+ double aa = ( ( a < 0.0 ) ? ((0.0-a)) : (a) );
2147
+ if( aa > bv ) {
2148
+ bv = aa ;
2149
+ big = j ;
2150
+ } else {
2151
+ 0 ;
2152
+ } ;
2153
+ ;
2154
+ ;
2155
+ } ;
2156
+ double sg = ( ( v[((big*p)+col)] < 0.0 ) ? (-1.0) : (1.0) );
2157
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2158
+ comps[ ((r*p)+j) ] = (sg*v[((j*p)+col)]) ;
2159
+ } ;
2160
+ ;
2161
+ ;
2162
+ ;
2163
+ } ;
2164
+ return 0 ;
2165
+ }
2166
+
2167
+
2168
+ SCM2CPP_FN inline int
2169
+ ard_pinvh( scm2cpp::span<double> a, scm2cpp::span<double> s, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int k )
2170
+ { sym_eigen(a,v,ev,e,k) ;
2171
+ double mx = 0.0;
2172
+ for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2173
+ double av = ( ( ev[r] < 0.0 ) ? ((0.0-ev[r])) : (ev[r]) );
2174
+ if( av > mx ) {
2175
+ mx = av ;
2176
+ } else {
2177
+ 0 ;
2178
+ } ;
2179
+ ;
2180
+ } ;
2181
+ double cut = (mx*(double(k)*2.220446049250313e-16));
2182
+ for( int i = 0 ; !(i == k) ; i = (i+1) ) {
2183
+ for( int j = 0 ; !(j == k) ; j = (j+1) ) {
2184
+ double acc = 0.0;
2185
+ for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2186
+ double er = ev[r];
2187
+ if( ( ( er < 0.0 ) ? ((0.0-er)) : (er) ) > cut ) {
2188
+ acc = (acc+((v[((i*k)+r)]*v[((j*k)+r)])/er)) ;
2189
+ } else {
2190
+ 0 ;
2191
+ } ;
2192
+ ;
2193
+ } ;
2194
+ s[ ((i*k)+j) ] = acc ;
2195
+ ;
2196
+ } ;
2197
+ } ;
2198
+ ;
2199
+ ;
2200
+ return 0 ;
2201
+ }
2202
+
2203
+
2204
+ SCM2CPP_FN inline int
2205
+ ard_sigma_coef( scm2cpp::cspan<double> xy, scm2cpp::cspan<int> idx, scm2cpp::cspan<double> lam, scm2cpp::span<double> coef, scm2cpp::span<double> sigma, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::cspan<double> gk, double alpha, int k )
2206
+ { for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2207
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2208
+ a[ ((r*k)+c) ] = (( ( r == c ) ? (lam[idx[r]]) : (0.0) )+(alpha*gk[((r*k)+c)])) ;
2209
+ } ;
2210
+ } ;
2211
+ ard_pinvh(a,sigma,v,ev,e,k) ;
2212
+ for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2213
+ double acc = 0.0;
2214
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2215
+ acc = (acc+(sigma[((r*k)+c)]*xy[idx[c]])) ;
2216
+ } ;
2217
+ coef[ idx[r] ] = (alpha*acc) ;
2218
+ ;
2219
+ } ;
2220
+ return 0 ;
2221
+ }
2222
+
2223
+
2224
+ inline int
2225
+ ard( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> sigma, scm2cpp::span<double> lam, scm2cpp::span<double> out, int maxiter, double tol, double alpha1, double alpha2, double lambda1, double lambda2, double thresh, int hoist, int n, int p )
2226
+ { std::vector<double> g(( ( hoist == 1 ) ? ((p*p)) : (1) ),0.0);
2227
+ std::vector<double> xy(p,0.0);
2228
+ std::vector<double> xk(( ( hoist == 1 ) ? (1) : ((n*p)) ),0.0);
2229
+ std::vector<double> gk((p*p),0.0);
2230
+ std::vector<double> a((p*p),0.0);
2231
+ std::vector<double> v((p*p),0.0);
2232
+ std::vector<double> ev(p,0.0);
2233
+ std::vector<double> e(p,0.0);
2234
+ std::vector<double> r(n,0.0);
2235
+ std::vector<int> idx(p,0);
2236
+ std::vector<int> keep(p,1);
2237
+ std::vector<double> old(p,0.0);
2238
+ double alpha = 0.0;
2239
+ int k = p;
2240
+ int it = 0;
2241
+ int done = 0;
2242
+ if( hoist == 1 ) {
2243
+ scm2cpp::blas_syrk(g, x, 1.0, 0.0, 1, p, n) ;
2244
+ } else {
2245
+ 0 ;
2246
+ } ;
2247
+ scm2cpp::blas_gemv(xy, x, y, 1.0, 0.0, 1, p, n) ;
2248
+ double ym = 0.0;
2249
+ double vy = 0.0;
2250
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2251
+ ym = (ym+y[i]) ;
2252
+ } ;
2253
+ ym = (ym/double(n)) ;
2254
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2255
+ vy = (vy+((y[i]-ym)*(y[i]-ym))) ;
2256
+ } ;
2257
+ alpha = (1.0/((vy/double(n))+2.220446049250313e-16)) ;
2258
+ ;
2259
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2260
+ lam[ j ] = 1.0 ;
2261
+ coef[ j ] = 0.0 ;
2262
+ } ;
2263
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
2264
+ k = 0 ;
2265
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2266
+ if( keep[j] == 1 ) {
2267
+ idx[ k ] = j ;
2268
+ k = (k+1) ;
2269
+ } else {
2270
+ 0 ;
2271
+ } ;
2272
+ } ;
2273
+ if( hoist == 1 ) {
2274
+ for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2275
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2276
+ gk[ ((r*k)+c) ] = g[((idx[r]*p)+idx[c])] ;
2277
+ } ;
2278
+ } ;
2279
+ } else {
2280
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2281
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2282
+ xk[ ((i*k)+c) ] = x[((i*p)+idx[c])] ;
2283
+ } ;
2284
+ } ;
2285
+ scm2cpp::blas_syrk(gk, xk, 1.0, 0.0, 1, k, n) ;
2286
+ } ;
2287
+ ard_sigma_coef(xy,idx,lam,coef,sigma,a,v,ev,e,gk,alpha,k) ;
2288
+ scm2cpp::blas_gemv(r, x, coef, 1.0, 0.0, 0, n, p) ;
2289
+ double sse = 0.0;
2290
+ double gsum = 0.0;
2291
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2292
+ double d = (y[i]-r[i]);
2293
+ sse = (sse+(d*d)) ;
2294
+ ;
2295
+ } ;
2296
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2297
+ int j = idx[c];
2298
+ double gm = (1.0-(lam[j]*sigma[((c*k)+c)]));
2299
+ gsum = (gsum+gm) ;
2300
+ lam[ j ] = ((gm+(2.0*lambda1))/((coef[j]*coef[j])+(2.0*lambda2))) ;
2301
+ ;
2302
+ ;
2303
+ } ;
2304
+ alpha = (((double(n)-gsum)+(2.0*alpha1))/(sse+(2.0*alpha2))) ;
2305
+ ;
2306
+ int nk = 0;
2307
+ double moved = 0.0;
2308
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2309
+ if( lam[j] < thresh ) {
2310
+ keep[ j ] = 1 ;
2311
+ nk = (nk+1) ;
2312
+ } else {
2313
+ keep[ j ] = 0 ;
2314
+ coef[ j ] = 0.0 ;
2315
+ } ;
2316
+ double dv = (old[j]-coef[j]);
2317
+ moved = (moved+( ( dv < 0.0 ) ? ((0.0-dv)) : (dv) )) ;
2318
+ ;
2319
+ } ;
2320
+ if( (it > 0 && moved < tol) ) {
2321
+ done = 1 ;
2322
+ } else {
2323
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2324
+ old[ j ] = coef[j] ;
2325
+ } ;
2326
+ if( nk == 0 ) {
2327
+ done = 1 ;
2328
+ } else {
2329
+ 0 ;
2330
+ } ;
2331
+ } ;
2332
+ ;
2333
+ it = (it+1) ;
2334
+ } ;
2335
+ k = 0 ;
2336
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2337
+ if( keep[j] == 1 ) {
2338
+ idx[ k ] = j ;
2339
+ k = (k+1) ;
2340
+ } else {
2341
+ 0 ;
2342
+ } ;
2343
+ } ;
2344
+ if( k > 0 ) {
2345
+ if( hoist == 1 ) {
2346
+ for( int r = 0 ; !(r == k) ; r = (r+1) ) {
2347
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2348
+ gk[ ((r*k)+c) ] = g[((idx[r]*p)+idx[c])] ;
2349
+ } ;
2350
+ } ;
2351
+ } else {
2352
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2353
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2354
+ xk[ ((i*k)+c) ] = x[((i*p)+idx[c])] ;
2355
+ } ;
2356
+ } ;
2357
+ scm2cpp::blas_syrk(gk, xk, 1.0, 0.0, 1, k, n) ;
2358
+ } ;
2359
+ ard_sigma_coef(xy,idx,lam,coef,sigma,a,v,ev,e,gk,alpha,k) ;
2360
+ } else {
2361
+ 0 ;
2362
+ } ;
2363
+ out[ 0 ] = alpha ;
2364
+ out[ 1 ] = double(k) ;
2365
+ return it ;
2366
+ }
2367
+
2368
+
2369
+ inline int
2370
+ f_regression( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> r, scm2cpp::span<double> f, int center, int n, int p, int q )
2371
+ { std::vector<double> mx(p,0.0);
2372
+ std::vector<double> sx(p,0.0);
2373
+ std::vector<double> yc((n*q),0.0);
2374
+ std::vector<double> yn(q,0.0);
2375
+ double dof = double((n-( ( center == 1 ) ? (2) : (1) )));
2376
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2377
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2378
+ double v = x[((i*p)+j)];
2379
+ mx[ j ] = (mx[j]+v) ;
2380
+ sx[ j ] = (sx[j]+(v*v)) ;
2381
+ ;
2382
+ } ;
2383
+ } ;
2384
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2385
+ mx[ j ] = (mx[j]/double(n)) ;
2386
+ } ;
2387
+ for( int t = 0 ; !(t == q) ; t = (t+1) ) {
2388
+ double m = 0.0;
2389
+ double s = 0.0;
2390
+ if( center == 1 ) {
2391
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2392
+ m = (m+y[((i*q)+t)]) ;
2393
+ } ;
2394
+ m = (m/double(n)) ;
2395
+ } else {
2396
+ 0 ;
2397
+ } ;
2398
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2399
+ double v = (y[((i*q)+t)]-m);
2400
+ yc[ ((i*q)+t) ] = v ;
2401
+ s = (s+(v*v)) ;
2402
+ ;
2403
+ } ;
2404
+ yn[ t ] = sqrt(s) ;
2405
+ ;
2406
+ } ;
2407
+ scm2cpp::blas_gemm(r, x, yc, 1.0, 0.0, 1, 0, p, q, n) ;
2408
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2409
+ double xn = sqrt(( ( center == 1 ) ? ((sx[j]-(double(n)*(mx[j]*mx[j])))) : (sx[j]) ));
2410
+ for( int t = 0 ; !(t == q) ; t = (t+1) ) {
2411
+ double rr = ((r[((j*q)+t)]/xn)/yn[t]);
2412
+ r[ ((j*q)+t) ] = rr ;
2413
+ f[ ((j*q)+t) ] = (((rr*rr)/(1.0-(rr*rr)))*dof) ;
2414
+ ;
2415
+ } ;
2416
+ ;
2417
+ } ;
2418
+ return 0 ;
2419
+ }
2420
+
2421
+
2422
+ inline int
2423
+ f_classif( scm2cpp::cspan<double> x, scm2cpp::cspan<int> lab, scm2cpp::span<double> f, int n, int p, int k )
2424
+ { std::vector<double> oh((n*k),0.0);
2425
+ std::vector<double> cs((k*p),0.0);
2426
+ std::vector<double> cnt(k,0.0);
2427
+ std::vector<double> ss(p,0.0);
2428
+ std::vector<double> tot(p,0.0);
2429
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2430
+ int c = lab[i];
2431
+ oh[ ((i*k)+c) ] = 1.0 ;
2432
+ cnt[ c ] = (cnt[c]+1.0) ;
2433
+ ;
2434
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2435
+ double v = x[((i*p)+j)];
2436
+ ss[ j ] = (ss[j]+(v*v)) ;
2437
+ ;
2438
+ } ;
2439
+ } ;
2440
+ scm2cpp::blas_gemm(cs, oh, x, 1.0, 0.0, 1, 0, k, p, n) ;
2441
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2442
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2443
+ tot[ j ] = (tot[j]+cs[((c*p)+j)]) ;
2444
+ } ;
2445
+ } ;
2446
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2447
+ double sq = ((tot[j]*tot[j])/double(n));
2448
+ double ssbn = 0.0;
2449
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2450
+ ssbn = (ssbn+((cs[((c*p)+j)]*cs[((c*p)+j)])/cnt[c])) ;
2451
+ } ;
2452
+ ssbn = (ssbn-sq) ;
2453
+ double sswn = ((ss[j]-sq)-ssbn);
2454
+ f[ j ] = ((ssbn/double((k-1)))/(sswn/double((n-k)))) ;
2455
+ ;
2456
+ ;
2457
+ } ;
2458
+ return 0 ;
2459
+ }
2460
+
2461
+
2462
+ SCM2CPP_FN inline double
2463
+ min_pos( scm2cpp::cspan<double> v, int m )
2464
+ { double r = 1.7976931348623157e+308;
2465
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
2466
+ double x = v[i];
2467
+ if( (x > 0.0 && x < r) ) {
2468
+ r = x ;
2469
+ } else {
2470
+ 0 ;
2471
+ } ;
2472
+ ;
2473
+ } ;
2474
+ return r ;
2475
+ }
2476
+
2477
+
2478
+ SCM2CPP_FN inline double
2479
+ round_even( double y )
2480
+ {
2481
+ double r = std::floor(y);
2482
+ double d = (y-r);
2483
+ if( d > 0.5 ) {
2484
+ return (r+1.0) ;
2485
+ }
2486
+ else {
2487
+ if( d < 0.5 ) {
2488
+ return r ;
2489
+ }
2490
+ else {
2491
+ if( (2.0*std::floor((0.5*r))) == r ) {
2492
+ return r ;
2493
+ }
2494
+ else {
2495
+ return (r+1.0) ;
2496
+ }
2497
+ }
2498
+ }
2499
+ }
2500
+
2501
+
2502
+ SCM2CPP_FN inline int
2503
+ cholesky_delete( scm2cpp::span<double> l, int go, int n, int k )
2504
+ { for( int i = go ; !(i >= (n-1)) ; i = (i+1) ) {
2505
+ for( int j = 0 ; !(j == (i+2)) ; j = (j+1) ) {
2506
+ l[ ((i*k)+j) ] = l[(((i+1)*k)+j)] ;
2507
+ } ;
2508
+ } ;
2509
+ for( int i = go ; !(i >= (n-1)) ; i = (i+1) ) {
2510
+ double a = l[((i*k)+i)];
2511
+ double b = l[((i*k)+(i+1))];
2512
+ double aa = ( ( a < 0.0 ) ? ((0.0-a)) : (a) );
2513
+ double ab = ( ( b < 0.0 ) ? ((0.0-b)) : (b) );
2514
+ double roe = ( ( aa > ab ) ? (a) : (b) );
2515
+ double scale = (aa+ab);
2516
+ double r = ( ( scale == 0.0 ) ? (0.0) : ((( ( roe < 0.0 ) ? (-1.0) : (1.0) )*(scale*sqrt((((a/scale)*(a/scale))+((b/scale)*(b/scale))))))) );
2517
+ double c = ( ( scale == 0.0 ) ? (1.0) : ((a/r)) );
2518
+ double s = ( ( scale == 0.0 ) ? (0.0) : ((b/r)) );
2519
+ double cc = ( ( r < 0.0 ) ? ((0.0-c)) : (c) );
2520
+ double ss = ( ( r < 0.0 ) ? ((0.0-s)) : (s) );
2521
+ l[ ((i*k)+i) ] = ( ( r < 0.0 ) ? ((0.0-r)) : (r) ) ;
2522
+ l[ ((i*k)+(i+1)) ] = 0.0 ;
2523
+ for( int t = (i+1) ; !(t >= n) ; t = (t+1) ) {
2524
+ double x = l[((t*k)+i)];
2525
+ double y = l[((t*k)+(i+1))];
2526
+ l[ ((t*k)+i) ] = ((cc*x)+(ss*y)) ;
2527
+ l[ ((t*k)+(i+1)) ] = ((cc*y)-(ss*x)) ;
2528
+ ;
2529
+ } ;
2530
+ ;
2531
+ ;
2532
+ ;
2533
+ ;
2534
+ ;
2535
+ ;
2536
+ } ;
2537
+ return 0 ;
2538
+ }
2539
+
2540
+
2541
+ SCM2CPP_FN inline int
2542
+ swap_rc( scm2cpp::span<double> g, int a, int b, int p )
2543
+ { for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2544
+ double rv = g[((a*p)+j)];
2545
+ g[ ((a*p)+j) ] = g[((b*p)+j)] ;
2546
+ g[ ((b*p)+j) ] = rv ;
2547
+ ;
2548
+ } ;
2549
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2550
+ double cv = g[((j*p)+a)];
2551
+ g[ ((j*p)+a) ] = g[((j*p)+b)] ;
2552
+ g[ ((j*p)+b) ] = cv ;
2553
+ ;
2554
+ } ;
2555
+ return 0 ;
2556
+ }
2557
+
2558
+
2559
+ inline int
2560
+ lars( scm2cpp::span<double> g, scm2cpp::cspan<double> cov, scm2cpp::span<double> coef, scm2cpp::span<double> path, scm2cpp::span<double> alphas, int rec, double nsamples, double alphamin, int method, int maxiter, double eps, int p )
2561
+ { std::vector<double> g0((p*p),0.0);
2562
+ std::vector<double> cov0(p,0.0);
2563
+ std::vector<double> cbuf(p,0.0);
2564
+ std::vector<int> index(p,0);
2565
+ std::vector<int> active(p,0);
2566
+ std::vector<double> sign(p,0.0);
2567
+ int kmax = ( ( maxiter < p ) ? (maxiter) : (p) );
2568
+ std::vector<double> prev(p,0.0);
2569
+ std::vector<double> dir(p,0.0);
2570
+ std::vector<double> ls(p,0.0);
2571
+ std::vector<double> zz(p,0.0);
2572
+ std::vector<double> ratio(p,0.0);
2573
+ std::vector<int> idx(p,0);
2574
+ std::vector<int> dropv(p,0);
2575
+ int cs = 0;
2576
+ int na = 0;
2577
+ int niter = 0;
2578
+ int drop = 0;
2579
+ int done = 0;
2580
+ double alpha = 0.0;
2581
+ double prevalpha = 0.0;
2582
+ double tiny32 = 1.1754943508222875e-38;
2583
+ double eqtol = 1.1920928955078125e-7;
2584
+ std::vector<double> l((kmax*kmax),0.0);
2585
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
2586
+ g0[ t ] = g[t] ;
2587
+ } ;
2588
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2589
+ cov0[ j ] = cov[j] ;
2590
+ cbuf[ j ] = cov[j] ;
2591
+ index[ j ] = j ;
2592
+ coef[ j ] = 0.0 ;
2593
+ if( rec == 1 ) {
2594
+ path[ j ] = 0.0 ;
2595
+ } else {
2596
+ 0 ;
2597
+ } ;
2598
+ } ;
2599
+ for( ; !(done == 1) ; ) {
2600
+ int clen = (p-cs);
2601
+ int cidx = 0;
2602
+ double cval = 0.0;
2603
+ double cabs = 0.0;
2604
+ for( int t = 0 ; !(t == clen) ; t = (t+1) ) {
2605
+ double v = cbuf[(cs+t)];
2606
+ double av = ( ( v < 0.0 ) ? ((0.0-v)) : (v) );
2607
+ if( av > cabs ) {
2608
+ cabs = av ;
2609
+ cidx = t ;
2610
+ cval = v ;
2611
+ } else {
2612
+ 0 ;
2613
+ } ;
2614
+ ;
2615
+ ;
2616
+ } ;
2617
+ alpha = (cabs/(1.0*nsamples)) ;
2618
+ if( rec == 1 ) {
2619
+ alphas[ niter ] = alpha ;
2620
+ } else {
2621
+ 0 ;
2622
+ } ;
2623
+ if( alpha <= (alphamin+eqtol) ) {
2624
+ if( ( ( (alpha-alphamin) < 0.0 ) ? ((alphamin-alpha)) : ((alpha-alphamin)) ) > eqtol ) {
2625
+ if( niter > 0 ) {
2626
+ double ss = ((prevalpha-alphamin)/(prevalpha-alpha));
2627
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2628
+ coef[ j ] = (prev[j]+(ss*(coef[j]-prev[j]))) ;
2629
+ } ;
2630
+ ;
2631
+ } else {
2632
+ 0 ;
2633
+ } ;
2634
+ alpha = alphamin ;
2635
+ if( rec == 1 ) {
2636
+ alphas[ niter ] = alphamin ;
2637
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2638
+ path[ ((niter*p)+j) ] = coef[j] ;
2639
+ } ;
2640
+ } else {
2641
+ 0 ;
2642
+ } ;
2643
+ } else {
2644
+ 0 ;
2645
+ } ;
2646
+ done = 1 ;
2647
+ } else {
2648
+ if( (niter >= maxiter || na >= p) ) {
2649
+ done = 1 ;
2650
+ } else {
2651
+ int degenerate = 0;
2652
+ if( drop == 0 ) {
2653
+ int m = na;
2654
+ int nn = (cidx+na);
2655
+ sign[ na ] = ( ( cval > 0.0 ) ? (1.0) : (( ( cval < 0.0 ) ? (-1.0) : (0.0) )) ) ;
2656
+ double tc = cbuf[(cs+cidx)];
2657
+ cbuf[ (cs+cidx) ] = cbuf[cs] ;
2658
+ cbuf[ cs ] = tc ;
2659
+ ;
2660
+ int ti = index[nn];
2661
+ index[ nn ] = index[m] ;
2662
+ index[ m ] = ti ;
2663
+ ;
2664
+ cs = (cs+1) ;
2665
+ swap_rc(g,m,nn,p) ;
2666
+ double c = g[((na*p)+na)];
2667
+ double v = 0.0;
2668
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2669
+ double t = g[((na*p)+i)];
2670
+ for( int s = 0 ; !(s == i) ; s = (s+1) ) {
2671
+ t = (t-(l[((i*kmax)+s)]*l[((na*kmax)+s)])) ;
2672
+ } ;
2673
+ double li = (t/l[((i*kmax)+i)]);
2674
+ l[ ((na*kmax)+i) ] = li ;
2675
+ v = (v+(li*li)) ;
2676
+ ;
2677
+ ;
2678
+ } ;
2679
+ double dd = sqrt(( ( (c-v) < 0.0 ) ? ((v-c)) : ((c-v)) ));
2680
+ double dg = ( ( dd > (1.0*eps) ) ? (dd) : ((1.0*eps)) );
2681
+ l[ ((na*kmax)+na) ] = dg ;
2682
+ if( dg < 1e-7 ) {
2683
+ cs = (cs-1) ;
2684
+ cbuf[ cs ] = 0.0 ;
2685
+ double tc = cbuf[(cs+cidx)];
2686
+ cbuf[ (cs+cidx) ] = cbuf[cs] ;
2687
+ cbuf[ cs ] = tc ;
2688
+ ;
2689
+ degenerate = 1 ;
2690
+ } else {
2691
+ active[ na ] = index[na] ;
2692
+ na = (na+1) ;
2693
+ } ;
2694
+ ;
2695
+ ;
2696
+ ;
2697
+ ;
2698
+ } else {
2699
+ false ;
2700
+ } ;
2701
+ if( degenerate == 0 ) {
2702
+ if( (method == 1 && niter > 0 && prevalpha < alpha) ) {
2703
+ done = 1 ;
2704
+ } else {
2705
+ double aa = 0.0;
2706
+ int clen2 = (p-cs);
2707
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2708
+ double t = sign[i];
2709
+ for( int s = 0 ; !(s == i) ; s = (s+1) ) {
2710
+ t = (t-(l[((i*kmax)+s)]*zz[s])) ;
2711
+ } ;
2712
+ zz[ i ] = (t/l[((i*kmax)+i)]) ;
2713
+ ;
2714
+ } ;
2715
+ for( int ii = 0 ; !(ii == na) ; ii = (ii+1) ) {
2716
+ int i = ((na-1)-ii);
2717
+ double t = zz[i];
2718
+ for( int s = (i+1) ; !(s >= na) ; s = (s+1) ) {
2719
+ t = (t-(l[((s*kmax)+i)]*ls[s])) ;
2720
+ } ;
2721
+ ls[ i ] = (t/l[((i*kmax)+i)]) ;
2722
+ ;
2723
+ ;
2724
+ } ;
2725
+ if( (na == 1 && ls[0] == 0.0) ) {
2726
+ ls[ 0 ] = 1.0 ;
2727
+ aa = 1.0 ;
2728
+ } else {
2729
+ double sm = 0.0;
2730
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2731
+ sm = (sm+(ls[i]*sign[i])) ;
2732
+ } ;
2733
+ aa = (1.0/sqrt(sm)) ;
2734
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2735
+ ls[ i ] = (aa*ls[i]) ;
2736
+ } ;
2737
+ ;
2738
+ } ;
2739
+ for( int t = 0 ; !(t == clen2) ; t = (t+1) ) {
2740
+ double acc = 0.0;
2741
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2742
+ acc = (acc+(g[((i*p)+(na+t))]*ls[i])) ;
2743
+ } ;
2744
+ dir[ t ] = (round_even(double((acc*1e+15)))/1e+15) ;
2745
+ ;
2746
+ } ;
2747
+ for( int t = 0 ; !(t == clen2) ; t = (t+1) ) {
2748
+ ratio[ t ] = ((cabs-cbuf[(cs+t)])/((aa-dir[t])+tiny32)) ;
2749
+ } ;
2750
+ double gfirst = min_pos(ratio,clen2);
2751
+ for( int t = 0 ; !(t == clen2) ; t = (t+1) ) {
2752
+ ratio[ t ] = ((cabs+cbuf[(cs+t)])/((aa+dir[t])+tiny32)) ;
2753
+ } ;
2754
+ double gsecond = min_pos(ratio,clen2);
2755
+ double gam = ( ( ( ( gfirst < gsecond ) ? (gfirst) : (gsecond) ) < (cabs/aa) ) ? (( ( gfirst < gsecond ) ? (gfirst) : (gsecond) )) : ((cabs/aa)) );
2756
+ int nidx = 0;
2757
+ drop = 0 ;
2758
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2759
+ zz[ i ] = ((0.0-coef[active[i]])/(ls[i]+tiny32)) ;
2760
+ } ;
2761
+ double zpos = min_pos(zz,na);
2762
+ if( zpos < gam ) {
2763
+ for( int ii = 0 ; !(ii == na) ; ii = (ii+1) ) {
2764
+ int i = ((na-1)-ii);
2765
+ if( zz[i] == zpos ) {
2766
+ idx[ nidx ] = i ;
2767
+ nidx = (nidx+1) ;
2768
+ } else {
2769
+ 0 ;
2770
+ } ;
2771
+ ;
2772
+ } ;
2773
+ for( int r = 0 ; !(r == nidx) ; r = (r+1) ) {
2774
+ int i = idx[r];
2775
+ sign[ i ] = (0.0-sign[i]) ;
2776
+ ;
2777
+ } ;
2778
+ if( method == 1 ) {
2779
+ gam = zpos ;
2780
+ } else {
2781
+ 0 ;
2782
+ } ;
2783
+ drop = 1 ;
2784
+ } else {
2785
+ 0 ;
2786
+ } ;
2787
+ ;
2788
+ niter = (niter+1) ;
2789
+ prevalpha = alpha ;
2790
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2791
+ prev[ j ] = coef[j] ;
2792
+ coef[ j ] = 0.0 ;
2793
+ } ;
2794
+ for( int i = 0 ; !(i == na) ; i = (i+1) ) {
2795
+ int a = active[i];
2796
+ coef[ a ] = (prev[a]+(gam*ls[i])) ;
2797
+ ;
2798
+ } ;
2799
+ if( rec == 1 ) {
2800
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2801
+ path[ ((niter*p)+j) ] = coef[j] ;
2802
+ } ;
2803
+ } else {
2804
+ 0 ;
2805
+ } ;
2806
+ for( int t = 0 ; !(t == clen2) ; t = (t+1) ) {
2807
+ cbuf[ (cs+t) ] = (cbuf[(cs+t)]-(gam*dir[t])) ;
2808
+ } ;
2809
+ if( (drop == 1 && method == 1) ) {
2810
+ for( int r = 0 ; !(r == nidx) ; r = (r+1) ) {
2811
+ cholesky_delete(l,idx[r],na,kmax) ;
2812
+ } ;
2813
+ na = (na-1) ;
2814
+ for( int r = 0 ; !(r == nidx) ; r = (r+1) ) {
2815
+ int ii = idx[r];
2816
+ int dropped = active[ii];
2817
+ for( int i = ii ; !(i >= na) ; i = (i+1) ) {
2818
+ active[ i ] = active[(i+1)] ;
2819
+ } ;
2820
+ dropv[ r ] = dropped ;
2821
+ ;
2822
+ ;
2823
+ } ;
2824
+ for( int r = 0 ; !(r == nidx) ; r = (r+1) ) {
2825
+ int ii = idx[r];
2826
+ for( int i = ii ; !(i >= na) ; i = (i+1) ) {
2827
+ int ti = index[i];
2828
+ index[ i ] = index[(i+1)] ;
2829
+ index[ (i+1) ] = ti ;
2830
+ ;
2831
+ swap_rc(g,i,int((i+1)),p) ;
2832
+ } ;
2833
+ ;
2834
+ } ;
2835
+ for( int rr = 0 ; !(rr == nidx) ; rr = (rr+1) ) {
2836
+ int r = ((nidx-1)-rr);
2837
+ int d = dropv[r];
2838
+ double t = cov0[d];
2839
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2840
+ t = (t-(g0[((d*p)+j)]*coef[j])) ;
2841
+ } ;
2842
+ cs = (cs-1) ;
2843
+ cbuf[ cs ] = t ;
2844
+ ;
2845
+ ;
2846
+ ;
2847
+ } ;
2848
+ for( int r = 0 ; !(r == nidx) ; r = (r+1) ) {
2849
+ int ii = idx[r];
2850
+ for( int i = ii ; !(i >= (p-1)) ; i = (i+1) ) {
2851
+ sign[ i ] = sign[(i+1)] ;
2852
+ } ;
2853
+ sign[ (p-1) ] = 0.0 ;
2854
+ ;
2855
+ } ;
2856
+ } else {
2857
+ 0 ;
2858
+ } ;
2859
+ ;
2860
+ ;
2861
+ ;
2862
+ ;
2863
+ } ;
2864
+ } else {
2865
+ 0 ;
2866
+ } ;
2867
+ ;
2868
+ } ;
2869
+ } ;
2870
+ ;
2871
+ } ;
2872
+ ;
2873
+ return niter ;
2874
+ }
2875
+
2876
+
2877
+ SCM2CPP_FN inline int
2878
+ rfe_chol( scm2cpp::cspan<double> g, scm2cpp::cspan<int> idx, scm2cpp::span<double> l, double alpha, int k, int p )
2879
+ { for( int j = 0 ; !(j == k) ; j = (j+1) ) {
2880
+ double s = (g[((idx[j]*p)+idx[j])]+alpha);
2881
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
2882
+ s = (s-(l[((j*p)+m)]*l[((j*p)+m)])) ;
2883
+ } ;
2884
+ l[ ((j*p)+j) ] = sqrt(s) ;
2885
+ for( int i = (j+1) ; !(i >= k) ; i = (i+1) ) {
2886
+ double t = g[((idx[i]*p)+idx[j])];
2887
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
2888
+ t = (t-(l[((i*p)+m)]*l[((j*p)+m)])) ;
2889
+ } ;
2890
+ l[ ((i*p)+j) ] = (t/l[((j*p)+j)]) ;
2891
+ ;
2892
+ } ;
2893
+ ;
2894
+ } ;
2895
+ return 0 ;
2896
+ }
2897
+
2898
+
2899
+ SCM2CPP_FN inline int
2900
+ rfe_solve( scm2cpp::cspan<double> c, scm2cpp::cspan<int> idx, scm2cpp::span<double> w, scm2cpp::cspan<double> l, int k, int p )
2901
+ { for( int i = 0 ; !(i == k) ; i = (i+1) ) {
2902
+ double t = c[idx[i]];
2903
+ for( int m = 0 ; !(m == i) ; m = (m+1) ) {
2904
+ t = (t-(l[((i*p)+m)]*w[m])) ;
2905
+ } ;
2906
+ w[ i ] = (t/l[((i*p)+i)]) ;
2907
+ ;
2908
+ } ;
2909
+ for( int ii = 0 ; !(ii == k) ; ii = (ii+1) ) {
2910
+ int i = ((k-1)-ii);
2911
+ double t = w[i];
2912
+ for( int m = (i+1) ; !(m >= k) ; m = (m+1) ) {
2913
+ t = (t-(l[((m*p)+i)]*w[m])) ;
2914
+ } ;
2915
+ w[ i ] = (t/l[((i*p)+i)]) ;
2916
+ ;
2917
+ ;
2918
+ } ;
2919
+ return 0 ;
2920
+ }
2921
+
2922
+
2923
+ inline int
2924
+ rfe( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<int> support, scm2cpp::span<int> ranking, double alpha, int nsel, int step, int n, int p )
2925
+ { std::vector<double> xc((n*p),0.0);
2926
+ std::vector<double> yc(n,0.0);
2927
+ std::vector<double> mx(p,0.0);
2928
+ std::vector<double> g((p*p),0.0);
2929
+ std::vector<double> c(p,0.0);
2930
+ std::vector<double> l((p*p),0.0);
2931
+ std::vector<double> w(p,0.0);
2932
+ std::vector<int> idx(p,0);
2933
+ std::vector<int> ord(p,0);
2934
+ std::vector<int> gone(p,0);
2935
+ double ym = 0.0;
2936
+ int rounds = 0;
2937
+ int k = p;
2938
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2939
+ ym = (ym+y[i]) ;
2940
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2941
+ mx[ j ] = (mx[j]+x[((i*p)+j)]) ;
2942
+ } ;
2943
+ } ;
2944
+ ym = (ym/double(n)) ;
2945
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2946
+ mx[ j ] = (mx[j]/double(n)) ;
2947
+ } ;
2948
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2949
+ yc[ i ] = (y[i]-ym) ;
2950
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2951
+ xc[ ((i*p)+j) ] = (x[((i*p)+j)]-mx[j]) ;
2952
+ } ;
2953
+ } ;
2954
+ scm2cpp::blas_syrk(g, xc, 1.0, 0.0, 1, p, n) ;
2955
+ scm2cpp::blas_gemv(c, xc, yc, 1.0, 0.0, 1, p, n) ;
2956
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2957
+ support[ j ] = 1 ;
2958
+ ranking[ j ] = 1 ;
2959
+ idx[ j ] = j ;
2960
+ } ;
2961
+ rfe_chol(g,idx,l,alpha,p,p) ;
2962
+ for( ; !(k <= nsel) ; ) {
2963
+ rfe_solve(c,idx,w,l,k,p) ;
2964
+ for( int i = 0 ; !(i == k) ; i = (i+1) ) {
2965
+ double key = (w[i]*w[i]);
2966
+ int jj = (i-1);
2967
+ for( ; !((jj < 0 || (w[ord[jj]]*w[ord[jj]]) <= key)) ; ) {
2968
+ ord[ (jj+1) ] = ord[jj] ;
2969
+ jj = (jj-1) ;
2970
+ } ;
2971
+ ord[ (jj+1) ] = i ;
2972
+ ;
2973
+ } ;
2974
+ int thr = ( ( step < (k-nsel) ) ? (step) : ((k-nsel)) );
2975
+ for( int r = 0 ; !(r == thr) ; r = (r+1) ) {
2976
+ support[ idx[ord[r]] ] = 0 ;
2977
+ } ;
2978
+ for( int t = 0 ; !(t == k) ; t = (t+1) ) {
2979
+ gone[ t ] = 0 ;
2980
+ } ;
2981
+ for( int r = 0 ; !(r == thr) ; r = (r+1) ) {
2982
+ gone[ ord[r] ] = 1 ;
2983
+ } ;
2984
+ int cur = k;
2985
+ for( int tt = 0 ; !(tt == k) ; tt = (tt+1) ) {
2986
+ int pos = ((k-1)-tt);
2987
+ if( gone[pos] == 1 ) {
2988
+ cholesky_delete(l,pos,cur,p) ;
2989
+ for( int u = pos ; !(u >= (cur-1)) ; u = (u+1) ) {
2990
+ idx[ u ] = idx[(u+1)] ;
2991
+ } ;
2992
+ cur = (cur-1) ;
2993
+ } else {
2994
+ 0 ;
2995
+ } ;
2996
+ ;
2997
+ } ;
2998
+ ;
2999
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
3000
+ if( support[j] == 0 ) {
3001
+ ranking[ j ] = (ranking[j]+1) ;
3002
+ } else {
3003
+ 0 ;
3004
+ } ;
3005
+ } ;
3006
+ k = (k-thr) ;
3007
+ rounds = (rounds+1) ;
3008
+ ;
3009
+ } ;
3010
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
3011
+ coef[ j ] = 0.0 ;
3012
+ } ;
3013
+ rfe_solve(c,idx,w,l,k,p) ;
3014
+ for( int i = 0 ; !(i == k) ; i = (i+1) ) {
3015
+ coef[ idx[i] ] = w[i] ;
3016
+ } ;
3017
+ return rounds ;
3018
+ }
3019
+
3020
+
3021
+ SCM2CPP_FN inline int
3022
+ gram_xx( scm2cpp::cspan<double> x, scm2cpp::span<double> g, int n, int p )
3023
+ { scm2cpp::blas_syrk(g, x, 1.0, 0.0, 1, p, n) ;
3024
+ return 0 ;
3025
+ }
3026
+
3027
+
3028
+ SCM2CPP_FN inline int
3029
+ gram_xy( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> c, int n, int p, int q )
3030
+ { scm2cpp::blas_gemm(c, x, y, 1.0, 0.0, 1, 0, p, q, n) ;
3031
+ return 0 ;
3032
+ }
3033
+ #endif // GRAMOPS_HPP