├── glmnet ├── __init__.py ├── example_lasso_elastic_net.py ├── elastic_net.py ├── glmnet.py └── glmnet.pyf ├── .gitignore ├── setup.py ├── README.rst └── LICENSE /glmnet/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pyc 3 | 4 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from numpy.distutils.misc_util import Configuration 2 | from numpy.distutils.system_info import get_info 3 | import os, sys 4 | 5 | import sys 6 | 7 | fflags= '-fdefault-real-8 -ffixed-form' 8 | 9 | # TODO: Fix it so that these flags are default. 10 | 11 | config = Configuration( 12 | 'glmnet', 13 | parent_package=None, 14 | top_path=None 15 | ) 16 | 17 | f_sources = ['glmnet/glmnet.pyf','glmnet/glmnet.f'] 18 | 19 | config.add_extension(name='_glmnet',sources=f_sources) 20 | config_dict = config.todict() 21 | if __name__ == '__main__': 22 | from numpy.distutils.core import setup 23 | setup(version='1.1-5', 24 | description='Python wrappers for the GLMNET package', 25 | author='David Warde-Farley', 26 | author_email='dwf@cs.toronto.edu', 27 | url='github.com/dwf/glmnet-python', 28 | license='GPL2', 29 | requires=['NumPy (>= 1.3)'], 30 | packages=['glmnet'], 31 | **config_dict) 32 | 33 | -------------------------------------------------------------------------------- /glmnet/example_lasso_elastic_net.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from elastic_net import ElasticNet, Lasso, elastic_net_path, lasso_path 3 | 4 | # ====================== 5 | # = Run Lasso and Enet = 6 | # ====================== 7 | X = np.random.randn(50, 200) 8 | w = 3*np.random.randn(200) 9 | w[10:] = 0 10 | y = np.dot(X, w) 11 | enet = ElasticNet(alpha=0.1) 12 | y_pred = enet.fit(X, y).predict(X) 13 | print enet 14 | 15 | # ===================== 16 | # = Compute full path = 17 | # ===================== 18 | 19 | alphas_enet, coefs_enet, intercepts_enet = elastic_net_path(X, y, 0.2) 20 | alphas_lasso, coefs_lasso, intercepts_lasso = lasso_path(X, y) 21 | 22 | # ============== 23 | # = show paths = 24 | # ============== 25 | from itertools import cycle 26 | import pylab as pl 27 | pl.close('all') 28 | 29 | color_iter = cycle(['b', 'g', 'r', 'c', 'm', 'y', 'k']) 30 | for color, coef_lasso, coef_enet in zip(color_iter, 31 | coefs_lasso, coefs_enet): 32 | pl.plot(-np.log(alphas_lasso[1:]), coef_lasso[1:], color) 33 | pl.plot(-np.log(alphas_enet[1:]), coef_enet[1:], color+'x') 34 | 35 | pl.xlabel('-log(lambda)') 36 | pl.ylabel('coefs') 37 | pl.title('Lasso and Elastic-Net Paths') 38 | pl.legend(['Lasso','Elastic-Net']) 39 | pl.show() 40 | 41 | -------------------------------------------------------------------------------- /glmnet/elastic_net.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from glmnet import elastic_net 3 | 4 | class ElasticNet(object): 5 | """ElasticNet based on GLMNET""" 6 | def __init__(self, alpha, rho=0.2): 7 | super(ElasticNet, self).__init__() 8 | self.alpha = alpha 9 | self.rho = rho 10 | self.coef_ = None 11 | self.rsquared_ = None 12 | 13 | def fit(self, X, y): 14 | n_lambdas, intercept_, coef_, _, _, rsquared_, lambdas, _, jerr \ 15 | = elastic_net(X, y, self.rho, lambdas=[self.alpha]) 16 | # elastic_net will fire exception instead 17 | # assert jerr == 0 18 | self.coef_ = coef_ 19 | self.intercept_ = intercept_ 20 | self.rsquared_ = rsquared_ 21 | return self 22 | 23 | def predict(self, X): 24 | return np.dot(X, self.coef_) + self.intercept_ 25 | 26 | def __str__(self): 27 | n_non_zeros = (np.abs(self.coef_) != 0).sum() 28 | return ("%s with %d non-zero coefficients (%.2f%%)\n" + \ 29 | " * Intercept = %.7f, Lambda = %.7f\n" + \ 30 | " * Training r^2: %.4f") % \ 31 | (self.__class__.__name__, n_non_zeros, 32 | n_non_zeros / float(len(self.coef_)) * 100, 33 | self.intercept_[0], self.alpha, self.rsquared_[0]) 34 | 35 | 36 | def elastic_net_path(X, y, rho, **kwargs): 37 | """return full path for ElasticNet""" 38 | n_lambdas, intercepts, coefs, _, _, _, lambdas, _, jerr \ 39 | = elastic_net(X, y, rho, **kwargs) 40 | return lambdas, coefs, intercepts 41 | 42 | def Lasso(alpha): 43 | """Lasso based on GLMNET""" 44 | return ElasticNet(alpha, rho=1.0) 45 | 46 | def lasso_path(X, y, **kwargs): 47 | """return full path for Lasso""" 48 | return elastic_net_path(X, y, rho=1.0, **kwargs) 49 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | glmnet wrappers for Python 2 | ========================== 3 | 4 | Very much a work in progress. 5 | 6 | Building 7 | -------- 8 | 9 | In order to get double precision working without modifying Friedman's code, 10 | some compiler trickery is required. The wrappers have been written such that 11 | everything returned is expected to be a ``real*8`` i.e. a double-precision 12 | floating point number, and unfortunately the code is written in a way 13 | Fortran is often written with simply ``real`` specified, letting the compiler 14 | decide on the appropriate width. ``f2py`` assumes ``real`` are always 4 byte/ 15 | single precision, hence the manual change in the wrappers to ``real*8``, but 16 | that change requires the actual Fortran code to be compiled with 8-byte reals, 17 | otherwise bad things will happen (the stack will be blown, program will hang 18 | or segfault, etc.). 19 | 20 | AFAIK, this package requires ``gfortran`` to build. ``g77`` will not work as 21 | it does not support ``-fdefault-real-8``. 22 | 23 | The way to get this to build properly is: 24 | 25 | :: 26 | 27 | python setup.py config_fc --fcompiler=gnu95 \ 28 | --f77flags='-fdefault-real-8' \ 29 | --f90flags='-fdefault-real-8' build 30 | 31 | The ``--fcompiler=gnu95`` business may be omitted if gfortran is the only 32 | Fortran compiler you have installed, but the compiler flags are essential. 33 | 34 | License 35 | ------- 36 | 37 | Friedman's code in ``glmnet.f`` is released under the GPLv2, necessitating that 38 | any code that uses it (including my wrapper, and anyone using my wrapper) 39 | be released under the GPLv2 as well. See LICENSE for details. 40 | 41 | That said, to the extent that they are useful in the absence of the GPL Fortran 42 | code (i.e. not very), my portions may be used under the 3-clause BSD license. 43 | 44 | Thanks 45 | ------ 46 | 47 | * To Jerome Friedman for the fantastically fast and efficient Fortran code. 48 | * To Pearu Peterson for writing ``f2py`` and answering my dumb questions. 49 | * To Dag Sverre Seljebotn for his help with ``f2py`` wrangling. 50 | * To Kevin Jacobs for showing me `his wrapper `_ 51 | which helped me side-step some problems with the auto-generated ``.pyf``. 52 | -------------------------------------------------------------------------------- /glmnet/glmnet.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import _glmnet 3 | 4 | _DEFAULT_THRESH = 1.0e-4 5 | _DEFAULT_FLMIN = 0.001 6 | _DEFAULT_NLAM = 100 7 | 8 | def elastic_net(predictors, target, balance, memlimit=None, 9 | largest=None, **kwargs): 10 | """ 11 | Raw-output wrapper for elastic net linear regression. 12 | """ 13 | 14 | # Mandatory parameters 15 | predictors = np.asanyarray(predictors) 16 | target = np.asanyarray(target) 17 | 18 | # Decide on largest allowable models for memory/convergence. 19 | memlimit = predictors.shape[1] if memlimit is None else memlimit 20 | 21 | # If largest isn't specified use memlimit. 22 | largest = memlimit if largest is None else largest 23 | 24 | if memlimit < largest: 25 | raise ValueError('Need largest <= memlimit') 26 | 27 | # Flags determining overwrite behavior 28 | overwrite_pred_ok = False 29 | overwrite_targ_ok = False 30 | 31 | thr = _DEFAULT_THRESH # Minimum change in largest coefficient 32 | weights = None # Relative weighting per observation case 33 | vp = None # Relative penalties per predictor (0 = no penalty) 34 | isd = True # Standardize input variables before proceeding? 35 | jd = np.zeros(1) # Predictors to exclude altogether from fitting 36 | ulam = None # User-specified lambda values 37 | flmin = _DEFAULT_FLMIN # Fraction of largest lambda at which to stop 38 | nlam = _DEFAULT_NLAM # The (maximum) number of lambdas to try. 39 | 40 | for keyword in kwargs: 41 | if keyword == 'overwrite_pred_ok': 42 | overwrite_pred_ok = kwargs[keyword] 43 | elif keyword == 'overwrite_targ_ok': 44 | overwrite_targ_ok = kwargs[keyword] 45 | elif keyword == 'threshold': 46 | thr = kwargs[keyword] 47 | elif keyword == 'weights': 48 | weights = np.asarray(kwargs[keyword]).copy() 49 | elif keyword == 'penalties': 50 | vp = kwargs[keyword].copy() 51 | elif keyword == 'standardize': 52 | isd = bool(kwargs[keyword]) 53 | elif keyword == 'exclude': 54 | # Add one since Fortran indices start at 1 55 | exclude = (np.asarray(kwargs[keyword]) + 1).tolist() 56 | jd = np.array([len(exclude)] + exclude) 57 | elif keyword == 'lambdas': 58 | if 'flmin' in kwargs: 59 | raise ValueError("Can't specify both lambdas & flmin keywords") 60 | ulam = np.asarray(kwargs[keyword]) 61 | flmin = 2. # Pass flmin > 1.0 indicating to use the user-supplied. 62 | nlam = len(ulam) 63 | elif keyword == 'flmin': 64 | flmin = kwargs[keyword] 65 | ulam = None 66 | elif keyword == 'nlam': 67 | if 'lambdas' in kwargs: 68 | raise ValueError("Can't specify both lambdas & nlam keywords") 69 | nlam = kwargs[keyword] 70 | else: 71 | raise ValueError("Unknown keyword argument '%s'" % keyword) 72 | 73 | # If predictors is a Fortran contiguous array, it will be overwritten. 74 | # Decide whether we want this. If it's not Fortran contiguous it will 75 | # be copied into that form anyway so there's no chance of overwriting. 76 | if np.isfortran(predictors): 77 | if not overwrite_pred_ok: 78 | # Might as well make it F-ordered to avoid ANOTHER copy. 79 | predictors = predictors.copy(order='F') 80 | 81 | # target being a 1-dimensional array will usually be overwritten 82 | # with the standardized version unless we take steps to copy it. 83 | if not overwrite_targ_ok: 84 | target = target.copy() 85 | 86 | # Uniform weighting if no weights are specified. 87 | if weights is None: 88 | weights = np.ones(predictors.shape[0]) 89 | 90 | # Uniform penalties if none were specified. 91 | if vp is None: 92 | vp = np.ones(predictors.shape[1]) 93 | 94 | # Call the Fortran wrapper. 95 | lmu, a0, ca, ia, nin, rsq, alm, nlp, jerr = \ 96 | _glmnet.elnet(balance, predictors, target, weights, jd, vp, 97 | memlimit, flmin, ulam, thr, nlam=nlam) 98 | 99 | # Check for errors, documented in glmnet.f. 100 | if jerr != 0: 101 | if jerr == 10000: 102 | raise ValueError('cannot have max(vp) < 0.0') 103 | elif jerr == 7777: 104 | raise ValueError('all used predictors have 0 variance') 105 | elif jerr < 7777: 106 | raise MemoryError('elnet() returned error code %d' % jerr) 107 | else: 108 | raise Exception('unknown error: %d' % jerr) 109 | 110 | return lmu, a0, ca, ia, nin, rsq, alm, nlp, jerr 111 | 112 | class GlmnetLinearModel(object): 113 | """Class representing a linear model trained by Glmnet.""" 114 | def __init__(self, a0, ca, ia, nin, rsq, alm, npred): 115 | self._intercept = a0 116 | self._coefficients = ca[:nin] 117 | self._indices = ia[:nin] - 1 118 | self._rsquared = rsq 119 | self._lambda = alm 120 | self._npred = npred 121 | 122 | def __str__(self): 123 | return ("%s with %d non-zero coefficients (%.2f%%)\n" + \ 124 | " * Intercept = %.7f, Lambda = %.7f\n" + \ 125 | " * Training r^2: %.4f") % \ 126 | (self.__class__.__name__, len(self._coefficients), 127 | len(self._coefficients) / float(self._npred) * 100, 128 | self._intercept, self._lambda, self._rsquared) 129 | 130 | def predict(self, predictors): 131 | predictors = np.atleast_2d(np.asarray(predictors)) 132 | return self._intercept + \ 133 | np.dot(predictors[:,self._indices], self._coefficients) 134 | 135 | @property 136 | def coefficients(self): 137 | coeffs = np.zeros(self._npred) 138 | coeffs[self._indices] = self._coefficients 139 | return coeffs 140 | 141 | 142 | 143 | class GlmnetLinearResults(object): 144 | def __init__(self, lmu, a0, ca, ia, nin, rsq, alm, nlp, npred, parm): 145 | self._lmu = lmu 146 | self._a0 = a0 147 | self._ca = ca 148 | self._ia = ia 149 | self._nin = nin 150 | self._rsq = rsq 151 | self._alm = alm 152 | self._nlp = nlp 153 | self._npred = npred 154 | self._model_objects = {} 155 | self._parm = parm 156 | 157 | def __str__(self): 158 | ninp = np.argmax(self._nin) 159 | return ("%s object, elastic net parameter = %.3f\n" + \ 160 | " * %d values of lambda\n" + \ 161 | " * computed in %d passes over data\n" + \ 162 | " * largest model: %d predictors (%.1f%%), train r^2 = %.4f") % \ 163 | (self.__class__.__name__, self._parm, self._lmu, self._nlp, 164 | self._nin[ninp], self._nin[ninp] / float(self._npred) * 100, 165 | self._rsq[ninp]) 166 | 167 | def __len__(self): 168 | return self._lmu 169 | 170 | def __getitem__(self, item): 171 | item = (item + self._lmu) if item < 0 else item 172 | if item >= self._lmu or item < 0: 173 | raise IndexError("model index out of bounds") 174 | 175 | if item not in self._model_objects: 176 | model = GlmnetLinearModel( 177 | self._a0[item], 178 | self._ca[:,item], 179 | self._ia, 180 | self._nin[item], 181 | self._rsq[item], 182 | self._alm[item], 183 | self._npred 184 | ) 185 | self._model_objects[item] = model 186 | 187 | else: 188 | model = self._model_objects[item] 189 | 190 | return model 191 | 192 | @property 193 | def nummodels(self): 194 | return self._lmu 195 | 196 | @property 197 | def coefficients(self): 198 | return self._ca[:np.max(self._nin), :self._lmu] 199 | 200 | @property 201 | def indices(self): 202 | return self._ia 203 | 204 | @property 205 | def lambdas(self): 206 | return self._alm[:self._lmu] 207 | 208 | @property 209 | def balance(self): 210 | return self._parm 211 | 212 | def plot_paths(results, which_to_label=None): 213 | import matplotlib 214 | import matplotlib.pyplot as plt 215 | plt.clf() 216 | interactive_state = plt.isinteractive() 217 | xvalues = -np.log(results.lambdas[1:]) 218 | for index, path in enumerate(results.coefficients): 219 | if which_to_label and results.indices[index] in which_to_label: 220 | if which_to_label[results.indices[index]] is None: 221 | label = "$x_{%d}$" % results.indices[index] 222 | else: 223 | label = which_to_label[results.indices[index]] 224 | else: 225 | label = None 226 | 227 | 228 | if which_to_label and label is None: 229 | plt.plot(xvalues, path[1:], ':') 230 | else: 231 | plt.plot(xvalues, path[1:], label=label) 232 | 233 | plt.xlim(np.amin(xvalues), np.amax(xvalues)) 234 | 235 | if which_to_label is not None: 236 | plt.legend(loc='upper left') 237 | plt.title('Regularization paths ($\\rho$ = %.2f)' % results.balance) 238 | plt.xlabel('$-\log(\lambda)$') 239 | plt.ylabel('Value of regression coefficient $\hat{\\beta}_i$') 240 | plt.show() 241 | plt.interactive(interactive_state) 242 | -------------------------------------------------------------------------------- /glmnet/glmnet.pyf: -------------------------------------------------------------------------------- 1 | ! -*- f90 -*- 2 | ! Note: the context of this file is case sensitive. 3 | 4 | python module _glmnet ! in 5 | interface ! in :_glmnet 6 | subroutine elnet(ka,parm,no,ni,x,y,w,jd,vp,ne,nx,nlam,flmin,ulam,thr,isd,lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) ! in :glmnet:glmnet.f 7 | integer optional :: ka=1 ! Use covariance updates over naive by default 8 | real*8 :: parm 9 | integer intent(hide),check(shape(x,0)==no),depend(x) :: no=shape(x,0) 10 | integer intent(hide),check(shape(x,1)==ni),depend(x) :: ni=shape(x,1) 11 | real*8 dimension(no,ni) :: x 12 | real*8 dimension(no),depend(no) :: y 13 | real*8 dimension(no),depend(no) :: w 14 | integer dimension(*) :: jd 15 | real*8 dimension(ni),depend(ni) :: vp 16 | integer optional,depend(x) :: ne=min(shape(x,1), nx) 17 | integer :: nx 18 | integer optional,check((flmin < 1.0 || len(ulam)==nlam)),depend(flmin,ulam) :: nlam=len(ulam) 19 | real*8 :: flmin 20 | real*8 dimension(nlam) :: ulam 21 | real*8 :: thr 22 | integer optional :: isd=1 ! Standardize predictors by default 23 | 24 | ! Outputs 25 | integer intent(out) :: lmu 26 | real*8 intent(out),dimension(nlam),depend(nlam) :: a0 27 | real*8 intent(out),dimension(nx,nlam),depend(nlam) :: ca 28 | integer intent(out),dimension(nx),depend(nx) :: ia 29 | integer intent(out),dimension(nlam),depend(nlam) :: nin 30 | real*8 intent(out),dimension(nlam),depend(nlam) :: rsq 31 | real*8 intent(out),dimension(nlam),depend(nlam) :: alm 32 | integer intent(out) :: nlp 33 | integer intent(out) :: jerr 34 | end subroutine elnet 35 | 36 | subroutine uncomp(ni,ca,ia,nin,a) ! in :glmnet:glmnet.f 37 | integer :: ni 38 | real*8 dimension(*) :: ca 39 | integer dimension(*) :: ia 40 | integer :: nin 41 | real*8 intent(out),dimension(ni),depend(ni) :: a 42 | end subroutine uncomp 43 | 44 | subroutine modval(a0,ca,ia,nin,n,x,f) ! in :glmnet:glmnet.f 45 | real :: a0 46 | real dimension(*) :: ca 47 | integer dimension(*), check(len(ca) == len(ia)), depend(ca) :: ia 48 | integer check(len(ca)>=nin),depend(ca) :: nin 49 | integer optional,check(shape(x,0)==n),depend(x) :: n=shape(x,0) 50 | real dimension(n,*) :: x 51 | real dimension(n),depend(n),intent(out) :: f 52 | end subroutine modval 53 | 54 | subroutine spelnet(ka,parm,no,ni,x,ix,jx,y,w,jd,vp,ne,nx,nlam,flmin,ulam,thr,isd,lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr) ! in :glmnet:glmnet.f 55 | integer optional :: ka=1 ! Use covariance updates over naive by default 56 | real*8 :: parm 57 | integer intent(hide),check(len(y)>=no),depend(y) :: no=len(y) 58 | integer intent(hide),check(len(vp)>=ni),depend(vp) :: ni=len(vp) 59 | real*8 dimension(*) :: x 60 | integer dimension(*) :: ix 61 | integer dimension(*) :: jx 62 | real*8 dimension(no) :: y 63 | real*8 dimension(no),depend(no) :: w 64 | integer dimension(*) :: jd 65 | real*8 dimension(ni) :: vp 66 | integer optional, depend(x) :: ne=shape(x,1) 67 | integer optional,check(shape(ca,0)==nx),depend(ca) :: nx=shape(ca,0) 68 | integer optional,check((flmin < 1.0 || len(ulam)==nlam)),depend(flmin,ulam) :: nlam=len(ulam) 69 | real*8 :: flmin 70 | real*8 dimension(nlam) :: ulam 71 | real*8 optional :: thr=1.0e-4 72 | integer optional :: isd=1 ! Standardize predictors by default 73 | 74 | ! Output arguments 75 | integer intent(out) :: lmu 76 | real*8 intent(out),dimension(nlam),depend(nlam) :: a0 77 | real*8 intent(out),dimension(nx,nlam),depend(nlam) :: ca 78 | integer intent(out),dimension(nx),depend(nx) :: ia 79 | integer intent(out),dimension(nlam),depend(nlam) :: nin 80 | real*8 intent(out),dimension(nlam),depend(nlam) :: rsq 81 | real*8 intent(out),dimension(nlam),depend(nlam) :: alm 82 | integer intent(out) :: nlp 83 | integer intent(out) :: jerr 84 | end subroutine spelnet 85 | subroutine cmodval(a0,ca,ia,nin,x,ix,jx,n,f) ! in :glmnet:glmnet.f 86 | real*8 :: a0 87 | real*8 dimension(*) :: ca 88 | integer dimension(*) :: ia 89 | integer :: nin 90 | real*8 dimension(*) :: x 91 | integer dimension(*) :: ix 92 | integer dimension(*) :: jx 93 | integer optional,check(len(f)>=n),depend(f) :: n=len(f) 94 | real*8 dimension(n) :: f 95 | end subroutine cmodval 96 | subroutine lognet(parm,no,ni,nc,x,y,jd,vp,ne,nx,nlam,flmin,ulam,thr,isd,maxit,kopt,lmu,a0,ca,ia,nin,dev,alm,nlp,jerr) ! in :glmnet:glmnet.f 97 | real*8 :: parm 98 | integer intent(hide),check(shape(x,0)==no),depend(x) :: no=shape(x,0) 99 | integer intent(hide),check(shape(x,1)==ni),depend(x) :: ni=shape(x,1) 100 | integer optional,check(shape(y,0)==max(2,nc)),depend(y) :: nc = ((shape(y,0) == 2) ? 1 : shape(y, 0)) 101 | real*8 dimension(no,ni) :: x 102 | real*8 dimension(no,max(2,nc)),depend(no) :: y 103 | integer dimension(*) :: jd 104 | real*8 dimension(ni),depend(ni) :: vp 105 | integer optional,depend(x) :: ne=min(shape(x,1), nx) 106 | integer :: nx 107 | integer optional,check((flmin < 1.0 || len(ulam)<=nlam)),depend(flmin,ulam) :: nlam=len(ulam) 108 | real*8 :: flmin 109 | real*8 dimension(nlam) :: ulam 110 | real*8 :: thr 111 | integer optional :: isd=1 ! Standardize predictors by default 112 | integer :: maxit 113 | integer optional :: kopt=1 ! Use modified Newton-Raphson by default 114 | integer intent(out) :: lmu 115 | real*8 intent(out),dimension(nc,nlam),depend(nlam) :: a0 116 | real*8 intent(out),dimension(nx,nc,nlam),depend(nlam) :: ca 117 | integer intent(out),dimension(nx),depend(nx) :: ia 118 | integer intent(out),dimension(nlam),depend(nlam) :: nin 119 | real*8 intent(out),dimension(nlam),depend(nlam) :: dev 120 | real*8 intent(out),dimension(nlam),depend(nlam) :: alm 121 | integer intent(out) :: nlp 122 | integer intent(out) :: jerr 123 | end subroutine lognet 124 | subroutine luncomp(ni,nx,nc,ca,ia,nin,a) ! in :glmnet:glmnet.f 125 | integer optional,check(shape(a,0)==ni),depend(a) :: ni=shape(a,0) 126 | integer optional,check(shape(ca,0)==nx),depend(ca) :: nx=shape(ca,0) 127 | integer optional,check(shape(ca,1)==nc),depend(ca) :: nc=shape(ca,1) 128 | real*8 dimension(nx,nc) :: ca 129 | integer dimension(nx),depend(nx) :: ia 130 | integer :: nin 131 | real*8 dimension(ni,nc),depend(nc) :: a 132 | end subroutine luncomp 133 | subroutine lmodval(nt,x,nc,nx,a0,ca,ia,nin,ans) ! in :glmnet:glmnet.f 134 | integer optional,check(shape(x,0)==nt),depend(x) :: nt=shape(x,0) 135 | real*8 dimension(nt,*) :: x 136 | integer optional,check(len(a0)>=nc),depend(a0) :: nc=len(a0) 137 | integer optional,check(shape(ca,0)==nx),depend(ca) :: nx=shape(ca,0) 138 | real*8 dimension(nc) :: a0 139 | real*8 dimension(nx,nc),depend(nc) :: ca 140 | integer dimension(nx),depend(nx) :: ia 141 | integer :: nin 142 | real*8 dimension(nc,nt),depend(nc,nt) :: ans 143 | end subroutine lmodval 144 | subroutine splognet(parm,no,ni,nc,x,ix,jx,y,jd,vp,ne,nx,nlam,flmin,ulam,thr,isd,maxit,kopt,lmu,a0,ca,ia,nin,dev,alm,nlp,jerr) ! in :glmnet:glmnet.f 145 | real*8 :: parm 146 | integer intent(hide),check(shape(y,0)==no),depend(y) :: no=shape(y,0) 147 | integer intent(hide),check(len(vp)>=ni),depend(vp) :: ni=len(vp) 148 | integer optional,check(shape(a0,0)==nc),depend(a0) :: nc=shape(a0,0) 149 | real*8 dimension(*) :: x 150 | integer dimension(*) :: ix 151 | integer dimension(*) :: jx 152 | real*8 dimension(no,max(2,nc)),depend(nc) :: y 153 | integer dimension(*) :: jd 154 | real*8 dimension(ni) :: vp 155 | integer :: ne 156 | integer optional,check(shape(ca,0)==nx),depend(ca) :: nx=shape(ca,0) 157 | integer optional,check((flmin < 1.0 || len(ulam)==nlam)),depend(flmin,ulam) :: nlam=len(ulam) 158 | real*8 :: flmin 159 | real*8 dimension(nlam) :: ulam 160 | real*8 :: thr 161 | integer optional :: isd=1 ! Standardize predictors by default 162 | integer :: maxit 163 | integer optional :: kopt=1 ! Use modified Newton-Raphson by default 164 | integer intent(out) :: lmu 165 | real*8 intent(out),dimension(nc,nlam),depend(nlam) :: a0 166 | real*8 intent(out),dimension(nx,nc,nlam),depend(nc,nlam) :: ca 167 | integer intent(out),dimension(nx),depend(nx) :: ia 168 | integer intent(out),dimension(nlam),depend(nlam) :: nin 169 | real*8 intent(out),dimension(nlam),depend(nlam) :: dev 170 | real*8 intent(out),dimension(nlam),depend(nlam) :: alm 171 | integer intent(out) :: nlp 172 | integer intent(out) :: jerr 173 | end subroutine splognet 174 | subroutine lcmodval(nc,nx,a0,ca,ia,nin,x,ix,jx,n,f) ! in :glmnet:glmnet.f 175 | integer optional,check(len(a0)>=nc),depend(a0) :: nc=len(a0) 176 | integer optional,check(shape(ca,0)==nx),depend(ca) :: nx=shape(ca,0) 177 | real*8 dimension(nc) :: a0 178 | real*8 dimension(nx,nc),depend(nc) :: ca 179 | integer dimension(*) :: ia 180 | integer :: nin 181 | real*8 dimension(*) :: x 182 | integer dimension(*) :: ix 183 | integer dimension(*) :: jx 184 | integer optional,check(shape(f,1)==n),depend(f) :: n=shape(f,1) 185 | real*8 dimension(nc,n),depend(nc) :: f 186 | end subroutine lcmodval 187 | end interface 188 | end python module glmnet 189 | 190 | ! This file was auto-generated with f2py (version:2). 191 | ! See http://cens.ioc.ee/projects/f2py2e/ 192 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------