Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
411143e
Merge branch 'travis' into kevinbfry-debias_lasso_linear
jonathan-taylor Aug 9, 2017
1672cee
Merge pull request #24 from kevinbfry/debias_lasso_linear
tibshirani Aug 9, 2017
be89769
Merge branch 'master' of github.com:selective-inference/R-software in…
jonathan-taylor Aug 16, 2017
248ce54
C code for one row of M
jonathan-taylor Aug 16, 2017
4d67199
added a warning about feasibility -- but it didn't print in gist?
jonathan-taylor Aug 16, 2017
e87d12d
removed print statement
jonathan-taylor Aug 16, 2017
210d0fe
using C for each row
jonathan-taylor Aug 16, 2017
c7c41e4
optimized the C code a bit -- still has debug statements
jonathan-taylor Aug 16, 2017
f6ae738
removing debug statements, making objective computation faster
jonathan-taylor Aug 16, 2017
2bd33e8
Merge pull request #18 from jonathan-taylor/master
tibshirani Aug 16, 2017
1a8e2ad
slightly lower tolerance
jonathan-taylor Aug 16, 2017
c391bd3
using active sets
jonathan-taylor Aug 16, 2017
096b0b8
begun the Rcpp extension
jonathan-taylor Aug 17, 2017
5bf8018
don't lose this
jonathan-taylor Aug 17, 2017
944ae7d
segfaulting on the test_big.R :(
jonathan-taylor Aug 17, 2017
f53af23
success -- about 2ms now -- python still faster (as timed through rpy…
jonathan-taylor Aug 17, 2017
7920c8c
BF: column major, removing print statements
jonathan-taylor Aug 17, 2017
6756ab2
changing name of function, evaluation of feasibility in Rcpp
jonathan-taylor Aug 17, 2017
0e58435
RF: renamed C function, removing R solver for one row
jonathan-taylor Aug 17, 2017
0614305
need to make Rcpp exports
jonathan-taylor Aug 17, 2017
ca60bc9
ignore first two lines if status not OK?
jonathan-taylor Aug 17, 2017
60f6cde
install Rcpp earlier
jonathan-taylor Aug 17, 2017
c1aef63
using Rcpp for matrixcomps as well -- update1 and downdate1 -- exampl…
jonathan-taylor Aug 17, 2017
f468510
using a warm start if available
jonathan-taylor Aug 17, 2017
a8805b8
trying to find segfault
jonathan-taylor Aug 18, 2017
abf0351
BF: order of arguments to is_active, renamed the function as well
jonathan-taylor Aug 18, 2017
27af0d5
removing debug statements
jonathan-taylor Aug 18, 2017
d487526
BF: percent signs in example
jonathan-taylor Aug 18, 2017
7360386
smaller changes in mu per step in line search
jonathan-taylor Aug 18, 2017
a9a8bbb
renaming Sigma_theta to gradient, making sure we loop through active set
jonathan-taylor Aug 18, 2017
7f1e4a6
more renaming
jonathan-taylor Aug 18, 2017
a4055ce
BF: forgot to rename in Rcpp file, passing active and ever_active from R
jonathan-taylor Aug 18, 2017
f432b42
more renaming
jonathan-taylor Aug 18, 2017
fcd8206
trying to get arbitrary linfunc
jonathan-taylor Aug 18, 2017
a67d29f
can solve arbitrary LASSO now
jonathan-taylor Aug 18, 2017
d248a8f
BF: updating active set
jonathan-taylor Aug 18, 2017
aa515c9
cosmetic change
jonathan-taylor Aug 18, 2017
5d5e8f3
BF: fixing function signatures
jonathan-taylor Aug 18, 2017
d1debcd
BF: fixing function signatures
jonathan-taylor Aug 18, 2017
15762af
BF: KKT wrong for active conditions, still have debug statements
jonathan-taylor Aug 18, 2017
9872b45
removing debug statements
jonathan-taylor Aug 18, 2017
be84df2
BF: KKT condition was wrong
jonathan-taylor Aug 18, 2017
0de59af
lenient tolerance
jonathan-taylor Aug 18, 2017
190c0a0
added a few targets to makefile
jonathan-taylor Aug 18, 2017
2c4cf3a
not checking objective
jonathan-taylor Aug 18, 2017
9ebcaab
making Rcpp in Makevars now
jonathan-taylor Aug 19, 2017
735c4d6
trying without making Rcpp
jonathan-taylor Aug 19, 2017
0865d09
making new quadratic_program C file
jonathan-taylor Aug 19, 2017
bfad505
need to make Rcpp for travis
jonathan-taylor Aug 19, 2017
d65e437
BF: everything was thrown into active set
jonathan-taylor Aug 19, 2017
1237c78
both solvers working
jonathan-taylor Aug 19, 2017
3405f23
passing tol as argument; both solvers agree
jonathan-taylor Aug 20, 2017
8c956f8
making a choice for solver
jonathan-taylor Aug 20, 2017
93a9602
RF: ever_active is now 1-based indices to be more R like
jonathan-taylor Aug 20, 2017
b127083
added an argument to limit the number of times the linesearch runs
jonathan-taylor Aug 20, 2017
acbf82c
making it 10 tries as before
jonathan-taylor Aug 20, 2017
6dc80be
Merge pull request #26 from jonathan-taylor/using_Rcpp
jonathan-taylor Aug 21, 2017
1cc094e
Tried different eestimates of covariance
kevinbfry Oct 25, 2017
7de4f28
Trying stuff with full target logistic
kevinbfry Apr 4, 2018
bd12151
Removed comments
kevinbfry Apr 4, 2018
9112cc2
Small cleanup for funs.fixed.R
kevinbfry Apr 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ r:
- devel
addons:
apt:
packages: libmpfr-dev
packages: libmpfr-dev
warnings_are_errors: true
before_install:
- tlmgr install index # for texlive and vignette?
- R -e 'install.packages("Rcpp", repos="http://cloud.r-project.org")'
- make Rcpp
- cd selectiveInference
3 changes: 3 additions & 0 deletions C-software/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This repo contains C code relevant for selective inference: http://github.com/selective-inference

This code is meant to be used by R, python, etc. for the basic operations needed for selective inference.
79 changes: 79 additions & 0 deletions C-software/src/debias.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

void multiply_by_2(double *X, int nval);

int solve_qp(double *nndef_ptr, /* A non-negative definite matrix */
double *linear_func_ptr, /* Linear term in objective */
double *nndef_diag_ptr, /* Diagonal of nndef */
double *gradient_ptr, /* nndef times theta */
int *ever_active_ptr, /* Ever active set: 1-based */
int *nactive_ptr, /* Size of ever active set */
int nfeature, /* How many features in nndef */
double bound, /* feasibility parameter */
double *theta, /* current value */
double *theta_old, /* previous value */
int maxiter, /* max number of iterations */
double kkt_tol, /* precision for checking KKT conditions */
double objective_tol, /* precision for checking relative decrease in objective value */
double parameter_tol, /* precision for checking relative convergence of parameter */
int max_active, /* Upper limit for size of active set -- otherwise break */
int kkt_stop, /* Break based on KKT? */
int objective_stop, /* Break based on convergence of objective value? */
int param_stop); /* Break based on parameter convergence? */

int check_KKT_qp(double *theta, /* current theta */
double *gradient_ptr, /* nndef times theta + linear_func */
int nrow, /* how many rows in nndef */
double bound, /* Lagrange multipler for \ell_1 */
double tol); /* precision for checking KKT conditions */

int solve_wide(double *X_ptr, /* Sqrt of non-neg def matrix -- X^TX/ncase = nndef */
double *X_theta_ptr, /* Fitted values */
double *linear_func_ptr, /* Linear term in objective */
double *nndef_diag_ptr, /* Diagonal entries of non-neg def matrix */
double *gradient_ptr, /* X^TX/ncase times theta + linear_func*/
int *need_update_ptr, /* Keeps track of updated gradient coords */
int *ever_active_ptr, /* Ever active set: 1-based */
int *nactive_ptr, /* Size of ever active set */
int ncase, /* How many rows in X */
int nfeature, /* How many columns in X */
double *bound_ptr, /* Lagrange multipliers */
double ridge_term, /* Ridge / ENet term */
double *theta_ptr, /* current value */
double *theta_old_ptr, /* previous value */
int maxiter, /* max number of iterations */
double kkt_tol, /* precision for checking KKT conditions */
double objective_tol, /* precision for checking relative decrease in objective value */
double parameter_tol, /* precision for checking relative convergence of parameter */
int max_active, /* Upper limit for size of active set -- otherwise break */
int kkt_stop, /* Break based on KKT? */
int objective_stop, /* Break based on convergence of objective value? */
int param_stop); /* Break based on parameter convergence? */

int check_KKT_wide(double *theta_ptr, /* current theta */
double *gradient_ptr, /* X^TX/ncase times theta + linear_func*/
double *X_theta_ptr, /* Current fitted values */
double *X_ptr, /* Sqrt of non-neg def matrix -- X^TX/ncase = nndef */
double *linear_func_ptr, /* Linear term in objective */
int *need_update_ptr, /* Which coordinates need to be updated? */
int nfeature, /* how many columns in X */
int ncase, /* how many rows in X */
double *bound_ptr, /* Lagrange multiplers for \ell_1 */
double ridge_term, /* Ridge / ENet term */
double tol); /* precision for checking KKT conditions */

void update_gradient_wide(double *gradient_ptr, /* X^TX/ncase times theta + linear_func */
double *X_theta_ptr, /* Current fitted values */
double *X_ptr, /* Sqrt of non-neg def matrix -- X^TX/ncase = nndef */
double *linear_func_ptr, /* Linear term in objective */
int *need_update_ptr, /* Which coordinates need to be updated? */
int nfeature, /* how many columns in X */
int ncase); /* how many rows in X */


#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
261 changes: 261 additions & 0 deletions C-software/src/matrixcomps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
#include <R.h>
#include <Rmath.h>

// Matrices are stored as vectors, in column-major order

// Givens rotation of a and b, stored in c and s
void givens(double a, double b, double *c, double *s) {
if (b==0) {
*c = 1;
*s = 0;
}
else {
if (fabs(b)>fabs(a)) {
double t = -a/b;
*s = 1/sqrt(1+t*t);
*c = (*s)*t;
}
else {
double t = -b/a;
*c = 1/sqrt(1+t*t);
*s = (*c)*t;
}
}
}

// Givens rotation applied to rows i1 and i2 of the m x n
// matrix A, on the subset of columns j1 through j2
void rowrot(double *A, int i1, int i2, int m, int n, int j1, int j2, double c, double s) {
int j;
double t1,t2;
for (j=j1; j<=j2; j++) {
t1 = A[i1+j*m];
t2 = A[i2+j*m];
A[i1+j*m] = c*t1-s*t2;
A[i2+j*m] = s*t1+c*t2;
}
}

// Givens rotation applied to columns j1 and j2 of the m x n
// matrix A, on the subset of rows i1 through i2
void colrot(double *A, int j1, int j2, int m, int n, int i1, int i2, double c, double s) {
int i;
double t1,t2;
for (i=i1; i<=i2; i++) {
t1 = A[i+j1*m];
t2 = A[i+j2*m];
A[i+j1*m] = c*t1-s*t2;
A[i+j2*m] = s*t1+c*t2;
}
}

// Downdate the QR factorization after deleting column j0,
// where Q1 is m x n and R is n x n. The other part of
// the Q matrix, Q2 m x (m-n), isn't needed so it isn't
// passed for efficiency
void downdate1(double *Q1, double *R, int j0, int m, int n) {
int j;

double c,s;
for (j=j0+1; j<n; j++) {
// Compute the appropriate c and s
givens(R[j-1+j*n],R[j+j*n],&c,&s);

// Pre-multiply R
rowrot(R,j-1,j,n,n,j,n-1,c,s);

// Post-mutiply Q1
colrot(Q1,j-1,j,m,n,0,m-1,c,s);
}
}

// Update the QR factorization after adding a column z.
// For convenience, we are given w=Q2'z. Here Q2 is m x
// (m-n). The other part of the Q matrix, Q1 m x n, and
// R are not needed, so they aren't passed for efficiency
void update1(double *Q2, double *w, int m, int k) {
int j;

double c,s;
for (j=k-1; j>=1; j--) {
// Compute the appropriate c and s
givens(w[j-1],w[j],&c,&s);

// Pre-multiply w
rowrot(w,j-1,j,k,1,0,0,c,s);

// Post-multiply Q2
colrot(Q2,j-1,j,m,k,0,m-1,c,s);
}
}

// Downdate the QR factorization after deleting the first row,
// where Q is m x m and R is m x n
void downdate2(double *Q, double *R, int *mp, int *np) {
int m,n,i;
m = *mp;
n = *np;

double c,s;
for (i=m-1; i>=1; i--) {
// Compute the appropriate c and s
givens(Q[(i-1)*m],Q[i*m],&c,&s);

// Post-mutiply Q
colrot(Q,i-1,i,m,m,0,m-1,c,s);

// Pre-multiply R
if (i<=n) rowrot(R,i-1,i,m,n,i-1,n-1,c,s);
}
}

// Update the QR factorization after adding the last row,
// where Q is m x m and R is m x n. For efficiency, Q is not
// passed, and only the first row of R is passed. Not counting
// its first row, the first q columns of R are zero
void update2(double *y, double *D, double *r, int *mp, int *np, int *qp) {
int m,n,q,j;
m = *mp;
n = *np;
q = *qp;

double c,s;
for (j=0; j<q-1; j++) {
// Compute the appropriate c and s
givens(r[j+1],r[j],&c,&s);

// Pre-multiply r
rowrot(r,j+1,j,n,1,0,0,c,s);

// Post-mutiply D
colrot(D,j+1,j,m,n,0,m-1,c,s);

// Pre-multiply y
rowrot(y,j+1,j,n,1,0,0,c,s);
}
}

// Make the R factor upper triangular, by Givens rotating its
// columns. Here A is m x n, and R is n x n with rank(R) = n-k
void maketri1(double *y, double *A, double *R, int *mp, int *np, int *kp) {
int m,n,k,i,j;
m = *mp;
n = *np;
k = *kp;

double c,s;
for (i=n-k-1; i>=0; i--) {
for (j=i; j<i+k; j++) {
// Compute the appropriate c and s
givens(R[i+(j+1)*n],R[i+j*n],&c,&s);

// Post-multiply R
colrot(R,j+1,j,n,n,0,i,c,s);

// Post-multiply D
colrot(A,j+1,j,m,n,0,m-1,c,s);

// Pre-multiply y
rowrot(y,j+1,j,n,1,0,0,c,s);
}
}
}

// Make the R factor upper triangular, by Givens rotating its
// columns. Here A is m x n, and R is m x n with rank(R) = min(m,n)-k
void maketri2(double *y, double *A, double *R, int *mp, int *np, int *kp) {
int m,n,k,r,d,i,j;
m = *mp;
n = *np;
k = *kp;

r = imin2(m,n);
d = imax2(n-m,0);

double c,s;
for (i=r-k-1; i>=0; i--) {
for (j=i; j<i+k+d; j++) {
// Compute the appropriate c and s
givens(R[i+(j+1)*m],R[i+j*m],&c,&s);

// Post-multiply R
colrot(R,j+1,j,m,n,0,i,c,s);

// Post-multiply D
colrot(A,j+1,j,m,n,0,m-1,c,s);

// Pre-multiply y
rowrot(y,j+1,j,n,1,0,0,c,s);
}
}
}

// Make the R factor upper triangular, by Givens rotating
// its columns. Here A is m1 x n, and R is m2 x n with
// rank(R) = n-q-1. The first q columns of R are zero
void maketri3(double *y, double *A, double *R, int *m1p, int *m2p, int *np, int *qp) {
int m1,m2,n,q,i;
m1 = *m1p;
m2 = *m2p;
n = *np;
q = *qp;

double c,s;
for (i=n-q-2; i>=0; i--) {
// Compute the appropriate c and s
givens(R[i+(i+q+1)*m2],R[i+(i+q)*m2],&c,&s);

// Post-multiply R
colrot(R,i+q+1,i+q,m2,n,0,i,c,s);

// Post-multiply D
colrot(A,i+q+1,i+q,m1,n,0,m1-1,c,s);

// Pre-multiply y
rowrot(y,i+q+1,i+q,n,1,0,0,c,s);
}
}

// Make the R factor upper triangular, by Givens rotating
// its columns and rows, appropriately. Here A is m1 x n,
// Q is m2 x m2, and R is m2 x n with rank(R) = n-q-1. The
// first q columns of R are zero. The kth row of R is the
// last row with a zero element on the diagonal
void maketri4(double *y, double *A, double *Q, double *R, int *m1p, int *m2p, int *np, int *qp, int *kp) {
int m1,m2,n,q,k,i,j;
m1 = *m1p;
m2 = *m2p;
n = *np;
q = *qp;
k = *kp;

double c,s;

// First rotate the columns
for (i=k-1; i>=0; i--) {
// Compute the appropriate c and s
givens(R[i+(i+q+1)*m2],R[i+(i+q)*m2],&c,&s);

// Post-multiply R
colrot(R,i+q+1,i+q,m2,n,0,i,c,s);

// Post-multiply D
colrot(A,i+q+1,i+q,m1,n,0,m1-1,c,s);

// Pre-multiply y
rowrot(y,i+q+1,i+q,n,1,0,0,c,s);
}

// Next rotate the rows
for (j=k+q+1; j<n; j++) {
// Compute the appropriate c and s
givens(R[j-q-1+j*m2],R[j-q+j*m2],&c,&s);

// Pre-multiply R
rowrot(R,j-q-1,j-q,m2,n,j,n-1,c,s);

// Post-multiply Q
colrot(Q,j-q-1,j-q,m2,m2,0,m2-1,c,s);
}
}

12 changes: 12 additions & 0 deletions C-software/src/matrixcomps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

void update1(double *Q2, double *w, int m, int k);

void downdate1(double *Q1, double *R, int j0, int m, int n);

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
Loading