Beispiel #1
0
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 );
}
Beispiel #2
0
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;
  }
}
Beispiel #3
0
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);
    }
  }
}
Beispiel #4
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 );
}
Beispiel #5
0
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 );
    }
  }
}
Beispiel #6
0
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;
    }
  }
}
Beispiel #7
0
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;
}
Beispiel #8
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 );
      }
    }
  }
}
Beispiel #9
0
void matrix_ensure_rows(matrix_type * matrix, int rows, bool copy_content) {
  if (matrix->rows < rows)
    matrix_resize( matrix , rows , matrix->columns , copy_content);
}
Beispiel #10
0
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;
}
Beispiel #11
0
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);
}
Beispiel #12
0
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

}
Beispiel #13
0
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 );
}