mirror of
https://github.com/sjwhitworth/golearn.git
synced 2025-04-26 13:49:14 +08:00
linear_models: fix cgo issues, upgrade to liblinear 2.14
Requires an additional step to install: - cd /tmp && - wget https://github.com/cjlin1/liblinear/archive/v241.tar.gz - tar xvf v241.tar.gz - cd liblinear-241 - make lib - sudo install -vm644 linear.h /usr/include - sudo install -vm755 liblinear.so.4 /usr/lib - sudo ln -sfv liblinear.so.4 /usr/lib/liblinear.so
This commit is contained in:
parent
c39ef5156b
commit
5ceb4e7111
@ -2,13 +2,14 @@ language: go
|
|||||||
go:
|
go:
|
||||||
- 1.13.x
|
- 1.13.x
|
||||||
- 1.14.x
|
- 1.14.x
|
||||||
|
arch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
env:
|
env:
|
||||||
# Temporary workaround for Go 1.6+
|
|
||||||
- GODEBUG=cgocheck=0
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq libatlas-base-dev
|
- sudo apt-get install -qq libatlas-base-dev
|
||||||
- cd /tmp && wget http://www.csie.ntu.edu.tw/~cjlin/liblinear/oldfiles/liblinear-1.94.tar.gz && tar xf liblinear-1.94.tar.gz && cd liblinear-1.94 && make lib && sudo install -vm644 linear.h /usr/include && sudo install -vm755 liblinear.so.1 /usr/lib && sudo ln -sfv liblinear.so.1 /usr/lib/liblinear.so
|
- cd /tmp && wget https://github.com/cjlin1/liblinear/archive/v241.tar.gz && tar xvf v241.tar.gz && cd liblinear-241 && make lib && sudo install -vm644 linear.h /usr/include && sudo install -vm755 liblinear.so.4 /usr/lib && sudo ln -sfv liblinear.so.4 /usr/lib/liblinear.so
|
||||||
- cd $TRAVIS_BUILD_DIR
|
- cd $TRAVIS_BUILD_DIR
|
||||||
install:
|
install:
|
||||||
- go get github.com/smartystreets/goconvey/convey
|
- go get github.com/smartystreets/goconvey/convey
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
/* blas.h -- C header file for BLAS Ver 1.0 */
|
|
||||||
/* Jesse Bennett March 23, 2000 */
|
|
||||||
|
|
||||||
/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
|
|
||||||
|
|
||||||
- From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */
|
|
||||||
|
|
||||||
#ifndef BLAS_INCLUDE
|
|
||||||
#define BLAS_INCLUDE
|
|
||||||
|
|
||||||
/* Data types specific to BLAS implementation */
|
|
||||||
typedef struct { float r, i; } fcomplex;
|
|
||||||
typedef struct { double r, i; } dcomplex;
|
|
||||||
typedef int blasbool;
|
|
||||||
|
|
||||||
#include "blasp.h" /* Prototypes for all BLAS functions */
|
|
||||||
|
|
||||||
#define FALSE 0
|
|
||||||
#define TRUE 1
|
|
||||||
|
|
||||||
/* Macro functions */
|
|
||||||
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
|
|
||||||
#define MAX(a,b) ((a) >= (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,430 +0,0 @@
|
|||||||
/* blasp.h -- C prototypes for BLAS Ver 1.0 */
|
|
||||||
/* Jesse Bennett March 23, 2000 */
|
|
||||||
|
|
||||||
/* Functions listed in alphabetical order */
|
|
||||||
|
|
||||||
#ifdef F2C_COMPAT
|
|
||||||
|
|
||||||
void cdotc_(fcomplex *dotval, int *n, fcomplex *cx, int *incx,
|
|
||||||
fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
void cdotu_(fcomplex *dotval, int *n, fcomplex *cx, int *incx,
|
|
||||||
fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
double sasum_(int *n, float *sx, int *incx);
|
|
||||||
|
|
||||||
double scasum_(int *n, fcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
double scnrm2_(int *n, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
double sdot_(int *n, float *sx, int *incx, float *sy, int *incy);
|
|
||||||
|
|
||||||
double snrm2_(int *n, float *x, int *incx);
|
|
||||||
|
|
||||||
void zdotc_(dcomplex *dotval, int *n, dcomplex *cx, int *incx,
|
|
||||||
dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
void zdotu_(dcomplex *dotval, int *n, dcomplex *cx, int *incx,
|
|
||||||
dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
fcomplex cdotc_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
fcomplex cdotu_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
float sasum_(int *n, float *sx, int *incx);
|
|
||||||
|
|
||||||
float scasum_(int *n, fcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
float scnrm2_(int *n, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
float sdot_(int *n, float *sx, int *incx, float *sy, int *incy);
|
|
||||||
|
|
||||||
float snrm2_(int *n, float *x, int *incx);
|
|
||||||
|
|
||||||
dcomplex zdotc_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
dcomplex zdotu_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Remaining functions listed in alphabetical order */
|
|
||||||
|
|
||||||
int caxpy_(int *n, fcomplex *ca, fcomplex *cx, int *incx, fcomplex *cy,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int ccopy_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
int cgbmv_(char *trans, int *m, int *n, int *kl, int *ku,
|
|
||||||
fcomplex *alpha, fcomplex *a, int *lda, fcomplex *x, int *incx,
|
|
||||||
fcomplex *beta, fcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int cgemm_(char *transa, char *transb, int *m, int *n, int *k,
|
|
||||||
fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, int *ldb,
|
|
||||||
fcomplex *beta, fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int cgemv_(char *trans, int *m, int *n, fcomplex *alpha, fcomplex *a,
|
|
||||||
int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int cgerc_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *y, int *incy, fcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int cgeru_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *y, int *incy, fcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int chbmv_(char *uplo, int *n, int *k, fcomplex *alpha, fcomplex *a,
|
|
||||||
int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int chemm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha,
|
|
||||||
fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta,
|
|
||||||
fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int chemv_(char *uplo, int *n, fcomplex *alpha, fcomplex *a, int *lda,
|
|
||||||
fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int cher_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int cher2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *y, int *incy, fcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int cher2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha,
|
|
||||||
fcomplex *a, int *lda, fcomplex *b, int *ldb, float *beta,
|
|
||||||
fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int cherk_(char *uplo, char *trans, int *n, int *k, float *alpha,
|
|
||||||
fcomplex *a, int *lda, float *beta, fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int chpmv_(char *uplo, int *n, fcomplex *alpha, fcomplex *ap, fcomplex *x,
|
|
||||||
int *incx, fcomplex *beta, fcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int chpr_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *ap);
|
|
||||||
|
|
||||||
int chpr2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx,
|
|
||||||
fcomplex *y, int *incy, fcomplex *ap);
|
|
||||||
|
|
||||||
int crotg_(fcomplex *ca, fcomplex *cb, float *c, fcomplex *s);
|
|
||||||
|
|
||||||
int cscal_(int *n, fcomplex *ca, fcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
int csscal_(int *n, float *sa, fcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
int cswap_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
int csymm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha,
|
|
||||||
fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta,
|
|
||||||
fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int csyr2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha,
|
|
||||||
fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta,
|
|
||||||
fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int csyrk_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha,
|
|
||||||
fcomplex *a, int *lda, fcomplex *beta, fcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int ctbmv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
fcomplex *a, int *lda, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ctbsv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
fcomplex *a, int *lda, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ctpmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap,
|
|
||||||
fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ctpsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap,
|
|
||||||
fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ctrmm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int ctrmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a,
|
|
||||||
int *lda, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ctrsm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int ctrsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a,
|
|
||||||
int *lda, fcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int daxpy_(int *n, double *sa, double *sx, int *incx, double *sy,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int dcopy_(int *n, double *sx, int *incx, double *sy, int *incy);
|
|
||||||
|
|
||||||
int dgbmv_(char *trans, int *m, int *n, int *kl, int *ku,
|
|
||||||
double *alpha, double *a, int *lda, double *x, int *incx,
|
|
||||||
double *beta, double *y, int *incy);
|
|
||||||
|
|
||||||
int dgemm_(char *transa, char *transb, int *m, int *n, int *k,
|
|
||||||
double *alpha, double *a, int *lda, double *b, int *ldb,
|
|
||||||
double *beta, double *c, int *ldc);
|
|
||||||
|
|
||||||
int dgemv_(char *trans, int *m, int *n, double *alpha, double *a,
|
|
||||||
int *lda, double *x, int *incx, double *beta, double *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int dger_(int *m, int *n, double *alpha, double *x, int *incx,
|
|
||||||
double *y, int *incy, double *a, int *lda);
|
|
||||||
|
|
||||||
int drot_(int *n, double *sx, int *incx, double *sy, int *incy,
|
|
||||||
double *c, double *s);
|
|
||||||
|
|
||||||
int drotg_(double *sa, double *sb, double *c, double *s);
|
|
||||||
|
|
||||||
int dsbmv_(char *uplo, int *n, int *k, double *alpha, double *a,
|
|
||||||
int *lda, double *x, int *incx, double *beta, double *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int dscal_(int *n, double *sa, double *sx, int *incx);
|
|
||||||
|
|
||||||
int dspmv_(char *uplo, int *n, double *alpha, double *ap, double *x,
|
|
||||||
int *incx, double *beta, double *y, int *incy);
|
|
||||||
|
|
||||||
int dspr_(char *uplo, int *n, double *alpha, double *x, int *incx,
|
|
||||||
double *ap);
|
|
||||||
|
|
||||||
int dspr2_(char *uplo, int *n, double *alpha, double *x, int *incx,
|
|
||||||
double *y, int *incy, double *ap);
|
|
||||||
|
|
||||||
int dswap_(int *n, double *sx, int *incx, double *sy, int *incy);
|
|
||||||
|
|
||||||
int dsymm_(char *side, char *uplo, int *m, int *n, double *alpha,
|
|
||||||
double *a, int *lda, double *b, int *ldb, double *beta,
|
|
||||||
double *c, int *ldc);
|
|
||||||
|
|
||||||
int dsymv_(char *uplo, int *n, double *alpha, double *a, int *lda,
|
|
||||||
double *x, int *incx, double *beta, double *y, int *incy);
|
|
||||||
|
|
||||||
int dsyr_(char *uplo, int *n, double *alpha, double *x, int *incx,
|
|
||||||
double *a, int *lda);
|
|
||||||
|
|
||||||
int dsyr2_(char *uplo, int *n, double *alpha, double *x, int *incx,
|
|
||||||
double *y, int *incy, double *a, int *lda);
|
|
||||||
|
|
||||||
int dsyr2k_(char *uplo, char *trans, int *n, int *k, double *alpha,
|
|
||||||
double *a, int *lda, double *b, int *ldb, double *beta,
|
|
||||||
double *c, int *ldc);
|
|
||||||
|
|
||||||
int dsyrk_(char *uplo, char *trans, int *n, int *k, double *alpha,
|
|
||||||
double *a, int *lda, double *beta, double *c, int *ldc);
|
|
||||||
|
|
||||||
int dtbmv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
double *a, int *lda, double *x, int *incx);
|
|
||||||
|
|
||||||
int dtbsv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
double *a, int *lda, double *x, int *incx);
|
|
||||||
|
|
||||||
int dtpmv_(char *uplo, char *trans, char *diag, int *n, double *ap,
|
|
||||||
double *x, int *incx);
|
|
||||||
|
|
||||||
int dtpsv_(char *uplo, char *trans, char *diag, int *n, double *ap,
|
|
||||||
double *x, int *incx);
|
|
||||||
|
|
||||||
int dtrmm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, double *alpha, double *a, int *lda, double *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int dtrmv_(char *uplo, char *trans, char *diag, int *n, double *a,
|
|
||||||
int *lda, double *x, int *incx);
|
|
||||||
|
|
||||||
int dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, double *alpha, double *a, int *lda, double *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int dtrsv_(char *uplo, char *trans, char *diag, int *n, double *a,
|
|
||||||
int *lda, double *x, int *incx);
|
|
||||||
|
|
||||||
|
|
||||||
int saxpy_(int *n, float *sa, float *sx, int *incx, float *sy, int *incy);
|
|
||||||
|
|
||||||
int scopy_(int *n, float *sx, int *incx, float *sy, int *incy);
|
|
||||||
|
|
||||||
int sgbmv_(char *trans, int *m, int *n, int *kl, int *ku,
|
|
||||||
float *alpha, float *a, int *lda, float *x, int *incx,
|
|
||||||
float *beta, float *y, int *incy);
|
|
||||||
|
|
||||||
int sgemm_(char *transa, char *transb, int *m, int *n, int *k,
|
|
||||||
float *alpha, float *a, int *lda, float *b, int *ldb,
|
|
||||||
float *beta, float *c, int *ldc);
|
|
||||||
|
|
||||||
int sgemv_(char *trans, int *m, int *n, float *alpha, float *a,
|
|
||||||
int *lda, float *x, int *incx, float *beta, float *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int sger_(int *m, int *n, float *alpha, float *x, int *incx,
|
|
||||||
float *y, int *incy, float *a, int *lda);
|
|
||||||
|
|
||||||
int srot_(int *n, float *sx, int *incx, float *sy, int *incy,
|
|
||||||
float *c, float *s);
|
|
||||||
|
|
||||||
int srotg_(float *sa, float *sb, float *c, float *s);
|
|
||||||
|
|
||||||
int ssbmv_(char *uplo, int *n, int *k, float *alpha, float *a,
|
|
||||||
int *lda, float *x, int *incx, float *beta, float *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int sscal_(int *n, float *sa, float *sx, int *incx);
|
|
||||||
|
|
||||||
int sspmv_(char *uplo, int *n, float *alpha, float *ap, float *x,
|
|
||||||
int *incx, float *beta, float *y, int *incy);
|
|
||||||
|
|
||||||
int sspr_(char *uplo, int *n, float *alpha, float *x, int *incx,
|
|
||||||
float *ap);
|
|
||||||
|
|
||||||
int sspr2_(char *uplo, int *n, float *alpha, float *x, int *incx,
|
|
||||||
float *y, int *incy, float *ap);
|
|
||||||
|
|
||||||
int sswap_(int *n, float *sx, int *incx, float *sy, int *incy);
|
|
||||||
|
|
||||||
int ssymm_(char *side, char *uplo, int *m, int *n, float *alpha,
|
|
||||||
float *a, int *lda, float *b, int *ldb, float *beta,
|
|
||||||
float *c, int *ldc);
|
|
||||||
|
|
||||||
int ssymv_(char *uplo, int *n, float *alpha, float *a, int *lda,
|
|
||||||
float *x, int *incx, float *beta, float *y, int *incy);
|
|
||||||
|
|
||||||
int ssyr_(char *uplo, int *n, float *alpha, float *x, int *incx,
|
|
||||||
float *a, int *lda);
|
|
||||||
|
|
||||||
int ssyr2_(char *uplo, int *n, float *alpha, float *x, int *incx,
|
|
||||||
float *y, int *incy, float *a, int *lda);
|
|
||||||
|
|
||||||
int ssyr2k_(char *uplo, char *trans, int *n, int *k, float *alpha,
|
|
||||||
float *a, int *lda, float *b, int *ldb, float *beta,
|
|
||||||
float *c, int *ldc);
|
|
||||||
|
|
||||||
int ssyrk_(char *uplo, char *trans, int *n, int *k, float *alpha,
|
|
||||||
float *a, int *lda, float *beta, float *c, int *ldc);
|
|
||||||
|
|
||||||
int stbmv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
float *a, int *lda, float *x, int *incx);
|
|
||||||
|
|
||||||
int stbsv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
float *a, int *lda, float *x, int *incx);
|
|
||||||
|
|
||||||
int stpmv_(char *uplo, char *trans, char *diag, int *n, float *ap,
|
|
||||||
float *x, int *incx);
|
|
||||||
|
|
||||||
int stpsv_(char *uplo, char *trans, char *diag, int *n, float *ap,
|
|
||||||
float *x, int *incx);
|
|
||||||
|
|
||||||
int strmm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, float *alpha, float *a, int *lda, float *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int strmv_(char *uplo, char *trans, char *diag, int *n, float *a,
|
|
||||||
int *lda, float *x, int *incx);
|
|
||||||
|
|
||||||
int strsm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, float *alpha, float *a, int *lda, float *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int strsv_(char *uplo, char *trans, char *diag, int *n, float *a,
|
|
||||||
int *lda, float *x, int *incx);
|
|
||||||
|
|
||||||
int zaxpy_(int *n, dcomplex *ca, dcomplex *cx, int *incx, dcomplex *cy,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int zcopy_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
int zdscal_(int *n, double *sa, dcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
int zgbmv_(char *trans, int *m, int *n, int *kl, int *ku,
|
|
||||||
dcomplex *alpha, dcomplex *a, int *lda, dcomplex *x, int *incx,
|
|
||||||
dcomplex *beta, dcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int zgemm_(char *transa, char *transb, int *m, int *n, int *k,
|
|
||||||
dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, int *ldb,
|
|
||||||
dcomplex *beta, dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zgemv_(char *trans, int *m, int *n, dcomplex *alpha, dcomplex *a,
|
|
||||||
int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int zgerc_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *y, int *incy, dcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int zgeru_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *y, int *incy, dcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int zhbmv_(char *uplo, int *n, int *k, dcomplex *alpha, dcomplex *a,
|
|
||||||
int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y,
|
|
||||||
int *incy);
|
|
||||||
|
|
||||||
int zhemm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha,
|
|
||||||
dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta,
|
|
||||||
dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zhemv_(char *uplo, int *n, dcomplex *alpha, dcomplex *a, int *lda,
|
|
||||||
dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int zher_(char *uplo, int *n, double *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int zher2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *y, int *incy, dcomplex *a, int *lda);
|
|
||||||
|
|
||||||
int zher2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha,
|
|
||||||
dcomplex *a, int *lda, dcomplex *b, int *ldb, double *beta,
|
|
||||||
dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zherk_(char *uplo, char *trans, int *n, int *k, double *alpha,
|
|
||||||
dcomplex *a, int *lda, double *beta, dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zhpmv_(char *uplo, int *n, dcomplex *alpha, dcomplex *ap, dcomplex *x,
|
|
||||||
int *incx, dcomplex *beta, dcomplex *y, int *incy);
|
|
||||||
|
|
||||||
int zhpr_(char *uplo, int *n, double *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *ap);
|
|
||||||
|
|
||||||
int zhpr2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx,
|
|
||||||
dcomplex *y, int *incy, dcomplex *ap);
|
|
||||||
|
|
||||||
int zrotg_(dcomplex *ca, dcomplex *cb, double *c, dcomplex *s);
|
|
||||||
|
|
||||||
int zscal_(int *n, dcomplex *ca, dcomplex *cx, int *incx);
|
|
||||||
|
|
||||||
int zswap_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy);
|
|
||||||
|
|
||||||
int zsymm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha,
|
|
||||||
dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta,
|
|
||||||
dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zsyr2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha,
|
|
||||||
dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta,
|
|
||||||
dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int zsyrk_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha,
|
|
||||||
dcomplex *a, int *lda, dcomplex *beta, dcomplex *c, int *ldc);
|
|
||||||
|
|
||||||
int ztbmv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
dcomplex *a, int *lda, dcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ztbsv_(char *uplo, char *trans, char *diag, int *n, int *k,
|
|
||||||
dcomplex *a, int *lda, dcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ztpmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap,
|
|
||||||
dcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ztpsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap,
|
|
||||||
dcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ztrmm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int ztrmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a,
|
|
||||||
int *lda, dcomplex *x, int *incx);
|
|
||||||
|
|
||||||
int ztrsm_(char *side, char *uplo, char *transa, char *diag, int *m,
|
|
||||||
int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b,
|
|
||||||
int *ldb);
|
|
||||||
|
|
||||||
int ztrsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a,
|
|
||||||
int *lda, dcomplex *x, int *incx);
|
|
@ -1,49 +0,0 @@
|
|||||||
#include "blas.h"
|
|
||||||
|
|
||||||
int daxpy_(int *n, double *sa, double *sx, int *incx, double *sy,
|
|
||||||
int *incy)
|
|
||||||
{
|
|
||||||
long int i, m, ix, iy, nn, iincx, iincy;
|
|
||||||
register double ssa;
|
|
||||||
|
|
||||||
/* constant times a vector plus a vector.
|
|
||||||
uses unrolled loop for increments equal to one.
|
|
||||||
jack dongarra, linpack, 3/11/78.
|
|
||||||
modified 12/3/93, array(1) declarations changed to array(*) */
|
|
||||||
|
|
||||||
/* Dereference inputs */
|
|
||||||
nn = *n;
|
|
||||||
ssa = *sa;
|
|
||||||
iincx = *incx;
|
|
||||||
iincy = *incy;
|
|
||||||
|
|
||||||
if( nn > 0 && ssa != 0.0 )
|
|
||||||
{
|
|
||||||
if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */
|
|
||||||
{
|
|
||||||
m = nn-3;
|
|
||||||
for (i = 0; i < m; i += 4)
|
|
||||||
{
|
|
||||||
sy[i] += ssa * sx[i];
|
|
||||||
sy[i+1] += ssa * sx[i+1];
|
|
||||||
sy[i+2] += ssa * sx[i+2];
|
|
||||||
sy[i+3] += ssa * sx[i+3];
|
|
||||||
}
|
|
||||||
for ( ; i < nn; ++i) /* clean-up loop */
|
|
||||||
sy[i] += ssa * sx[i];
|
|
||||||
}
|
|
||||||
else /* code for unequal increments or equal increments not equal to 1 */
|
|
||||||
{
|
|
||||||
ix = iincx >= 0 ? 0 : (1 - nn) * iincx;
|
|
||||||
iy = iincy >= 0 ? 0 : (1 - nn) * iincy;
|
|
||||||
for (i = 0; i < nn; i++)
|
|
||||||
{
|
|
||||||
sy[iy] += ssa * sx[ix];
|
|
||||||
ix += iincx;
|
|
||||||
iy += iincy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} /* daxpy_ */
|
|
@ -1,50 +0,0 @@
|
|||||||
#include "blas.h"
|
|
||||||
|
|
||||||
double ddot_(int *n, double *sx, int *incx, double *sy, int *incy)
|
|
||||||
{
|
|
||||||
long int i, m, nn, iincx, iincy;
|
|
||||||
double stemp;
|
|
||||||
long int ix, iy;
|
|
||||||
|
|
||||||
/* forms the dot product of two vectors.
|
|
||||||
uses unrolled loops for increments equal to one.
|
|
||||||
jack dongarra, linpack, 3/11/78.
|
|
||||||
modified 12/3/93, array(1) declarations changed to array(*) */
|
|
||||||
|
|
||||||
/* Dereference inputs */
|
|
||||||
nn = *n;
|
|
||||||
iincx = *incx;
|
|
||||||
iincy = *incy;
|
|
||||||
|
|
||||||
stemp = 0.0;
|
|
||||||
if (nn > 0)
|
|
||||||
{
|
|
||||||
if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */
|
|
||||||
{
|
|
||||||
m = nn-4;
|
|
||||||
for (i = 0; i < m; i += 5)
|
|
||||||
stemp += sx[i] * sy[i] + sx[i+1] * sy[i+1] + sx[i+2] * sy[i+2] +
|
|
||||||
sx[i+3] * sy[i+3] + sx[i+4] * sy[i+4];
|
|
||||||
|
|
||||||
for ( ; i < nn; i++) /* clean-up loop */
|
|
||||||
stemp += sx[i] * sy[i];
|
|
||||||
}
|
|
||||||
else /* code for unequal increments or equal increments not equal to 1 */
|
|
||||||
{
|
|
||||||
ix = 0;
|
|
||||||
iy = 0;
|
|
||||||
if (iincx < 0)
|
|
||||||
ix = (1 - nn) * iincx;
|
|
||||||
if (iincy < 0)
|
|
||||||
iy = (1 - nn) * iincy;
|
|
||||||
for (i = 0; i < nn; i++)
|
|
||||||
{
|
|
||||||
stemp += sx[ix] * sy[iy];
|
|
||||||
ix += iincx;
|
|
||||||
iy += iincy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stemp;
|
|
||||||
} /* ddot_ */
|
|
@ -1,62 +0,0 @@
|
|||||||
#include <math.h> /* Needed for fabs() and sqrt() */
|
|
||||||
#include "blas.h"
|
|
||||||
|
|
||||||
double dnrm2_(int *n, double *x, int *incx)
|
|
||||||
{
|
|
||||||
long int ix, nn, iincx;
|
|
||||||
double norm, scale, absxi, ssq, temp;
|
|
||||||
|
|
||||||
/* DNRM2 returns the euclidean norm of a vector via the function
|
|
||||||
name, so that
|
|
||||||
|
|
||||||
DNRM2 := sqrt( x'*x )
|
|
||||||
|
|
||||||
-- This version written on 25-October-1982.
|
|
||||||
Modified on 14-October-1993 to inline the call to SLASSQ.
|
|
||||||
Sven Hammarling, Nag Ltd. */
|
|
||||||
|
|
||||||
/* Dereference inputs */
|
|
||||||
nn = *n;
|
|
||||||
iincx = *incx;
|
|
||||||
|
|
||||||
if( nn > 0 && iincx > 0 )
|
|
||||||
{
|
|
||||||
if (nn == 1)
|
|
||||||
{
|
|
||||||
norm = fabs(x[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scale = 0.0;
|
|
||||||
ssq = 1.0;
|
|
||||||
|
|
||||||
/* The following loop is equivalent to this call to the LAPACK
|
|
||||||
auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */
|
|
||||||
|
|
||||||
for (ix=(nn-1)*iincx; ix>=0; ix-=iincx)
|
|
||||||
{
|
|
||||||
if (x[ix] != 0.0)
|
|
||||||
{
|
|
||||||
absxi = fabs(x[ix]);
|
|
||||||
if (scale < absxi)
|
|
||||||
{
|
|
||||||
temp = scale / absxi;
|
|
||||||
ssq = ssq * (temp * temp) + 1.0;
|
|
||||||
scale = absxi;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp = absxi / scale;
|
|
||||||
ssq += temp * temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
norm = scale * sqrt(ssq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
norm = 0.0;
|
|
||||||
|
|
||||||
return norm;
|
|
||||||
|
|
||||||
} /* dnrm2_ */
|
|
@ -1,5 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
Package linear_models implements linear
|
Package linear_models implements linear
|
||||||
and logistic regression models.
|
and logistic regression models.
|
||||||
|
|
||||||
|
train.csv, test.csv are truncated versions of
|
||||||
|
https://www.kaggle.com/uciml/pima-indians-diabetes-database
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package linear_models
|
package linear_models
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
#include "blas.h"
|
|
||||||
|
|
||||||
int dscal_(int *n, double *sa, double *sx, int *incx)
|
|
||||||
{
|
|
||||||
long int i, m, nincx, nn, iincx;
|
|
||||||
double ssa;
|
|
||||||
|
|
||||||
/* scales a vector by a constant.
|
|
||||||
uses unrolled loops for increment equal to 1.
|
|
||||||
jack dongarra, linpack, 3/11/78.
|
|
||||||
modified 3/93 to return if incx .le. 0.
|
|
||||||
modified 12/3/93, array(1) declarations changed to array(*) */
|
|
||||||
|
|
||||||
/* Dereference inputs */
|
|
||||||
nn = *n;
|
|
||||||
iincx = *incx;
|
|
||||||
ssa = *sa;
|
|
||||||
|
|
||||||
if (nn > 0 && iincx > 0)
|
|
||||||
{
|
|
||||||
if (iincx == 1) /* code for increment equal to 1 */
|
|
||||||
{
|
|
||||||
m = nn-4;
|
|
||||||
for (i = 0; i < m; i += 5)
|
|
||||||
{
|
|
||||||
sx[i] = ssa * sx[i];
|
|
||||||
sx[i+1] = ssa * sx[i+1];
|
|
||||||
sx[i+2] = ssa * sx[i+2];
|
|
||||||
sx[i+3] = ssa * sx[i+3];
|
|
||||||
sx[i+4] = ssa * sx[i+4];
|
|
||||||
}
|
|
||||||
for ( ; i < nn; ++i) /* clean-up loop */
|
|
||||||
sx[i] = ssa * sx[i];
|
|
||||||
}
|
|
||||||
else /* code for increment not equal to 1 */
|
|
||||||
{
|
|
||||||
nincx = nn * iincx;
|
|
||||||
for (i = 0; i < nincx; i += iincx)
|
|
||||||
sx[i] = ssa * sx[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} /* dscal_ */
|
|
109
linear_models/integration.cpp
Normal file
109
linear_models/integration.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* This file contains functions related to creating + freeing
|
||||||
|
* objects on behalf of the go runtime
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "linear.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
/* NOTE: the Golang versions of the structures must call the corresponding
|
||||||
|
* Free functions via runtime.SetFinalize */
|
||||||
|
/* CreateCProblem allocates a new struct problem outside of Golang's
|
||||||
|
* garbage collection. */
|
||||||
|
struct problem *CreateCProblem() {
|
||||||
|
auto ret = new problem();
|
||||||
|
*ret = {}; // < Clear all fields
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CreateCModel allocates a new struct model outside of Golang's
|
||||||
|
* garbage collection. */
|
||||||
|
struct model *CreateCModel() {
|
||||||
|
auto ret = new model();
|
||||||
|
*ret = {}; // < Clear all fields
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CreateCParameter allocates a new struct parameter outside of
|
||||||
|
* Golang's garbage collection.*/
|
||||||
|
struct parameter *CreateCParameter() {
|
||||||
|
auto ret = new parameter();
|
||||||
|
*ret = {};
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free's a previously allocated problem and all its data */
|
||||||
|
void FreeCProblem(struct problem *p) {
|
||||||
|
if (p->y != nullptr) {
|
||||||
|
free(p->y);
|
||||||
|
p->y = nullptr;
|
||||||
|
}
|
||||||
|
if (p->x != nullptr) {
|
||||||
|
// l is the total count of rows in the problem
|
||||||
|
// n is the number of values in each row
|
||||||
|
for (int i = 0; i < p->l; i++) {
|
||||||
|
if (p->x[i] != nullptr) {
|
||||||
|
free(p->x[i]);
|
||||||
|
p->x[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(p->x);
|
||||||
|
p->x = nullptr;
|
||||||
|
}
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free's a model with libsvm's internal routines */
|
||||||
|
void FreeCModel(struct model *m) {
|
||||||
|
free_model_content(m);
|
||||||
|
delete m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free's a parameter via libsvm */
|
||||||
|
void FreeCParameter(struct parameter *p) {
|
||||||
|
destroy_param(p);
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocates a vector of doubles for storing target values
|
||||||
|
* outside of Go's garbage collection */
|
||||||
|
int AllocateLabelsForProblem (struct problem *p, int numValues) {
|
||||||
|
p->y = reinterpret_cast<double *>(malloc(sizeof(double) * numValues));
|
||||||
|
return p->y == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility method used to set the target value for a particular
|
||||||
|
* input row */
|
||||||
|
void AssignLabelForProblem(struct problem *p, int i, double d) {
|
||||||
|
p->y[i] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a feature node for a particular row and column. */
|
||||||
|
struct feature_node *GetFeatureNodeForIndex(struct problem *p, int i, int j) {
|
||||||
|
return &(p->x[i][j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocates a buffer of input rows and the values to fill them. */
|
||||||
|
int AllocateFeatureNodesForProblem(struct problem *p,
|
||||||
|
int numSamples, int numValues, int *rowLengths) {
|
||||||
|
|
||||||
|
numValues++; // Extend for terminating element
|
||||||
|
p->x = reinterpret_cast<struct feature_node **>(
|
||||||
|
calloc(numSamples, sizeof(struct feature_node *))
|
||||||
|
);
|
||||||
|
if (p->x == nullptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Allocate all of the feature nodes, then riffle them together
|
||||||
|
struct feature_node *feature_nodes = reinterpret_cast<struct feature_node*>(calloc(numValues, sizeof(struct feature_node)));
|
||||||
|
|
||||||
|
int cur = 0;
|
||||||
|
for (int i = 0; i < numSamples; cur += rowLengths[i], i++) {
|
||||||
|
p->x[i] = feature_nodes + cur;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* extern "C" */
|
24
linear_models/integration.h
Normal file
24
linear_models/integration.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _H_INTEGRATION_
|
||||||
|
#define _H_INTEGRATION_
|
||||||
|
|
||||||
|
#include "linear.h"
|
||||||
|
|
||||||
|
struct problem *CreateCProblem();
|
||||||
|
void FreeCProblem(struct problem*);
|
||||||
|
struct model *CreateCModel();
|
||||||
|
void FreeCModel(struct model*);
|
||||||
|
struct parameter *CreateCParameter();
|
||||||
|
void FreeCParameter(struct parameter*);
|
||||||
|
// Allocates memory outside of golang for describing feature
|
||||||
|
// vectors. First pointer is the C-managed liblinear problem,
|
||||||
|
// second parameter is the number of rows we're training on
|
||||||
|
// third parameter is the total number of non-zero elements
|
||||||
|
// (including bias and null terminators) that we need to allocate
|
||||||
|
// and final parameter is an array describing the number of
|
||||||
|
// nodes in each row.
|
||||||
|
int AllocateFeatureNodesForProblem(struct problem*, int, int, int*);
|
||||||
|
int AllocateLabelsForProblem(struct problem *, int);
|
||||||
|
void AssignLabelForProblem(struct problem *, int, double);
|
||||||
|
struct feature_node *GetFeatureNodeForIndex(struct problem *, int, int);
|
||||||
|
|
||||||
|
#endif
|
@ -1,22 +1,47 @@
|
|||||||
package linear_models
|
package linear_models
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include "linear.h"
|
#include "integration.h"
|
||||||
|
#cgo CFLAGS:
|
||||||
|
#cgo CXXFLAGS: -std=c++11 -g -O0
|
||||||
|
#cgo LDFLAGS: -g -llinear
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import "fmt"
|
import (
|
||||||
import "unsafe"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Problem wraps a libsvm problem struct which describes a classification/
|
||||||
|
// regression problem. No externally-accessible fields.
|
||||||
type Problem struct {
|
type Problem struct {
|
||||||
c_prob C.struct_problem
|
c_prob *C.struct_problem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free releases resources associated with a libsvm problem.
|
||||||
|
func (p *Problem) Free() {
|
||||||
|
C.FreeCProblem(p.c_prob)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter encasulates all the possible libsvm training options.
|
||||||
|
// TODO: make user control of these more extensive.
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
c_param C.struct_parameter
|
c_param *C.struct_parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free releases resources associated with a Parameter.
|
||||||
|
func (p *Parameter) Free() {
|
||||||
|
C.FreeCParameter(p.c_param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Model encapsulates a trained libsvm model.
|
||||||
type Model struct {
|
type Model struct {
|
||||||
c_model unsafe.Pointer
|
c_model *C.struct_model
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free releases resources associated with a trained libsvm model.
|
||||||
|
func (m *Model) Free() {
|
||||||
|
C.FreeCModel(m.c_model)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -30,8 +55,14 @@ const (
|
|||||||
L2R_LR_DUAL = C.L2R_LR_DUAL
|
L2R_LR_DUAL = C.L2R_LR_DUAL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewParameter creates a libsvm parameter structure, which controls
|
||||||
|
// various aspects of libsvm training.
|
||||||
|
// For more information on what these parameters do, consult the
|
||||||
|
// "`train` usage" section of
|
||||||
|
// https://github.com/cjlin1/liblinear/blob/master/README
|
||||||
func NewParameter(solver_type int, C float64, eps float64) *Parameter {
|
func NewParameter(solver_type int, C float64, eps float64) *Parameter {
|
||||||
param := Parameter{}
|
param := &Parameter{C.CreateCParameter()}
|
||||||
|
runtime.SetFinalizer(param, (*Parameter).Free)
|
||||||
param.c_param.solver_type = C.int(solver_type)
|
param.c_param.solver_type = C.int(solver_type)
|
||||||
param.c_param.eps = C.double(eps)
|
param.c_param.eps = C.double(eps)
|
||||||
param.c_param.C = C.double(C)
|
param.c_param.C = C.double(C)
|
||||||
@ -39,30 +70,37 @@ func NewParameter(solver_type int, C float64, eps float64) *Parameter {
|
|||||||
param.c_param.weight_label = nil
|
param.c_param.weight_label = nil
|
||||||
param.c_param.weight = nil
|
param.c_param.weight = nil
|
||||||
|
|
||||||
return ¶m
|
return param
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewProblem creates input to libsvm which describes a particular
|
||||||
|
// regression/classification problem. It requires an array of float values
|
||||||
|
// and an array of y values.
|
||||||
func NewProblem(X [][]float64, y []float64, bias float64) *Problem {
|
func NewProblem(X [][]float64, y []float64, bias float64) *Problem {
|
||||||
prob := Problem{}
|
prob := &Problem{C.CreateCProblem()}
|
||||||
|
runtime.SetFinalizer(prob, (*Problem).Free)
|
||||||
prob.c_prob.l = C.int(len(X))
|
prob.c_prob.l = C.int(len(X))
|
||||||
prob.c_prob.n = C.int(len(X[0]) + 1)
|
prob.c_prob.n = C.int(len(X[0]) + 1)
|
||||||
|
|
||||||
prob.c_prob.x = convert_features(X, bias)
|
convert_features(prob, X, bias)
|
||||||
c_y := make([]C.double, len(y))
|
C.AllocateLabelsForProblem(prob.c_prob, C.int(len(y)))
|
||||||
for i := 0; i < len(y); i++ {
|
for i := 0; i < len(y); i++ {
|
||||||
c_y[i] = C.double(y[i])
|
C.AssignLabelForProblem(prob.c_prob, C.int(i), C.double(y[i]))
|
||||||
}
|
}
|
||||||
prob.c_prob.y = &c_y[0]
|
// Should not go out of scope until the Problem struct
|
||||||
|
// is cleaned up.
|
||||||
prob.c_prob.bias = C.double(-1)
|
prob.c_prob.bias = C.double(-1)
|
||||||
|
|
||||||
return &prob
|
return prob
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Train invokes libsvm and returns a trained model.
|
||||||
func Train(prob *Problem, param *Parameter) *Model {
|
func Train(prob *Problem, param *Parameter) *Model {
|
||||||
libLinearHookPrintFunc() // Sets up logging
|
libLinearHookPrintFunc() // Sets up logging
|
||||||
tmpCProb := &prob.c_prob
|
out := C.train(prob.c_prob, param.c_param)
|
||||||
tmpCParam := ¶m.c_param
|
m := &Model{out}
|
||||||
return &Model{unsafe.Pointer(C.train(tmpCProb, tmpCParam))}
|
runtime.SetFinalizer(m, (*Model).Free)
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func Export(model *Model, filePath string) error {
|
func Export(model *Model, filePath string) error {
|
||||||
@ -74,82 +112,100 @@ func Export(model *Model, filePath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Load(model *Model, filePath string) error {
|
func Load(model *Model, filePath string) error {
|
||||||
model.c_model = unsafe.Pointer(C.load_model(C.CString(filePath)))
|
model.c_model = C.load_model(C.CString(filePath))
|
||||||
if model.c_model == nil {
|
if model.c_model == nil {
|
||||||
return fmt.Errorf("Something went wrong")
|
return fmt.Errorf("Something went wrong")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Predict takes a row of float values corresponding to a particular
|
||||||
|
// input and returns the regression result.
|
||||||
func Predict(model *Model, x []float64) float64 {
|
func Predict(model *Model, x []float64) float64 {
|
||||||
c_x := convert_vector(x, 0)
|
cX := convertVector(x, 0)
|
||||||
c_y := C.predict((*C.struct_model)(model.c_model), c_x)
|
cY := C.predict((*C.struct_model)(model.c_model), &cX[0])
|
||||||
y := float64(c_y)
|
y := float64(cY)
|
||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
func convert_vector(x []float64, bias float64) *C.struct_feature_node {
|
|
||||||
n_ele := 0
|
// convertVector is an internal function used for converting
|
||||||
|
// dense float64 vectors into the sparse input that libsvm accepts.
|
||||||
|
func convertVector(x []float64, bias float64) []C.struct_feature_node {
|
||||||
|
// Count the number of non-zero elements
|
||||||
|
nElements := 0
|
||||||
for i := 0; i < len(x); i++ {
|
for i := 0; i < len(x); i++ {
|
||||||
if x[i] > 0 {
|
if x[i] > 0 {
|
||||||
n_ele++
|
nElements++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n_ele += 2
|
// Add one at the end for the -1 terminator
|
||||||
|
nElements++
|
||||||
|
if bias >= 0 {
|
||||||
|
// And one for the bias, if we have it
|
||||||
|
nElements++
|
||||||
|
}
|
||||||
|
|
||||||
c_x := make([]C.struct_feature_node, n_ele)
|
cX := make([]C.struct_feature_node, nElements)
|
||||||
j := 0
|
j := 0
|
||||||
for i := 0; i < len(x); i++ {
|
for i := 0; i < len(x); i++ {
|
||||||
if x[i] > 0 {
|
if x[i] > 0 {
|
||||||
c_x[j].index = C.int(i + 1)
|
cX[j].index = C.int(i + 1)
|
||||||
c_x[j].value = C.double(x[i])
|
cX[j].value = C.double(x[i])
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bias > 0 {
|
if bias >= 0 {
|
||||||
c_x[j].index = C.int(0)
|
cX[j].index = C.int(0)
|
||||||
c_x[j].value = C.double(0)
|
cX[j].value = C.double(0)
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
c_x[j].index = C.int(-1)
|
cX[j].index = C.int(-1)
|
||||||
return &c_x[0]
|
return cX
|
||||||
}
|
}
|
||||||
func convert_features(X [][]float64, bias float64) **C.struct_feature_node {
|
|
||||||
n_samples := len(X)
|
|
||||||
n_elements := 0
|
|
||||||
|
|
||||||
for i := 0; i < n_samples; i++ {
|
// convert_features is an internal function used for converting
|
||||||
|
// dense 2D arrays of float values into the sparse format libsvm accepts.
|
||||||
|
func convert_features(prob *Problem, X [][]float64, bias float64) {
|
||||||
|
|
||||||
|
nonZeroRowElements := make([]C.int, len(X))
|
||||||
|
totalElements := 0
|
||||||
|
|
||||||
|
for i := 0; i < len(X); i++ {
|
||||||
|
// For each row of input data, we count how many non-zero things are in the row
|
||||||
|
nonZeroElementsInRow := 1 // Initially one, because we need the -1 null terminator
|
||||||
for j := 0; j < len(X[i]); j++ {
|
for j := 0; j < len(X[i]); j++ {
|
||||||
if X[i][j] != 0.0 {
|
if X[i][j] != 0.0 {
|
||||||
n_elements++
|
nonZeroElementsInRow++
|
||||||
}
|
}
|
||||||
n_elements++ //for bias
|
if bias >= 0 {
|
||||||
|
nonZeroElementsInRow++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nonZeroRowElements[i] = C.int(nonZeroElementsInRow)
|
||||||
|
totalElements += nonZeroElementsInRow
|
||||||
|
}
|
||||||
|
// Allocate one feature vector for each row, total number
|
||||||
|
C.AllocateFeatureNodesForProblem(prob.c_prob, C.int(len(X)), C.int(totalElements), &nonZeroRowElements[0])
|
||||||
|
|
||||||
x_space := make([]C.struct_feature_node, n_elements+n_samples)
|
for i := 0; i < len(X); i++ {
|
||||||
|
nonZeroElementCounter := 0
|
||||||
cursor := 0
|
|
||||||
x := make([]*C.struct_feature_node, n_samples)
|
|
||||||
var c_x **C.struct_feature_node
|
|
||||||
|
|
||||||
for i := 0; i < n_samples; i++ {
|
|
||||||
x[i] = &x_space[cursor]
|
|
||||||
|
|
||||||
for j := 0; j < len(X[i]); j++ {
|
for j := 0; j < len(X[i]); j++ {
|
||||||
if X[i][j] != 0.0 {
|
if X[i][j] != 0.0 {
|
||||||
x_space[cursor].index = C.int(j + 1)
|
xSpace := C.GetFeatureNodeForIndex(prob.c_prob, C.int(i), C.int(nonZeroElementCounter))
|
||||||
x_space[cursor].value = C.double(X[i][j])
|
xSpace.index = C.int(j + 1)
|
||||||
cursor++
|
xSpace.value = C.double(X[i][j])
|
||||||
}
|
nonZeroElementCounter++
|
||||||
if bias > 0 {
|
|
||||||
x_space[cursor].index = C.int(0)
|
|
||||||
x_space[cursor].value = C.double(bias)
|
|
||||||
cursor++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x_space[cursor].index = C.int(-1)
|
if bias >= 0 {
|
||||||
cursor++
|
xSpace := C.GetFeatureNodeForIndex(prob.c_prob, C.int(i), C.int(nonZeroElementCounter))
|
||||||
|
xSpace.index = C.int(len(X[i]) + 1)
|
||||||
|
xSpace.value = C.double(bias)
|
||||||
|
nonZeroElementCounter++
|
||||||
|
}
|
||||||
|
xSpace := C.GetFeatureNodeForIndex(prob.c_prob, C.int(i), C.int(nonZeroElementCounter))
|
||||||
|
xSpace.index = C.int(-1)
|
||||||
|
xSpace.value = C.double(0)
|
||||||
}
|
}
|
||||||
c_x = &x[0]
|
|
||||||
return c_x
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,14 @@
|
|||||||
#ifndef _LIBLINEAR_H
|
#ifndef _LIBLINEAR_H
|
||||||
#define _LIBLINEAR_H
|
#define _LIBLINEAR_H
|
||||||
|
|
||||||
|
#define LIBLINEAR_VERSION 241
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int liblinear_version;
|
||||||
|
|
||||||
struct feature_node
|
struct feature_node
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
@ -19,7 +23,7 @@ struct problem
|
|||||||
double bias; /* < 0 if no bias term */
|
double bias; /* < 0 if no bias term */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR = 11, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL }; /* solver_type */
|
enum { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR = 11, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL, ONECLASS_SVM = 21 }; /* solver_type */
|
||||||
|
|
||||||
struct parameter
|
struct parameter
|
||||||
{
|
{
|
||||||
@ -32,6 +36,9 @@ struct parameter
|
|||||||
int *weight_label;
|
int *weight_label;
|
||||||
double* weight;
|
double* weight;
|
||||||
double p;
|
double p;
|
||||||
|
double nu;
|
||||||
|
double *init_sol;
|
||||||
|
int regularize_bias;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model
|
struct model
|
||||||
@ -42,10 +49,12 @@ struct model
|
|||||||
double *w;
|
double *w;
|
||||||
int *label; /* label of each class */
|
int *label; /* label of each class */
|
||||||
double bias;
|
double bias;
|
||||||
|
double rho; /* one-class SVM only */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model* train(const struct problem *prob, const struct parameter *param);
|
struct model* train(const struct problem *prob, const struct parameter *param);
|
||||||
void cross_validation(const struct problem *prob, const struct parameter *param, int nr_fold, double *target);
|
void cross_validation(const struct problem *prob, const struct parameter *param, int nr_fold, double *target);
|
||||||
|
void find_parameters(const struct problem *prob, const struct parameter *param, int nr_fold, double start_C, double start_p, double *best_C, double *best_p, double *best_score);
|
||||||
|
|
||||||
double predict_values(const struct model *model_, const struct feature_node *x, double* dec_values);
|
double predict_values(const struct model *model_, const struct feature_node *x, double* dec_values);
|
||||||
double predict(const struct model *model_, const struct feature_node *x);
|
double predict(const struct model *model_, const struct feature_node *x);
|
||||||
@ -57,6 +66,9 @@ struct model *load_model(const char *model_file_name);
|
|||||||
int get_nr_feature(const struct model *model_);
|
int get_nr_feature(const struct model *model_);
|
||||||
int get_nr_class(const struct model *model_);
|
int get_nr_class(const struct model *model_);
|
||||||
void get_labels(const struct model *model_, int* label);
|
void get_labels(const struct model *model_, int* label);
|
||||||
|
double get_decfun_coef(const struct model *model_, int feat_idx, int label_idx);
|
||||||
|
double get_decfun_bias(const struct model *model_, int label_idx);
|
||||||
|
double get_decfun_rho(const struct model *model_);
|
||||||
|
|
||||||
void free_model_content(struct model *model_ptr);
|
void free_model_content(struct model *model_ptr);
|
||||||
void free_and_destroy_model(struct model **model_ptr_ptr);
|
void free_and_destroy_model(struct model **model_ptr_ptr);
|
||||||
@ -64,6 +76,8 @@ void destroy_param(struct parameter *param);
|
|||||||
|
|
||||||
const char *check_parameter(const struct problem *prob, const struct parameter *param);
|
const char *check_parameter(const struct problem *prob, const struct parameter *param);
|
||||||
int check_probability_model(const struct model *model);
|
int check_probability_model(const struct model *model);
|
||||||
|
int check_regression_model(const struct model *model);
|
||||||
|
int check_oneclass_model(const struct model *model);
|
||||||
void set_print_string_function(void (*print_func) (const char*));
|
void set_print_string_function(void (*print_func) (const char*));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -71,4 +85,3 @@ void set_print_string_function(void (*print_func) (const char*));
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _LIBLINEAR_H */
|
#endif /* _LIBLINEAR_H */
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package linear_models
|
package linear_models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLogisticRegression(t *testing.T) {
|
func TestLogisticRegression(t *testing.T) {
|
||||||
@ -24,14 +25,14 @@ func TestLogisticRegression(t *testing.T) {
|
|||||||
Z, err := lr.Predict(Y)
|
Z, err := lr.Predict(Y)
|
||||||
So(err, ShouldEqual, nil)
|
So(err, ShouldEqual, nil)
|
||||||
Convey("The result should be 1", func() {
|
Convey("The result should be 1", func() {
|
||||||
So(Z.RowString(0), ShouldEqual, "1.0")
|
So(Z.RowString(0), ShouldEqual, "1")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Convey("When predicting the label of second vector", func() {
|
Convey("When predicting the label of second vector", func() {
|
||||||
Z, err := lr.Predict(Y)
|
Z, err := lr.Predict(Y)
|
||||||
So(err, ShouldEqual, nil)
|
So(err, ShouldEqual, nil)
|
||||||
Convey("The result should be -1", func() {
|
Convey("The result should be -1", func() {
|
||||||
So(Z.RowString(1), ShouldEqual, "-1.0")
|
So(Z.RowString(1), ShouldEqual, "0")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -3,6 +3,7 @@ package linear_models
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package linear_models
|
package linear_models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLogistic(t *testing.T) {
|
func TestLogistic(t *testing.T) {
|
||||||
@ -23,14 +24,14 @@ func TestLogistic(t *testing.T) {
|
|||||||
Z, err := lr.Predict(Y)
|
Z, err := lr.Predict(Y)
|
||||||
So(err, ShouldEqual, nil)
|
So(err, ShouldEqual, nil)
|
||||||
Convey("The result should be 1", func() {
|
Convey("The result should be 1", func() {
|
||||||
So(Z.RowString(0), ShouldEqual, "-1.0")
|
So(Z.RowString(0), ShouldEqual, "1")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Convey("When predicting the label of second vector", func() {
|
Convey("When predicting the label of second vector", func() {
|
||||||
Z, err := lr.Predict(Y)
|
Z, err := lr.Predict(Y)
|
||||||
So(err, ShouldEqual, nil)
|
So(err, ShouldEqual, nil)
|
||||||
Convey("The result should be -1", func() {
|
Convey("The result should be 2", func() {
|
||||||
So(Z.RowString(1), ShouldEqual, "-1.0")
|
So(Z.RowString(1), ShouldEqual, "0")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
So((*lr).String(), ShouldEqual, "LogisticRegression")
|
So((*lr).String(), ShouldEqual, "LogisticRegression")
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
1.0,1.0,0.0,0.0,1.0
|
6,148,72,35,0,33.6,0.627,50,1
|
||||||
0.0,0.0,1.0,1.0,-1.0
|
1,85,66,29,0,26.6,0.351,31,0
|
|
Binary file not shown.
@ -1,4 +1,21 @@
|
|||||||
0.0, 0.0, 0.0, 1.0, -1.0
|
6,148,72,35,0,33.6,0.627,50,1
|
||||||
0.0, 0.0, 1.0, 0.0, -1.0
|
1,85,66,29,0,26.6,0.351,31,0
|
||||||
0.0, 1.0, 0.0, 0.0, 1.0
|
8,183,64,0,0,23.3,0.672,32,1
|
||||||
1.0, 0.0, 0.0, 0.0, 1.0
|
1,89,66,23,94,28.1,0.167,21,0
|
||||||
|
0,137,40,35,168,43.1,2.288,33,1
|
||||||
|
5,116,74,0,0,25.6,0.201,30,0
|
||||||
|
3,78,50,32,88,31,0.248,26,1
|
||||||
|
10,115,0,0,0,35.3,0.134,29,0
|
||||||
|
2,197,70,45,543,30.5,0.158,53,1
|
||||||
|
8,125,96,0,0,0,0.232,54,1
|
||||||
|
4,110,92,0,0,37.6,0.191,30,0
|
||||||
|
10,168,74,0,0,38,0.537,34,1
|
||||||
|
10,139,80,0,0,27.1,1.441,57,0
|
||||||
|
1,189,60,23,846,30.1,0.398,59,1
|
||||||
|
5,166,72,19,175,25.8,0.587,51,1
|
||||||
|
7,100,0,0,0,30,0.484,32,1
|
||||||
|
0,118,84,47,230,45.8,0.551,31,1
|
||||||
|
7,107,74,0,0,29.6,0.254,31,1
|
||||||
|
1,103,30,38,83,43.3,0.183,33,0
|
||||||
|
1,115,70,30,96,34.6,0.529,32,1
|
||||||
|
3,126,88,41,235,39.3,0.704,27,0
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user