/** * @brief Default call to tf_admm. * Example of how to call tf_admm, taking only the response vector @p and * observation size @n as inputs. Users will likely need to adjust tf_admm_default * for their own needs, using it as a starting template. * @param y a vector of responses * @param n the length of y, i.e., the number of observations * @return Returns a pointer to beta values, a column oriented (nlambda x n) array. * @note The user is responsible for freeing the array pointed to by the response. */ double * tf_admm_default(double * y, int n) { int i; int j; double * x; double * w; int k; int family; int max_iter; int lam_flag; double * lambda; int nlambda; double lambda_min_ratio; double * beta; double * obj; int * iter; int * status; double rho; double obj_tol; double alpha_ls; double gamma_ls; int max_iter_ls; int max_iter_newton; int verbose; /* Set default constants */ k = 2; family = FAMILY_GAUSSIAN; max_iter = 200; lam_flag = 0; nlambda = 50; lambda_min_ratio = 1e-11; rho = 1; obj_tol = 1e-10; alpha_ls = 0.5; gamma_ls = 0.8; max_iter_ls = 20; max_iter_newton = 50; verbose = 0; /* Allocate space for input arrays */ x = (double *) malloc(n * sizeof(double)); w = (double *) malloc(n * sizeof(double)); lambda = (double *) malloc(nlambda * sizeof(double)); beta = (double *) malloc(nlambda * n * sizeof(double)); obj = (double *) malloc(nlambda * max_iter * sizeof(double)); iter = (int *) malloc(nlambda * sizeof(int)); status = (int *) malloc(nlambda * sizeof(int)); /* Fill x and w with default values */ for (i = 0; i < n; i++) { x[i] = i; w[i] = 1; } /* Initalize output arrays with 0's */ for (i = 0; i < nlambda; i++) { lambda[i] = 0; for (j = 0; j < n; j++) { beta[i + j*nlambda] = 0; } for (j = 0; j < max_iter; j++) { obj[i + j*nlambda] = 0; } iter[i] = 0; status[i] = 0; } tf_admm(y, x, w, n, k, family, max_iter, lam_flag, lambda, nlambda, lambda_min_ratio, beta, obj, iter, status, rho, obj_tol, alpha_ls, gamma_ls, max_iter_ls, max_iter_newton, verbose); /* Free allocated arrays (except beta; which is returned) */ free(x); free(w); free(lambda); free(obj); free(iter); free(status); return(beta); }
void test_admm_gauss(int mode) { int i; double * y; double * x; double * w; int n; int k; int family; int max_iter; int lam_flag; int obj_flag; double * lambda; int nlambda; double lambda_min_ratio; double * beta; double * pred; double * obj; int * iter; double rho; double obj_tol; double predict_zero_tol; /* Input parameters; will usually be given by parent function to tf_admm */ n = 8; k = 1; family = FAMILY_GAUSSIAN; max_iter = 5; lam_flag = 1; obj_flag = 1; nlambda = 1; lambda_min_ratio = 1e-4; rho = 1; obj_tol = 1e-12; y = (double *) malloc(n * sizeof(double)); x = (double *) malloc(n * sizeof(double)); w = (double *) malloc(n * sizeof(double)); lambda = (double *) malloc(nlambda * sizeof(double)); beta = (double *) malloc(n * nlambda * sizeof(double)); pred = (double *) malloc(n * sizeof(double)); obj = (double *) malloc(max_iter * nlambda * sizeof(double)); iter = (int *) malloc( nlambda * sizeof(int)); srand(5489); x[0] = 0; for (i = 1; i < n; i++) x[i] = x[i-1] + (rand() % 100)/100.; for (i = 0; i < n; i++) y[i] = x[i] * x[i] + 0.5 * (rand() % 100)/100.; for (i = 0; i < n; i++) w[i] = 0; lambda[0] = 1; /* Call the tf_admm function */ tf_admm(y, x, w, n, k, family, max_iter, lam_flag, obj_flag, lambda, nlambda, lambda_min_ratio, beta, obj, iter, rho, obj_tol); printf("\n--------------- (x,y) ---------------------------\n"); for (i = 0; i < n; i++) printf("%.3f\t%1.f\n", x[i], y[i]); printf("\n---------- lambda -------------------------------\n"); for (i = 0; i < nlambda; i++) printf("%f\n", lambda[i]); printf("\n---------- beta_1 -------------------------------\n"); for (i = 0; i < n; i++) printf("%f\n", beta[i]); /* printf("\n---------- beta_2 -------------------------------\n"); for (i = 0; i < n; i++) printf("%f\n", beta[i + n]); printf("\n---------- beta_3 -------------------------------\n"); for (i = 0; i < n; i++) printf("%f\n", beta[i + n*2]); */ predict_zero_tol = 1e-12; double err; for(i = 0; i < nlambda; i++) { int offset = i*n; tf_predict_gauss(beta + offset, x, n, k, x, n, pred, predict_zero_tol); err = max_diff(beta + offset, pred, n); printf("Prediction difference at input points=%E\n", err); if(!(err < 1e-12 )) printf("Prediction failed at input points (n=%d,k=%d,lam=%.4f,err=%E)\n",n,k,lambda[i], err); } /* Logistic loss */ family = FAMILY_LOGISTIC; double prob1, prob2; for (i = 0; i < n; i++) { prob1 = 1/ ( 1 + exp(-x[i]) ); prob2 = (rand() % 101)/100.; y[i] = prob1 <= prob2 ? 1 : 0; } printf("\n--------------- (x,y) ---------------------------\n"); for (i = 0; i < n; i++) printf("%.3f\t%1.f\n", x[i], y[i]); lambda[0] = 1e9; tf_admm(y, x, w, n, k, family, max_iter, lam_flag, obj_flag, lambda, nlambda, lambda_min_ratio, beta, obj, iter, rho, obj_tol); printf("\n---------- lambda -------------------------------\n"); for (i = 0; i < nlambda; i++) printf("%f\n", lambda[i]); printf("\n---------- beta_1 (logistic) -----------------------\n"); for (i = 0; i < n; i++) printf("%f\n", beta[i]); /* Free the allocated arrays */ free(y); free(x); free(w); free(lambda); free(beta); free(obj); free(iter); free(pred); }