Esempio n. 1
0
/*
 * call-seq:
 *   difcost(GSL::Matrix, GSL::Matrix) -> Float
 *
 * Calculates the geometric distance between two matrices
 */
static VALUE difcost_wrap(VALUE obj, VALUE matrix1, VALUE matrix2)
{
  gsl_matrix *m1, *m2;
  Data_Get_Struct(matrix1, gsl_matrix, m1);
  Data_Get_Struct(matrix2, gsl_matrix, m2);
  return rb_float_new(difcost(m1, m2));
}
Esempio n. 2
0
static double update(gsl_matrix *v, gsl_matrix *w, gsl_matrix *h)
{
  double dist = 0;
  gsl_matrix *wt=NULL, *ht=NULL, *wh=NULL;
  gsl_matrix *w_h=NULL, *wt_w=NULL;
  gsl_matrix *wt_v = NULL;
  gsl_matrix *v_ht=NULL, *wt_w_h=NULL, *w_h_ht=NULL;

  wt = gsl_matrix_alloc(w->size2, w->size1);
  gsl_matrix_transpose_memcpy(wt, w);
  ht = gsl_matrix_alloc(h->size2, h->size1);
  gsl_matrix_transpose_memcpy(ht, h);

  // wt * v
  wt_v = mm(wt, v);

  // wt * w * h
  wt_w = mm(wt, w);
  wt_w_h = mm(wt_w, h);
  gsl_matrix_free(wt_w);

  // h = h.mul_elements(wt * v).div_elements(wt * w * h)
  gsl_matrix_mul_elements(h, wt_v);
  gsl_matrix_div_elements(h, wt_w_h);
  gsl_matrix_free(wt_v);
  gsl_matrix_free(wt_w_h);

  // v * ht
  v_ht = mm(v, ht);

  // w * h * ht
  w_h = mm(w, h);
  w_h_ht = mm(w_h, ht);
  gsl_matrix_free(w_h);

  // w = w.mul_elements(v * ht).div_elements(w * h * ht)
  gsl_matrix_mul_elements(w, v_ht);
  gsl_matrix_div_elements(w, w_h_ht);
  gsl_matrix_free(v_ht);
  gsl_matrix_free(w_h_ht);

  gsl_matrix_free(wt);
  gsl_matrix_free(ht);

  wh = mm(w, h);
  dist = difcost(v, wh);
  gsl_matrix_free(wh);

  // w and h were modified in place
  return dist;
}