예제 #1
0
파일: test_reg.c 프로젝트: FMX/gsl
static void
test_reg_system(const size_t n, const size_t p, const gsl_rng *r)
{
  gsl_matrix *X = gsl_matrix_alloc(n, p);
  gsl_vector *y = gsl_vector_alloc(n);
  gsl_vector *c = gsl_vector_alloc(p);
  gsl_vector *wts = gsl_vector_alloc(n);
  gsl_multifit_linear_workspace *w = gsl_multifit_linear_alloc(n, p);
  gsl_multifit_linear_workspace *wbig = gsl_multifit_linear_alloc(n + 10, p + 5);
  gsl_vector *diagL = gsl_vector_alloc(p);
  gsl_matrix *Lsqr = gsl_matrix_alloc(p, p);
  gsl_matrix *Ltall = gsl_matrix_alloc(5*p, p);
  gsl_matrix *L1 = gsl_matrix_alloc(p - 1, p);
  gsl_matrix *L2 = gsl_matrix_alloc(p - 2, p);
  gsl_matrix *L3 = gsl_matrix_alloc(p - 3, p);
  gsl_matrix *L5 = gsl_matrix_alloc(p - 5, p);
  size_t i;

  /* generate random weights */
  test_random_vector(wts, r, 0.0, 1.0);

  /* generate well-conditioned system and test against OLS solution */
  test_random_matrix(X, r, -1.0, 1.0);
  test_random_vector(y, r, -1.0, 1.0);
  test_reg1(X, y, NULL, 1.0e-10, w, "unweighted");
  test_reg1(X, y, wts, 1.0e-10, w, "weighted");

  /* generate ill-conditioned system */
  test_random_matrix_ill(X, r);
  test_random_vector(c, r, -1.0, 1.0);

  /* compute y = X c + noise */
  gsl_blas_dgemv(CblasNoTrans, 1.0, X, c, 0.0, y);
  test_random_vector_noise(r, y);

  /* random diag(L) vector */
  test_random_vector(diagL, r, -2.0, 2.0);

  /* random square and tall L matrices */
  test_random_matrix(Lsqr, r, -2.0, 2.0);
  test_random_matrix(Ltall, r, -2.0, 2.0);

  gsl_multifit_linear_Lk(p, 1, L1);
  gsl_multifit_linear_Lk(p, 2, L2);
  gsl_multifit_linear_Lk(p, 3, L3);
  gsl_multifit_linear_Lk(p, 5, L5);

  for (i = 0; i < 3; ++i)
    {
      /*
       * can't make lambda too small or normal equations
       * approach won't work well
       */
      double lambda = pow(10.0, -(double) i);

      /* test unweighted */
      test_reg2(lambda, X, y, NULL, 1.0e-6, w, "unweighted");
      test_reg3(lambda, diagL, X, y, NULL, 1.0e-6, w, "unweighted");
      test_reg4(lambda, Lsqr, X, y, NULL, 1.0e-8, w, "Lsqr unweighted");
      test_reg4(lambda, Ltall, X, y, NULL, 1.0e-8, w, "Ltall unweighted");
      test_reg4(lambda, L1, X, y, NULL, 1.0e-6, w, "L1 unweighted");
      test_reg4(lambda, L2, X, y, NULL, 1.0e-6, w, "L2 unweighted");
      test_reg4(lambda, L3, X, y, NULL, 1.0e-5, w, "L3 unweighted");
      test_reg4(lambda, L5, X, y, NULL, 1.0e-4, w, "L5 unweighted");

      /* test weighted */
      test_reg2(lambda, X, y, wts, 1.0e-6, w, "weighted");
      test_reg3(lambda, diagL, X, y, wts, 1.0e-6, w, "weighted");
      test_reg4(lambda, Lsqr, X, y, wts, 1.0e-8, w, "Lsqr weighted");
      test_reg4(lambda, L1, X, y, wts, 1.0e-6, w, "L1 weighted");
      test_reg4(lambda, L2, X, y, wts, 1.0e-6, w, "L2 weighted");
      test_reg4(lambda, L3, X, y, wts, 1.0e-5, w, "L3 weighted");
      test_reg4(lambda, L5, X, y, wts, 1.0e-4, w, "L5 weighted");

      /* test again with larger workspace */
      test_reg2(lambda, X, y, NULL, 1.0e-6, wbig, "unweighted big");
      test_reg3(lambda, diagL, X, y, NULL, 1.0e-6, wbig, "unweighted big");
      test_reg4(lambda, Lsqr, X, y, NULL, 1.0e-8, wbig, "Lsqr unweighted big");
      test_reg4(lambda, L1, X, y, NULL, 1.0e-6, wbig, "L1 unweighted big");
      test_reg4(lambda, L2, X, y, NULL, 1.0e-6, wbig, "L2 unweighted big");
      test_reg4(lambda, L3, X, y, NULL, 1.0e-5, wbig, "L3 unweighted big");
      test_reg4(lambda, L5, X, y, NULL, 1.0e-4, wbig, "L5 unweighted big");

      test_reg2(lambda, X, y, wts, 1.0e-6, wbig, "weighted big");
      test_reg3(lambda, diagL, X, y, wts, 1.0e-6, wbig, "weighted big");
      test_reg4(lambda, Lsqr, X, y, wts, 1.0e-8, wbig, "Lsqr weighted big");
      test_reg4(lambda, L1, X, y, wts, 1.0e-6, wbig, "L1 weighted big");
      test_reg4(lambda, L2, X, y, wts, 1.0e-6, wbig, "L2 weighted big");
      test_reg4(lambda, L3, X, y, wts, 1.0e-5, wbig, "L3 weighted big");
      test_reg4(lambda, L5, X, y, wts, 1.0e-4, wbig, "L5 weighted big");
    }

  gsl_matrix_free(X);
  gsl_vector_free(y);
  gsl_vector_free(c);
  gsl_vector_free(wts);
  gsl_vector_free(diagL);
  gsl_matrix_free(Lsqr);
  gsl_matrix_free(Ltall);
  gsl_matrix_free(L1);
  gsl_matrix_free(L2);
  gsl_matrix_free(L3);
  gsl_matrix_free(L5);
  gsl_multifit_linear_free(w);
  gsl_multifit_linear_free(wbig);
}
예제 #2
0
static int
test_shaw_system(gsl_rng *rng_p, const size_t n, const size_t p,
                 const double lambda_expected,
                 gsl_vector *rhs)
{
  const size_t npoints = 1000; /* number of points on L-curve */
  const double tol1 = 1.0e-12;
  const double tol2 = 1.0e-10;
  const double tol3 = 1.0e-5;
  gsl_vector * reg_param = gsl_vector_alloc(npoints);
  gsl_vector * rho = gsl_vector_alloc(npoints);
  gsl_vector * eta = gsl_vector_alloc(npoints);

  gsl_matrix * X = gsl_matrix_alloc(n, p);
  gsl_matrix * cov = gsl_matrix_alloc(p, p);
  gsl_vector * c = gsl_vector_alloc(p);
  gsl_vector * ytmp = gsl_vector_alloc(n);
  gsl_vector * y;
  gsl_vector * r = gsl_vector_alloc(n);
  gsl_multifit_linear_workspace * work = 
    gsl_multifit_linear_alloc (n, p);

  size_t reg_idx, i;
  double lambda, rnorm, snorm;

  /* build design matrix */
  shaw_system(X, ytmp);

  if (rhs)
    y = rhs;
  else
    {
      y = ytmp;

      /* add random noise to exact rhs vector */
      test_random_vector_noise(rng_p, y);
    }

  /* SVD decomposition */
  gsl_multifit_linear_svd(X, work);

  /* calculate L-curve */
  gsl_multifit_linear_lcurve(y, reg_param, rho, eta, work);

  /* test rho and eta vectors */
  for (i = 0; i < npoints; ++i)
    {
      double rhoi = gsl_vector_get(rho, i);
      double etai = gsl_vector_get(eta, i);
      double lami = gsl_vector_get(reg_param, i);

      /* solve regularized system and check for consistent rho/eta values */
      gsl_multifit_linear_solve(lami, X, y, c, &rnorm, &snorm, work);
      gsl_test_rel(rhoi, rnorm, tol3, "shaw rho n="F_ZU" p="F_ZU" lambda=%e",
                   n, p, lami);
      gsl_test_rel(etai, snorm, tol1, "shaw eta n="F_ZU" p="F_ZU" lambda=%e",
                   n, p, lami);
    }

  /* calculate corner of L-curve */
  gsl_multifit_linear_lcorner(rho, eta, &reg_idx);

  lambda = gsl_vector_get(reg_param, reg_idx);

  /* test against known lambda value if given */
  if (lambda_expected > 0.0)
    {
      gsl_test_rel(lambda, lambda_expected, tol1,
                   "shaw: n="F_ZU" p="F_ZU" L-curve corner lambda",
                   n, p);
    }

  /* compute regularized solution with optimal lambda */
  gsl_multifit_linear_solve(lambda, X, y, c, &rnorm, &snorm, work);

  /* compute residual norm ||y - X c|| */
  gsl_vector_memcpy(r, y);
  gsl_blas_dgemv(CblasNoTrans, 1.0, X, c, -1.0, r);

  /* test rnorm value */
  gsl_test_rel(rnorm, gsl_blas_dnrm2(r), tol2,
               "shaw: n="F_ZU" p="F_ZU" rnorm", n, p);

  /* test snorm value */
  gsl_test_rel(snorm, gsl_blas_dnrm2(c), tol2,
               "shaw: n="F_ZU" p="F_ZU" snorm", n, p);

  gsl_matrix_free(X);
  gsl_matrix_free(cov);
  gsl_vector_free(reg_param);
  gsl_vector_free(rho);
  gsl_vector_free(eta);
  gsl_vector_free(r);
  gsl_vector_free(c);
  gsl_vector_free(ytmp);
  gsl_multifit_linear_free(work);

  return 0;
} /* test_shaw_system() */