void test_resize() { matrix_type * m1 = matrix_alloc(5,5); matrix_type * m2 = matrix_alloc(5,5); rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT ); matrix_random_init( m1 , rng ); matrix_assign( m2 , m1 ); test_assert_true( matrix_equal( m1 , m2 )); matrix_resize( m1 , 5 , 5 , false ); test_assert_true( matrix_equal( m1 , m2 )); matrix_resize( m1 , 5 , 5 , true ); test_assert_true( matrix_equal( m1 , m2 )); rng_free( rng ); matrix_free( m1 ); matrix_free( m2 ); }
matrix_type * matrix_realloc_copy(matrix_type * T , const matrix_type * src) { if (T == NULL) return matrix_alloc_copy( src ); else { matrix_resize( T , src->rows , src->columns , false ); matrix_assign( T , src ); return T; } }
void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A , const bool_vector_type * ens_mask ) { matrix_resize( state , matrix_get_rows( A ) , bool_vector_size( ens_mask ) , false); { const int ens_size = bool_vector_size( ens_mask ); int active_index = 0; for (int iens = 0; iens < ens_size; iens++) { if (bool_vector_iget( ens_mask , iens )) matrix_copy_column( state , A , iens , active_index ); else matrix_set_const_column( state , iens , 0); } } }
void test_create_data() { matrix_type * PC = matrix_alloc( 3 , 10); matrix_type * PC_obs = matrix_alloc( 3 , 1 ); double_vector_type * singular_values = double_vector_alloc(3 , 1); { pca_plot_data_type * data = pca_plot_data_alloc("KEY" , PC , PC_obs , singular_values); test_assert_true( pca_plot_data_is_instance( data )); test_assert_int_equal( 3 , pca_plot_data_get_size( data )); test_assert_int_equal( 10 , pca_plot_data_get_ens_size( data )); test_assert_string_equal( "KEY" , pca_plot_data_get_name( data )); pca_plot_data_free( data ); } matrix_resize( PC , 4 , 10 , false); test_assert_NULL( pca_plot_data_alloc( "KEY" , PC , PC_obs , singular_values)); matrix_resize( PC_obs , 3 , 2 , false); test_assert_NULL( pca_plot_data_alloc( "KEY" , PC , PC_obs , singular_values)); double_vector_free( singular_values ); matrix_free( PC ); matrix_free( PC_obs ); }
void rml_enkf_common_recover_state( const matrix_type * state , matrix_type * A , const bool_vector_type * ens_mask ) { const int ens_size = bool_vector_size( ens_mask ); const int active_size = bool_vector_count_equal( ens_mask , true ); const int rows = matrix_get_rows( state ); matrix_resize( A , rows , active_size , false ); { int active_index = 0; for (int iens = 0; iens < ens_size; iens++) { if (bool_vector_iget( ens_mask , iens )) matrix_copy_column( A , state , active_index , iens ); } } }
void lp_add_slacks(LP* lp) { char buf[LP_NAME_LEN_MAX]; int i, j; for (i = 0; i < lp->vars; i ++) { if (is_const_var(lp, i) || !vector_element_is_zero(lp->c, i) || lp->A->column[i]->nonzeros != 1) continue; j = lp->A->column[i]->i[0]; if (lp->row_equality[j] != LP_EQUALITY_LE) continue; if (mpq_sgn(*matrix_get_element_ptr(lp->A, j, i)) > 0 && lp->upper.is_valid[i]) continue; if (mpq_sgn(*matrix_get_element_ptr(lp->A, j, i)) < 0 && lp->lower.is_valid[i]) continue; lp->row_equality[j] = LP_EQUALITY_EQ; } j = 0; for (i = 0; i < lp->rows; i ++) { if (lp->row_equality[i] == LP_EQUALITY_LE) j ++; } matrix_resize(lp->A, lp->rows, lp->vars+j); for (i = 0; i < lp->rows; i ++) { if (lp->row_equality[i] == LP_EQUALITY_LE) { if(lp->row_name != NULL) { strncpy(buf, "#S", LP_NAME_LEN_MAX); strncat(buf, lp->row_name[i], LP_NAME_LEN_MAX); j = lp_add_var_without_A(lp, buf); } else j = lp_add_var_without_A(lp, NULL); lp_add_slackref(lp, i+1); lp->var_type[j] = LP_VAR_TYPE_SLACK; lp_set_coefficient(lp, mympq_one, i, j); lp->row_equality[i] = LP_EQUALITY_EQ; } } }
int main(int argc, char ** argv) { Settings settings(argc, argv); if (settings.is_exit) return 0; int N = settings.count; int start = settings.start; Loader l(settings.input, start); Saver s(settings.output, PNG); for (int i = 0; i < N; i++) { cv::Mat mat = matrix_resize(l.load(), settings.width, settings.height); s.save(mat); print_progress(i, N); } return 0; }
void matrix_fread(matrix_type * matrix , FILE * stream) { int rows = util_fread_int( stream ); int columns = util_fread_int( stream ); matrix_resize( matrix , rows , columns , false); if (matrix->column_stride == matrix->rows) util_fread( matrix->data , sizeof * matrix->data , matrix->columns * matrix->rows , stream , __func__); else { int column; for (column=0; column < matrix->columns; column++) { if (matrix->row_stride == 1) { double * column_data = &matrix->data[ column * matrix->column_stride ]; util_fread( column_data , sizeof * column_data , matrix->rows , stream , __func__); } else { int row; for (row=0; row < matrix->rows; row++) matrix->data[ GET_INDEX( matrix , row , column )] = util_fread_double( stream ); } } } }
void matrix_ensure_rows(matrix_type * matrix, int rows, bool copy_content) { if (matrix->rows < rows) matrix_resize( matrix , rows , matrix->columns , copy_content); }
static void update_evidence_grid(carmen_shape_p contour, int *laser_mask, double resolution, double laser_stdev) { double xmin, xmax, ymin, ymax; double dx, dy, dmax; double *ux, *uy; double **mask; int i, j, x, y, x0, x1, y0, y1; int new_x_size, new_y_size; int mask_x_size, mask_y_size, mask_ux, mask_uy; int mask_x0, mask_x1, mask_y0, mask_y1; int x_offset, y_offset; double ltheta; printf("update_evidence_grid()\n"); ux = contour->x; uy = contour->y; // find bounds for contour's evidence grid xmin = xmax = ux[0]; ymin = ymax = uy[0]; for (i = 1; i < contour->num_points; i++) { if (ux[i] > xmax) xmax = ux[i]; else if (ux[i] < xmin) xmin = ux[i]; if (uy[i] > ymax) ymax = uy[i]; else if (uy[i] < ymin) ymin = uy[i]; } // give a buffer for the egrid xmin -= 2 * EGRID_MASK_STDEV_MULT * laser_stdev; ymin -= 2 * EGRID_MASK_STDEV_MULT * laser_stdev; xmax += 2 * EGRID_MASK_STDEV_MULT * laser_stdev; ymax += 2 * EGRID_MASK_STDEV_MULT * laser_stdev; new_x_size = floor((xmax-xmin) / resolution); new_y_size = floor((ymax-ymin) / resolution); //egrid_x_offset = -xmin; //egrid_y_offset = -ymin; if (egrid == NULL) { // new egrid egrid = new_matrix(egrid_x_size, egrid_y_size); egrid_counts = new_imatrix(egrid_x_size, egrid_y_size); egrid_hits = new_imatrix(egrid_x_size, egrid_y_size); for (i = 0; i < egrid_x_size; i++) { for (j = 0; j < egrid_y_size; j++) { egrid_counts[i][j] = egrid_hits[i][j] = 0; egrid[i][j] = -1.0; } } egrid_x_size = new_x_size; egrid_y_size = new_y_size; egrid_x_offset = -xmin; egrid_y_offset = -ymin; } else { // resize x0 = floor((xmin - egrid_x_offset)/resolution); x1 = floor((xmax - egrid_x_offset)/resolution) + 1; y0 = floor((ymin - egrid_y_offset)/resolution); y1 = floor((ymax - egrid_y_offset)/resolution) + 1; if (x0 < 0 || x1 > egrid_x_size || y0 < 0 || y1 > egrid_y_size) { x0 = MAX(-x0, 0); x1 = MAX(x1, egrid_x_size); y0 = MAX(-y0, 0); y1 = MAX(y1, egrid_y_size); egrid = matrix_resize(egrid, x0, y0, egrid_x_size, egrid_y_size, x0+x1, y0+y1, -1.0); egrid_counts = imatrix_resize(egrid_counts, x0, y0, egrid_x_size, egrid_y_size, x0+x1, y0+y1, 0); egrid_hits = imatrix_resize(egrid_hits, x0, y0, egrid_x_size, egrid_y_size, x0+x1, y0+y1, 0); egrid_x_size = x0 + x1; egrid_y_size = y0 + y1; egrid_x_offset -= x0*resolution; egrid_y_offset -= y0*resolution; } } // trace laser for (i = 0; i < laser_msg.num_readings; i++) { ltheta = carmen_normalize_theta(laser->theta + (i-90)*M_PI/180.0); trace_laser_beam(laser->x, laser->y, ltheta, laser->range[i], laser_mask[i]); } /***************************** dbug ********************************** for (i = 0; i < egrid_x_size; i++) for (j = 0; j < egrid_y_size; j++) egrid[i][j] = LOW_LOG_PROB; // create a log prob mask of odd dimensions (so there will be a unique center cell) mask_x_size = floor(2 * EGRID_MASK_STDEV_MULT * laser_stdev / resolution); if (mask_x_size % 2 == 0) mask_x_size++; mask_y_size = floor(2 * EGRID_MASK_STDEV_MULT * laser_stdev / resolution); if (mask_y_size % 2 == 0) mask_y_size++; mask_ux = floor(mask_x_size / 2.0); mask_uy = floor(mask_y_size / 2.0); //printf("mask_size = (%d %d)\n", mask_x_size, mask_y_size); mask = new_matrix(mask_x_size, mask_y_size); dmax = mask_x_size*mask_x_size*resolution*resolution/4.0; for (i = 0; i < mask_x_size; i++) { dx = (i - mask_ux) * resolution; for (j = 0; j < mask_y_size; j++) { dy = (j - mask_uy) * resolution; if (dx*dx+dy*dy <= dmax) // circular mask mask[i][j] = -(dx*dx+dy*dy) / (2 * laser_stdev * laser_stdev); else mask[i][j] = LOW_LOG_PROB; } } for (i = 0; i < contour->num_points; i++) { x = floor((ux[i] - xmin) / resolution); y = floor((uy[i] - ymin) / resolution); if (x < 0 || x >= egrid_x_size || y < 0 || y >= egrid_y_size) { carmen_warn("Warning: contour point out of evidence grid bounds in get_evidence_grid()\n"); continue; } mask_x0 = MAX(0, x + (mask_ux+1) - mask_x_size); mask_x1 = MIN(egrid_x_size - 1, x - mask_ux + mask_x_size); mask_y0 = MAX(0, y + (mask_uy+1) - mask_y_size); mask_y1 = MIN(egrid_y_size - 1, y - mask_uy + mask_y_size); x_offset = mask_ux - x; y_offset = mask_uy - y; for (x = mask_x0; x < mask_x1; x++) for (y = mask_y0; y < mask_y1; y++) if (egrid[x][y] < mask[x+x_offset][y+y_offset]) egrid[x][y] = mask[x+x_offset][y+y_offset]; } free(mask); //*egrid_x_offset = -xmin; //*egrid_y_offset = -ymin; //*egrid_x_size_ptr = egrid_x_size; //*egrid_y_size_ptr = egrid_y_size; ***************************** end dbug *****************************/ return egrid; }
void lp_add_artificials(LP* lp) { mpq_t q1, q2, q3, best; char buf[LP_NAME_LEN_MAX]; int i, j, k, l, m, x, best_var; mpq_init(q1); mpq_init(q2); mpq_init(q3); mpq_init(best); vector_zero_clear(lp->c); vector_zero_clear(lp->cb); x = lp_select_basis(lp); for (i = 0; i < lp->rows; i ++) { if (lp->basis_column[i] != -1) continue; get_valid_rhs(&q1, lp, i); if (mpq_sgn(q1) < 0) { matrix_rev_row_sgn(lp->A, i); vector_rev_element_sgn(lp->b, i); mpq_neg(q1, q1); } best_var = -1; for (m = 0; m < lp->A->row[i]->nonzeros; m ++) { j = lp->A->row[i]->i[m]; if (!is_normal_var(lp, j) || lp->is_basis[j] || lp->A->column[j]->nonzeros == 0) continue; if (vector_get_first_nonzero_i(lp->A->column[j]) != i) continue; if (mpq_sgn(*vector_get_element_ptr(lp->x, j))) continue; mympq_div(q2, q1, *vector_get_element_ptr(lp->A->column[j], i)); if ((lp->upper.is_valid[j] && mpq_cmp(lp->upper.bound[j], q2) < 0) || (lp->lower.is_valid[j] && mpq_cmp(lp->lower.bound[j], q2) > 0)) continue; if (mpq_sgn(q2)) { l = 0; for (k = 0; k < lp->A->column[j]->nonzeros; k ++) { if (lp->basis_column[lp->A->column[j]->i[k]] == -1 || lp->A->column[j]->i[k] == i) continue; l = 1; break; } if (l) continue; } vector_get_element(&q3, lp->c_back, j); mympq_mul(q3, q3, q2); //if (!lp->maximize) // mpq_neg(q3, q3); if (best_var >= 0 && mpq_cmp(best, q3) >= 0) continue; best_var = j; mpq_set(best, q3); } if (best_var < 0) continue; x ++; j = best_var; mympq_div(q2, q1, *vector_get_element_ptr(lp->A->column[j], vector_get_first_nonzero_i(lp->A->column[j]))); lp->is_basis[j] = TRUE; lp->basis_column[i] = j; vector_set_element(lp->x, q2, j); vector_set_element(lp->xb, q2, i); } matrix_resize(lp->A, lp->rows, lp->vars + lp->rows - x); for (i = 0; i < lp->rows; i ++) { if (lp->basis_column[i] >= 0) continue; get_valid_rhs(&q1, lp, i); if(lp->var_name == NULL) j = lp_add_var_without_A(lp, NULL); else { strncpy(buf, "#A", LP_NAME_LEN_MAX); strncat(buf, lp->row_name[i], LP_NAME_LEN_MAX); j = lp_add_var_without_A(lp, buf); } lp_add_slackref(lp, -(i+1)); lp->var_type[j] = LP_VAR_TYPE_ARTIFICIAL; lp->basis_column[i] = j; lp->is_basis[j] = TRUE; lp_set_coefficient(lp, mympq_one, i, j); vector_set_element(lp->x, q1, j); vector_set_element(lp->xb, q1, i); vector_set_element(lp->c, mympq_minus_one, j); vector_set_element(lp->cb, mympq_minus_one, i); } #if 0 lp->vars = MIN(lp->vars, lp->A->columns); #endif mpq_clear(q1); mpq_clear(q2); mpq_clear(q3); mpq_clear(best); }
void lp_resize(LP* lp, int rows, int columns, int usenames) { int i, oldrows = lp->rows, oldvars = lp->vars; char buf[LP_NAME_LEN_MAX]; /* Row data */ lp->rows = rows; if(usenames) { lp->row_name = my_realloc(lp->row_name, lp->rows*sizeof(char*)); for(i = oldrows; i < rows; i ++) { snprintf(buf, LP_NAME_LEN_MAX, "r%d", i + 1); lp->row_name[i] = my_malloc(strlen(buf)+1); hash_str_find(lp->hash_str_row_name, buf, lp->row_name, i); } } lp->row_equality = my_realloc(lp->row_equality, lp->rows*sizeof(int)); lp->basis_column = my_realloc(lp->basis_column, lp->rows*sizeof(int)); for(i = oldrows; i < rows; i ++) { lp_set_row_equality(lp, i, LP_EQUALITY_EQ); lp->basis_column[i] = 0; } /* Column data */ lp->vars = columns; if(usenames) { lp->var_name = my_realloc(lp->var_name, lp->vars*sizeof(char*)); for(i = oldvars; i < columns; i ++) { snprintf(buf, LP_NAME_LEN_MAX, "v%d", i + 1); lp->var_name[i] = my_malloc(strlen(buf)+1); hash_str_find(lp->hash_str_var_name, buf, lp->var_name, i); } } lp->var_type = my_realloc(lp->var_type, lp->vars*sizeof(int)); vector_resize(lp->x, lp->vars); vector_resize(lp->c, lp->vars); vector_resize(lp->c_back, lp->vars); lp->is_basis = my_realloc(lp->is_basis, lp->vars*sizeof(int)); lp->is_integer = my_realloc(lp->is_integer, lp->vars*sizeof(int)); lp->upper.is_valid = my_realloc(lp->upper.is_valid, lp->vars*sizeof(int)); lp->lower.is_valid = my_realloc(lp->lower.is_valid, lp->vars*sizeof(int)); lp->upper.bound = my_realloc(lp->upper.bound, lp->vars*sizeof(mpq_t)); lp->lower.bound = my_realloc(lp->lower.bound, lp->vars*sizeof(mpq_t)); for(i = oldvars; i < columns; i ++) { lp->var_type[i] = LP_VAR_TYPE_NORMAL; lp->upper.is_valid[i] = FALSE; lp->lower.is_valid[i] = TRUE; mpq_init(lp->lower.bound[i]); } /* Matrix data */ matrix_resize(lp->A, lp->rows, lp->vars); #if 1 vector_resize(lp->b, lp->rows); vector_resize(lp->xb, lp->rows); vector_resize(lp->cb, lp->rows); #endif }
void lars_estimate(lars_type * lars , int max_vars , double max_beta , bool verbose) { int nvars = matrix_get_columns( lars->X ); int nsample = matrix_get_rows( lars->X ); matrix_type * X = matrix_alloc( nsample, nvars ); // Allocate local X and Y variables matrix_type * Y = matrix_alloc( nsample, 1 ); // which will hold the normalized data lars_estimate_init( lars , X , Y); // during the estimation process. { matrix_type * G = matrix_alloc_gram( X , true ); matrix_type * mu = matrix_alloc( nsample , 1 ); matrix_type * C = matrix_alloc( nvars , 1 ); matrix_type * Y_mu = matrix_alloc_copy( Y ); int_vector_type * active_set = int_vector_alloc(0,0); int_vector_type * inactive_set = int_vector_alloc(0,0); int active_size; if ((max_vars <= 0) || (max_vars > nvars)) max_vars = nvars; { int i; for (i=0; i < nvars; i++) int_vector_iset( inactive_set , i , i ); } matrix_set( mu , 0 ); while (true) { double maxC = 0; /* The first step is to calculate the correlations between the covariates, and the current residual. All the currently inactive covariates are searched; the covariate with the greatest correlation with (Y - mu) is selected and added to the active set. */ matrix_sub( Y_mu , Y , mu ); // Y_mu = Y - mu matrix_dgemm( C , X , Y_mu , true , false , 1.0 , 0); // C = X' * Y_mu { int i; int max_set_index = 0; for (i=0; i < int_vector_size( inactive_set ); i++) { int set_index = i; int var_index = int_vector_iget( inactive_set , set_index ); double value = fabs( matrix_iget(C , var_index , 0) ); if (value > maxC) { maxC = value; max_set_index = set_index; } } /* Remove element corresponding to max_set_index from the inactive set and add it to the active set: */ int_vector_append( active_set , int_vector_idel( inactive_set , max_set_index )); } active_size = int_vector_size( active_set ); /* Now we have calculated the correlations between all the covariates and the current residual @Y_mu. The correlations are stored in the matrix @C. The value of the maximum correlation is stored in @maxC. Based on the value of @maxC we have added one new covariate to the model, technically by moving the index from @inactive_set to @active_set. */ /*****************************************************************/ { matrix_type * weights = matrix_alloc( active_size , 1); double scale; /*****************************************************************/ /* This scope should compute and initialize the variables @weights and @scale. */ { matrix_type * subG = matrix_alloc( active_size , active_size ); matrix_type * STS = matrix_alloc( active_size , active_size ); matrix_type * sign_vector = matrix_alloc( active_size , 1); int i , j; /* STS = S' o S where 'o' is the Schur product and S is given by: [ s1 s2 s3 s4 ] S = [ s1 s2 s3 s4 ] [ s1 s2 s3 s4 ] [ s1 s2 s3 s4 ] Where si is the sign of the correlation between (active) variable 'i' and Y_mu. */ for (i=0; i < active_size ; i++) { int vari = int_vector_iget( active_set , i ); double signi = sgn( matrix_iget( C , vari , 0)); matrix_iset( sign_vector , i , 0 , signi ); for (j=0; j < active_size; j++) { int varj = int_vector_iget( active_set , j ); double signj = sgn( matrix_iget( C , varj , 0)); matrix_iset( STS , i , j , signi * signj ); } } // Extract the elements from G corresponding to active indices and // copy to the matrix subG: for (i=0; i < active_size ; i++) { int ii = int_vector_iget( active_set , i ); for (j=0; j < active_size; j++) { int jj = int_vector_iget( active_set , j ); matrix_iset( subG , i , j , matrix_iget(G , ii , jj)); } } // Weights matrix_inplace_mul( subG , STS ); matrix_inv( subG ); { matrix_type * ones = matrix_alloc( active_size , 1 ); matrix_type * GA1 = matrix_alloc( active_size , 1 ); matrix_set( ones , 1.0 ); matrix_matmul( GA1 , subG , ones ); scale = 1.0 / sqrt( matrix_get_column_sum( GA1 , 0 )); matrix_mul( weights , GA1 , sign_vector ); matrix_scale( weights , scale ); matrix_free( GA1 ); matrix_free( ones ); } matrix_free( sign_vector ); matrix_free( subG ); matrix_free( STS ); } /******************************************************************/ /* The variables weight and scale have been calculated, proceed to calculate the step length @gamma. */ { int i; double gamma; { matrix_type * u = matrix_alloc( nsample , 1 ); int j; for (i=0; i < nsample; i++) { double row_sum = 0; for (j =0; j < active_size; j++) row_sum += matrix_iget( X , i , int_vector_iget( active_set , j)) * matrix_iget(weights , j , 0 ); matrix_iset( u , i , 0 , row_sum ); } gamma = maxC / scale; if (active_size < matrix_get_columns( X )) { matrix_type * equi_corr = matrix_alloc( nvars , 1 ); matrix_dgemm( equi_corr , X , u , true , false , 1.0 , 0); // equi_corr = X'·u for (i=0; i < (nvars - active_size); i++) { int var_index = int_vector_iget( inactive_set , i ); double gamma1 = (maxC - matrix_iget(C , var_index , 0 )) / ( scale - matrix_iget( equi_corr , var_index , 0)); double gamma2 = (maxC + matrix_iget(C , var_index , 0 )) / ( scale + matrix_iget( equi_corr , var_index , 0)); if ((gamma1 > 0) && (gamma1 < gamma)) gamma = gamma1; if ((gamma2 > 0) && (gamma2 < gamma)) gamma = gamma2; } matrix_free( equi_corr ); } /* Update the current estimated 'location' mu. */ matrix_scale( u , gamma ); matrix_inplace_add( mu , u ); matrix_free( u ); } /* We have calculated the step length @gamma, and the @weights. Update the @beta matrix. */ for (i=0; i < active_size; i++) matrix_iset( lars->beta , int_vector_iget( active_set , i ) , active_size - 1 , gamma * matrix_iget( weights , i , 0)); if (active_size > 1) for (i=0; i < nvars; i++) matrix_iadd( lars->beta , i , active_size - 1 , matrix_iget( lars->beta , i , active_size - 2)); matrix_free( weights ); } } if (active_size == max_vars) break; if (max_beta > 0) { double beta_norm2 = matrix_get_column_abssum( lars->beta , active_size - 1 ); if (beta_norm2 > max_beta) { // We stop - we will use an interpolation between this beta estimate and // the previous, to ensure that the |beta| = max_beta criteria is satisfied. if (active_size >= 2) { double beta_norm1 = matrix_get_column_abssum( lars->beta , active_size - 2 ); double s = (max_beta - beta_norm1)/(beta_norm2 - beta_norm1); { int j; for (j=0; j < nvars; j++) { double beta1 = matrix_iget( lars->beta , j , active_size - 2 ); double beta2 = matrix_iget( lars->beta , j , active_size - 1 ); matrix_iset( lars->beta , j , active_size - 1 , beta1 + s*(beta2 - beta1)); } } } break; } } } matrix_free( G ); matrix_free( mu ); matrix_free( C ); matrix_free( Y_mu ); int_vector_free( active_set ); int_vector_free( inactive_set ); matrix_resize( lars->beta , nvars , active_size , true ); if (verbose) matrix_pretty_fprint( lars->beta , "beta" , "%12.5f" , stdout ); lars_select_beta( lars , active_size - 1); } matrix_free( X ); matrix_free( Y ); }