int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);

  QUESO::EnvOptionsValues options;
  options.m_numSubEnvironments = 1;

  QUESO::FullEnvironment env(MPI_COMM_WORLD, "", "", &options);

  QUESO::VectorSpace<QUESO::GslVector, QUESO::GslMatrix> paramSpace(env,
      "param_", 3, NULL);

  // Example RHS
  QUESO::GslVector b(paramSpace.zeroVector());
  b[0] = 1.0;
  b[1] = 2.0;
  b[2] = 3.0;

  // Set up block sizes for observation covariance matrix
  std::vector<unsigned int> blockSizes(2);
  blockSizes[0] = 1;  // First block is 1x1 (scalar)
  blockSizes[1] = 2;  // Second block is 2x2

  // Set up block (identity) matrix with specified block sizes
  QUESO::GslBlockMatrix covariance(blockSizes, b, 1.0);

  // The matrix [[1, 0, 0], [0, 1, 2], [0, 2, 8]]
  // has inverse 0.25 * [[1, 0, 0], [0, 2, -0.5], [0, -0.5, 0.25]]
  covariance.getBlock(0)(0, 0) = 1.0;
  covariance.getBlock(1)(0, 0) = 1.0;
  covariance.getBlock(1)(0, 1) = 2.0;
  covariance.getBlock(1)(1, 0) = 2.0;
  covariance.getBlock(1)(1, 1) = 8.0;

  // Compute solution
  QUESO::GslVector x(paramSpace.zeroVector());
  covariance.invertMultiply(b, x);

  // This is the analytical solution
  QUESO::GslVector sol(paramSpace.zeroVector());
  sol[0] = 1.0;
  sol[1] = 2.5;
  sol[2] = -0.25;

  // So if the solve worked, this sucker should be the zero vector
  sol -= x;

  // So its norm should be zero
  if (sol.norm2() > TOL) {
    std::cerr << "Computed solution:" << std::endl;
    std::cerr << b << std::endl;
    std::cerr << "Actual solution:" << std::endl;
    std::cerr << sol << std::endl;
    queso_error_msg("TEST: GslBlockMatrix::invertMultiply failed.");
  }

  MPI_Finalize();
  return 0;
}
int main(int argc, char ** argv) {
#ifdef QUESO_HAS_MPI
  MPI_Init(&argc, &argv);
  QUESO::FullEnvironment env(MPI_COMM_WORLD, argv[1], "", NULL);
#else
  QUESO::FullEnvironment env(argv[1], "", NULL);
#endif

  QUESO::VectorSpace<QUESO::GslVector, QUESO::GslMatrix> paramSpace(env,
      "param_", 1, NULL);

  double min_val = 0.0;
  double max_val = 1.0;

  QUESO::GslVector paramMins(paramSpace.zeroVector());
  paramMins.cwSet(min_val);
  QUESO::GslVector paramMaxs(paramSpace.zeroVector());
  paramMaxs.cwSet(max_val);

  QUESO::BoxSubset<QUESO::GslVector, QUESO::GslMatrix> paramDomain("param_",
      paramSpace, paramMins, paramMaxs);

  QUESO::UniformVectorRV<QUESO::GslVector, QUESO::GslMatrix> priorRv("prior_",
      paramDomain);

  // Set up observation space
  QUESO::VectorSpace<QUESO::GslVector, QUESO::GslMatrix> obsSpace(env,
      "obs_", 3, NULL);

  // Fill up observation vector
  QUESO::GslVector observations(obsSpace.zeroVector());
  observations[0] = 1.0;
  observations[1] = 1.0;
  observations[2] = 1.0;

  // Set up block sizes for observation covariance matrix
  std::vector<unsigned int> blockSizes(2);
  blockSizes[0] = 1;  // First block is 1x1 (scalar)
  blockSizes[1] = 2;  // Second block is 2x2

  // Set up block matrix (identity matrix) with specified block sizes
  QUESO::GslBlockMatrix covariance(blockSizes, observations, 1.0);

  // Pass in observations to Gaussian likelihood object
  Likelihood<QUESO::GslVector, QUESO::GslMatrix> lhood("llhd_", paramDomain,
      observations, covariance);

  QUESO::GenericVectorRV<QUESO::GslVector, QUESO::GslMatrix>
    postRv("post_", paramSpace);

  QUESO::StatisticalInverseProblem<QUESO::GslVector, QUESO::GslMatrix>
    ip("", NULL, priorRv, lhood, postRv);

  QUESO::GslVector paramInitials(paramSpace.zeroVector());

  paramInitials[0] = 0.0;

  QUESO::GslMatrix proposalCovMatrix(paramSpace.zeroVector());

  for (unsigned int i = 0; i < 1; i++) {
    proposalCovMatrix(i, i) = 0.1;
  }

  ip.solveWithBayesMetropolisHastings(NULL, paramInitials, &proposalCovMatrix);

#ifdef QUESO_HAS_MPI
  MPI_Finalize();
#endif

  return 0;
}