int Cokriging::execute( GsTL_project* ) {
  // those flags will be used to signal if some of the nodes could not be
  // informed
  bool issue_singular_system_warning = false;
  bool issue_no_conditioning_data_warning = false;

	// Set up a progress notifier	
  SmartPtr<Progress_notifier> progress_notifier = 
    utils::create_notifier( "Running Cokriging", 
			    simul_grid_->size() + 1,  
			    std::max( simul_grid_->size() / 50, 1 ) );

  // create property for kriging variance
  std::string var_prop_name = property_name_ + "_krig_var";
  Grid_continuous_property* var_prop = 
    geostat_utils::add_property_to_grid( simul_grid_, var_prop_name );
  appli_assert( var_prop );
  var_prop->set_parameters(parameters_);


  simul_grid_->select_property( property_name_ );
  
  Grid_path path(simul_grid_, simul_grid_->property(property_name_) , target_grid_region_);

  typedef Grid_path::iterator iterator;
  iterator begin = path.begin();
  iterator end = path.end();
  
  for( ; begin != end; ++begin ) {
//    std::cout << "center: " << begin->location() << "  ";
    if( !progress_notifier->notify() ) {
      simul_grid_->remove_property( property_name_ ); 
      return 1;
    }

    if( begin->is_informed() ) continue;
      
    neighborhood_vector_[0].find_neighbors( *begin );
    neighborhood_vector_[1].find_neighbors( *begin );
    
//    if( neighborhood_vector_[0].is_empty() &&
//      	neighborhood_vector_[1].is_empty() ) {
      if( neighborhood_vector_[0].size() < min_neigh_1_ &&
      	neighborhood_vector_[1].size() < min_neigh_2_ ) {
      //if we don't have any conditioning data, skip the node
      issue_no_conditioning_data_warning = true;
      continue;
    }
/*
    std::cout << "neighbors: " ;
    for( Neighborhood::iterator it = neighborhood_vector_[0].begin();
	   it != neighborhood_vector_[0].end(); ++it ) {
      std::cout << "(" << it->location() << "):" << it->property_value() << "  ";
    }
*/      
    double variance = -1;
    int status = cokriging_weights( kriging_weights_, variance,
                                    *begin,
                                    neighborhood_vector_.begin(), 
                                    neighborhood_vector_.end(),
                                    *covar_, *Kconstraints_ );
      
    if(status == 0) {
      // the kriging system could be solved
      double estimate = (*combiner_)( kriging_weights_.begin(), 
				      kriging_weights_.end(),
				      neighborhood_vector_.begin(), 
				      neighborhood_vector_.end() );
//    std::cout << "  estimate: " << estimate << std::endl;
      begin->set_property_value( estimate );
      var_prop->set_value( variance, begin->node_id() );
    }


    else {
      // the kriging system could not be solved
      issue_singular_system_warning = true;
    }
  }

  if( issue_singular_system_warning )
    GsTLcerr << "Some nodes could not be estimated The kriging system could not be solved for every node\n" 
             << gstlIO::end; 
/*
  if( issue_no_conditioning_data_warning )
    GsTLcerr << "Cokriging could not be performed at some locations because\n"
             << "the neighborhood of those locations was empty.\n"
             << "Try increasing the size of the search ellipsoid.\n"
             << gstlIO::end; 
*/
  return 0;
}
int Cokriging_x_validation::execute( GsTL_project* ) {
  // those flags will be used to signal if some of the nodes could not be
  // informed
  bool issue_singular_system_warning = false;
  bool issue_no_conditioning_data_warning = false;

	// Set up a progress notifier	
  SmartPtr<Progress_notifier> progress_notifier = 
    utils::create_notifier( "Running Cokriging", 
			    prim_harddata_grid_->size() + 1,  
			    std::max( prim_harddata_grid_->size() / 50, 1 ) );

  // create property for the cross-validation
  // value
  Grid_continuous_property* kvalue_prop = geostat_utils::add_property_to_grid(prim_harddata_grid_, property_name_ );
  property_name_ = kvalue_prop->name();
  kvalue_prop->set_parameters(parameters_);

  Grid_continuous_property* var_prop = 
    geostat_utils::add_property_to_grid( prim_harddata_grid_, property_name_ + "_krig_var" );
  appli_assert( var_prop );
  var_prop->set_parameters(parameters_);

  Grid_continuous_property* error_prop = 
    geostat_utils::add_property_to_grid( prim_harddata_grid_, property_name_ + "_error" );
  appli_assert( error_prop );
  error_prop->set_parameters(parameters_);

  Grid_continuous_property* error2_prop = 
    geostat_utils::add_property_to_grid( prim_harddata_grid_, property_name_ + "_error2" );
  appli_assert( error2_prop );
  error2_prop->set_parameters(parameters_);

  Grid_continuous_property* error2_kvar_prop = 
    geostat_utils::add_property_to_grid( prim_harddata_grid_, property_name_ + "_error2_kvar_ratio" );
  appli_assert( error2_kvar_prop );
  error2_kvar_prop->set_parameters(parameters_);

  prim_harddata_grid_->select_property( property_name_ );
  
  typedef Geostat_grid::iterator iterator;
  iterator begin = prim_harddata_grid_->begin();
  iterator end = prim_harddata_grid_->end();
  
  for( ; begin != end; ++begin ) {
//    std::cout << "center: " << begin->location() << "  ";
    if( !progress_notifier->notify() ) {
      prim_harddata_grid_->remove_property( kvalue_prop->name() ); 
      prim_harddata_grid_->remove_property( var_prop->name() );
      prim_harddata_grid_->remove_property( error_prop->name() );
      prim_harddata_grid_->remove_property( error2_prop->name() );
      prim_harddata_grid_->remove_property( error2_kvar_prop->name() );
      return 1;
    }

    neighborhood_vector_[0].find_neighbors( *begin );
    neighborhood_vector_[1].find_neighbors( *begin );
    
//    if( neighborhood_vector_[0].is_empty() &&
//      	neighborhood_vector_[1].is_empty() ) {
      if( neighborhood_vector_[0].size() < min_neigh_1_ &&
      	neighborhood_vector_[1].size() < min_neigh_2_ ) {
      //if we don't have any conditioning data, skip the node
      issue_no_conditioning_data_warning = true;
      continue;
    }
/*
    std::cout << "neighbors: " ;
    for( Neighborhood::iterator it = neighborhood_vector_[0].begin();
	   it != neighborhood_vector_[0].end(); ++it ) {
      std::cout << "(" << it->location() << "):" << it->property_value() << "  ";
    }
*/      
    double variance = -1;
    int status = cokriging_weights( kriging_weights_, variance,
                                    *begin,
                                    neighborhood_vector_.begin(), 
                                    neighborhood_vector_.end(),
                                    *covar_, *Kconstraints_ );
      
    if(status == 0) {
      // the kriging system could be solved
      double estimate = (*combiner_)( kriging_weights_.begin(), 
				      kriging_weights_.end(),
				      neighborhood_vector_.begin(), 
				      neighborhood_vector_.end() );
//    std::cout << "  estimate: " << estimate << std::endl;
      begin->set_property_value( estimate );
      int nodeid = begin->node_id();
      Grid_continuous_property::property_type value = neighborhood_vector_[0].selected_property()->get_value(nodeid);
      float error = estimate - value;
      float error2 = error*error;
      float error_kvar = error2/variance;

      var_prop->set_value( variance, nodeid );
      error_prop->set_value( error, nodeid );
      error2_prop->set_value( error2, nodeid );
      error2_kvar_prop->set_value( error_kvar, nodeid );
    }


    else {
      // the kriging system could not be solved
      issue_singular_system_warning = true;
    }
  }
/*
  if( issue_singular_system_warning )
    GsTLcerr << "Some nodes could not be estimated\n The kriging system could not be solved for every node\n" 
             << gstlIO::end; 
*/
/*
  if( issue_no_conditioning_data_warning )
    GsTLcerr << "Cokriging could not be performed at some locations because\n"
             << "the neighborhood of those locations was empty.\n"
             << "Try increasing the size of the search ellipsoid.\n"
             << gstlIO::end; 
*/
  return 0;
}