Пример #1
0
Raster* Raster::getRasterFromASCFile(std::string const& fname)
{
	std::ifstream in(fname.c_str());

	if (!in.is_open()) {
		WARN("Raster::getRasterFromASCFile(): Could not open file %s.", fname.c_str());
		return NULL;
	}

	// header information
	std::size_t n_cols(0), n_rows(0);
	double xllcorner(0.0), yllcorner(0.0), cell_size(0.0), no_data_val(-9999);

	if (readASCHeader(in, n_cols, n_rows, xllcorner, yllcorner, cell_size, no_data_val)) {
		double* values = new double[n_cols*n_rows];
		std::string s;
		// read the data into the double-array
		for (size_t j(0); j < n_rows; ++j) {
			const size_t idx ((n_rows - j - 1) * n_cols);
			for (size_t i(0); i < n_cols; ++i) {
				in >> s;
				values[idx+i] = strtod(BaseLib::replaceString(",", ".", s).c_str(),0);

			}
		}
		in.close();
		Raster *raster(new Raster(n_cols, n_rows, xllcorner, yllcorner,
						cell_size, values, values+n_cols*n_rows, no_data_val));
		delete [] values;
		return raster;
	} else {
Пример #2
0
void MutableMatrix::text_out(buffer &o) const
{
  const Ring *R = get_ring();
  size_t nrows = n_rows();
  size_t ncols = n_cols();
  buffer *p = new buffer[nrows];
  size_t r;
  for (size_t c=0; c<ncols; c++)
    {
      size_t maxcount = 0;
      for (r=0; r<nrows; r++)
        {
          ring_elem f;
          get_entry(r,c,f);
          if (!R->is_zero(f))
            R->elem_text_out(p[r], f);
          else
            p[r] << ".";
          if (p[r].size() > maxcount)
            maxcount = p[r].size();
        }
      for (r=0; r<nrows; r++)
        for (size_t k=maxcount+1-p[r].size(); k > 0; k--)
          p[r] << ' ';
    }
  for (r=0; r<nrows; r++)
    {
      p[r] << '\0';
      char *s = p[r].str();
      o << s << newline;
    }
  delete[] p;
}
Пример #3
0
 /// \name IO.
 /// \{
 void print(std::ostream & os) const
 {
     const bit_matrix & mat = *this;
     os << "[ ";
     for (size_t i = 0; i < n_rows(); i++)
     {
         for (size_t j = 0; j < n_cols(); j++)
         {
             os << mat(i,j) << ' ';
         }
         if (i != n_rows()-1)
         {
             os << "; ";
         }
     }
     os << "]";
 }
Пример #4
0
 virtual bool interchange_rows(size_t i, size_t j)
 /* swap rows: row(i) <--> row(j) */
 {
   size_t nrows = n_rows();
   if (error_row_bound(i,nrows) || error_row_bound(j,nrows))
     return false;
   mat.interchange_rows(i,j);
   return true;
 }
Пример #5
0
 virtual MutableMatrix * submatrix(M2_arrayint rows, M2_arrayint cols) const
 {
   for (size_t r = 0; r<rows->len; r++)
     if (rows->array[r] < 0 || rows->array[r] >= n_rows())
       {
         ERROR("row index %d out of bounds 0..%d", rows->array[r], n_rows()-1);
         return 0;
       }
   for (size_t c = 0; c<cols->len; c++)
     if (cols->array[c] < 0 || cols->array[c] >= n_cols())
       {
         ERROR("column index %d out of bounds 0..%d", cols->array[c], n_cols()-1);
         return 0;
       }
   MutableMat *result = new MutableMat(*this); // zero matrix, over the same ring
   result->getMat().setFromSubmatrix(getMat(), rows, cols);
   return result;
 }
Пример #6
0
 /// Get the \p j:th column.
 std::vector<bool> col(size_t j) const
 {
     const size_t n = n_rows();
     std::vector<bool> a(n);
     for (size_t i = 0; i < n; i++)
     {
         a[i] = get_bit(i, j);
     }
     return a;
 }
Пример #7
0
 virtual bool set_entry(size_t r, size_t c, const ring_elem a)
 // Returns false if (r,c) is out of range, or the ring of a is wrong.
 {
   if (error_row_bound(r,n_rows())) return false;
   if (error_column_bound(c,n_cols())) return false;
   elem b;
   mat.get_CoeffRing()->from_ring_elem(b,a);
   mat.set_entry(r,c,b);
   return true;
 }
Пример #8
0
 virtual bool insert_rows(size_t i, size_t n_to_add)
 /* Insert n_to_add rows directly BEFORE row i. */
 {
   if (i < 0 || i > n_rows() || n_to_add < 0)
     {
       ERROR("cannot insert %l rows before row %ln",n_to_add,i);
       return false;
     }
   mat.insert_rows(i, n_to_add);
   return true;
 }
Пример #9
0
 virtual bool divide_row(size_t i, ring_elem r)
 /* row(i) <- row(i) / r */
 {
   size_t nrows = n_rows();
   if (error_row_bound(i,nrows))
     return false;
   elem b;
   mat.get_CoeffRing()->from_ring_elem(b,r);
   mat.divide_row(i,b);
   return true;
 }
Пример #10
0
MutableMatrix* MutableMat<T>::invert() const
{
  MutableMat<T>*  result = makeZeroMatrix(n_rows(), n_cols());
  bool val = mat.invert(result->mat);
  if (!val)
    {
      delete result;
      return 0;
    }
  return result;
}
Пример #11
0
 virtual bool delete_rows(size_t i, size_t j)
 /* Delete rows i .. j from M */
 {
   size_t nrows = n_rows();
   if (error_row_bound(i,nrows) || error_row_bound(j,nrows))
     {
       ERROR("row index out of range");
       return false;
     }
   mat.delete_rows(i, j);
   return true;
 }
Пример #12
0
 virtual bool row_op(size_t i, ring_elem r, size_t j)
 /* row(i) <- row(i) + r * row(j) */
 {
   size_t nrows = n_rows();
   if (error_row_bound(i,nrows) || error_row_bound(j,nrows))
     return false;
   if (i == j) return true;
   elem b;
   mat.get_CoeffRing()->from_ring_elem(b,r);
   mat.row_op(i,b,j);
   return true;
 }
Пример #13
0
  virtual bool get_entry(size_t r, size_t c, ring_elem &result) const
  // Returns false if (r,c) is out of range or if result is 0.  No error
  // is returned. result <-- this(r,c), and is set to zero if false is returned.
  {
    if (r >= 0 && r < n_rows() && c >= 0 && c < n_cols())
      {
        elem a;
        mat.get_CoeffRing()->set_zero(a);
        if (mat.get_entry(r,c,a))
          {
            mat.get_CoeffRing()->to_ring_elem(result,a);
            return true;
          }
      }

    result = mat.get_ring()->zero();
    return false;
  }
Пример #14
0
 virtual bool row2by2(size_t r1, size_t r2,
                      ring_elem a1, ring_elem a2,
                      ring_elem b1, ring_elem b2)
 /* row(r1) <- a1 * row(r1) + a2 * row(r2),
    row(r2) <- b1 * row(r1) + b2 * row(r2)
 */
 {
   size_t nrows = n_rows();
   if (error_row_bound(r1,nrows) || error_row_bound(r2,nrows))
     return false;
   if (r1 == r2) return true;
   elem aa1, aa2, bb1, bb2;
   mat.get_CoeffRing()->from_ring_elem(aa1,a1);
   mat.get_CoeffRing()->from_ring_elem(aa2,a2);
   mat.get_CoeffRing()->from_ring_elem(bb1,b1);
   mat.get_CoeffRing()->from_ring_elem(bb2,b2);
   mat.row2by2(r1,r2,aa1,aa2,bb1,bb2);
   return true;
 }
Пример #15
0
  virtual MutableMat * add(const MutableMatrix *B) const
  // return this + B.  return NULL if sizes or types do not match.
  {
    const Mat *B1 = B->coerce<Mat>();
    if (B1 == NULL) 
      {
        ERROR("expected matrices with the same ring and sparsity");
        return NULL;
      }
    if (B->get_ring() != get_ring())
      {
        ERROR("expected matrices with the same ring");
        return NULL;
      }
    if (B1->n_rows() != n_rows() || B1->n_cols() != n_cols())
      {
        ERROR("expected matrices of the same shape");
        return NULL;
      }

    MutableMat* result = clone();
    result->getMat().addInPlace(*B1);
    return result;
  }
Пример #16
0
TEST(MathLib, DenseGaussAlgorithmDenseVector)
{
	std::size_t n_rows(50);
	std::size_t n_cols(n_rows);

	MathLib::DenseMatrix<double,std::size_t> mat(n_rows, n_cols);

	// *** fill matrix with arbitrary values
	// ** initialize random seed
	srand ( static_cast<unsigned>(time(nullptr)) );
	// ** loop over rows and columns
	for (std::size_t i(0); i<n_rows; i++) {
		for (std::size_t j(0); j<n_cols; j++) {
			mat(i,j) = rand()/static_cast<double>(RAND_MAX);
		}
	}

	// *** create solution vector, set all entries to 0.0
	MathLib::DenseVector<double> x(n_cols);
	std::fill(std::begin(x), std::end(x), 0.0);
	MathLib::DenseVector<double> b0(mat * x);

	// *** create other right hand sides,
	// set all entries of the solution vector to 1.0
	std::fill(std::begin(x), std::end(x), 1.0);
	MathLib::DenseVector<double> b1(mat * x);

	std::generate(std::begin(x), std::end(x), std::rand);
	MathLib::DenseVector<double> b2(mat * x);

	// right hand side and solution vector with random entries
	MathLib::DenseVector<double> b3(mat * x);
	MathLib::DenseVector<double> b3_copy(mat * x);
	MathLib::DenseVector<double> x3 (n_cols);
	std::generate(std::begin(x3),std::end(x3), std::rand);

	MathLib::GaussAlgorithm<MathLib::DenseMatrix<double, std::size_t>, MathLib::DenseVector<double>> gauss(mat);

	// solve with b0 as right hand side
	gauss.solve(b0, true);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(b0[i], 0.0, 1e5 * std::numeric_limits<float>::epsilon());
	}

	// solve with b1 as right hand side
	gauss.solve(b1, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(b1[i], 1.0, std::numeric_limits<float>::epsilon());
	}

	// solve with b2 as right hand side
	gauss.solve(b2, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(b2[i]-x[i])/fabs(x[i]), 0.0, std::numeric_limits<float>::epsilon());
	}

	gauss.solve(b3, x3, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(x3[i]-x[i])/fabs(x[i]), 0.0, std::numeric_limits<float>::epsilon());
	}
	// assure entries of vector b3 are not changed
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(b3[i]-b3_copy[i])/fabs(b3[i]), 0.0, std::numeric_limits<float>::epsilon());
	}
}
Пример #17
0
TEST(MathLib, DenseGaussAlgorithm)
{
	std::size_t n_rows(100);
	std::size_t n_cols(n_rows);

	MathLib::DenseMatrix<double,std::size_t> mat(n_rows, n_cols);

	// *** fill matrix with arbitrary values
	// ** initialize random seed
	srand ( static_cast<unsigned>(time(nullptr)) );
	// ** loop over rows and columns
	for (std::size_t i(0); i<n_rows; i++) {
		for (std::size_t j(0); j<n_cols; j++) {
			mat(i,j) = rand()/static_cast<double>(RAND_MAX);
		}
	}

	// *** create solution vector, set all entries to 0.0
	double *x(new double[n_cols]);
	std::fill(x,x+n_cols, 0.0);
	double *b0(mat * x);

	// *** create other right hand sides,
	// set all entries of the solution vector to 1.0
	std::fill(x,x+n_cols, 1.0);
	double *b1(mat * x);

	std::generate(x,x+n_cols, std::rand);
	double *b2(mat * x);

	// right hand side and solution vector with random entries
	double *b3(mat * x);
	double *b3_copy(mat * x);
	double *x3 (new double[n_cols]);
	std::generate(x3,x3+n_cols, std::rand);

	MathLib::GaussAlgorithm<MathLib::DenseMatrix<double, std::size_t>, double*> gauss(mat);

	// solve with b0 as right hand side
	gauss.solve(b0, true);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(b0[i], 0.0, std::numeric_limits<float>::epsilon());
	}

	// solve with b1 as right hand side
	gauss.solve(b1, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(b1[i], 1.0, std::numeric_limits<float>::epsilon());
	}

	// solve with b2 as right hand side
	gauss.solve(b2, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(b2[i]-x[i])/fabs(x[i]), 0.0, std::numeric_limits<float>::epsilon());
	}

	// solve with b3 as right hand side and x3 as solution vector
	gauss.solve(b3, x3, false);
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(x3[i]-x[i])/fabs(x[i]), 0.0, std::numeric_limits<float>::epsilon());
	}
	// assure entries of vector b3 are not changed
	for (std::size_t i(0); i<n_rows; i++) {
		ASSERT_NEAR(fabs(b3[i]-b3_copy[i])/fabs(b3[i]), 0.0, std::numeric_limits<float>::epsilon());
	}

	delete [] x;
	delete [] b0;
	delete [] b1;
	delete [] b2;
	delete [] b3;
	delete [] x3;
	delete [] b3_copy;
}
Пример #18
0
void Cluster::subdivide(unsigned bmin)
{
    const unsigned size(_end - _beg);
    if (size > bmin) {

        idx_t n_rows(static_cast<idx_t>(_l_adj_mat->getNRows()));

        idx_t *xadj(new idx_t[n_rows+1]);
        unsigned const*const original_row_ptr(_l_adj_mat->getRowPtrArray());
        for(idx_t k(0); k<=n_rows; k++) {
            xadj[k] = original_row_ptr[k];
        }

        unsigned nnz(_l_adj_mat->getNNZ());
        idx_t *adjncy(new idx_t[nnz]);
        unsigned const*const original_adjncy(_l_adj_mat->getColIdxArray());
        for(unsigned k(0); k<nnz; k++) {
            adjncy[k] = original_adjncy[k];
        }
//		unsigned nparts = 2;
        idx_t options[METIS_NOPTIONS]; // for METIS
        METIS_SetDefaultOptions(options);
//		options[METIS OPTION PTYPE] = METIS PTYPE RB;
//		options[METIS OPTION OBJTYPE] = METIS OBJTYPE CUT;
//		options[METIS OPTION CTYPE] = METIS CTYPE SHEM;
//		options[] = ;
//		options[] = ;
//		options[] = ;

//		unsigned sepsize(0); // for METIS
        idx_t *vwgt(new idx_t[n_rows + 1]);
//		const unsigned nnz(xadj[n_rows]);
//		unsigned *adjwgt(new unsigned[nnz]);
        for (idx_t k(0); k < n_rows + 1; k++)
            vwgt[k] = 1;
//		for (unsigned k(0); k < nnz; k++)
//			adjwgt[k] = 1;
//		unsigned *part(new unsigned[n_rows + 1]);

        // subdivide the index set into three parts employing METIS
//		METIS_ComputeVertexSeparator(&n_rows, xadj, adjncy, vwgt, &options,
//				&sepsize, part);
        idx_t *loc_op_perm(new idx_t[n_rows]);
        idx_t *loc_po_perm(new idx_t[n_rows]);
        for (idx_t k(0); k<n_rows; k++) {
            loc_op_perm[k] = _g_op_perm[k];
        }
        for (idx_t k(0); k<n_rows; k++) {
            loc_po_perm[k] = _g_po_perm[k];
        }
        METIS_NodeND(&n_rows, xadj, adjncy, vwgt, options, loc_op_perm, loc_po_perm);
        for (idx_t k(0); k<n_rows; k++) {
            _g_op_perm[k] = loc_op_perm[k];
        }
        for (idx_t k(0); k<n_rows; k++) {
            _g_po_perm[k] = loc_po_perm[k];
        }
        delete [] loc_op_perm;
        delete [] loc_po_perm;
        delete [] vwgt;
        delete [] adjncy;
        delete [] xadj;
//		// create and init local permutations
//		unsigned *l_op_perm(new unsigned[size]);
//		unsigned *l_po_perm(new unsigned[size]);
//		for (unsigned i = 0; i < size; ++i)
//			l_op_perm[i] = l_po_perm[i] = i;
//
//		unsigned isep1, isep2;
//		updatePerm(part, isep1, isep2, l_op_perm, l_po_perm);
//		delete[] part;
//
//		// update global permutation
//		unsigned *t_op_perm = new unsigned[size];
//		for (unsigned k = 0; k < size; ++k)
//			t_op_perm[k] = _g_op_perm[_beg + l_op_perm[k]];
//
//		for (unsigned k = _beg; k < _end; ++k) {
//			_g_op_perm[k] = t_op_perm[k - _beg];
//			_g_po_perm[_g_op_perm[k]] = k;
//		}
//		delete[] t_op_perm;
//
//		// next recursion step
//		if ((isep1 >= bmin) && (isep2 - isep1 >= bmin)) {
//			// construct adj matrices for [0, isep1), [isep1,isep2), [isep2, _end)
//			AdjMat *l_adj0(_l_adj_mat->getMat(0, isep1, l_op_perm, l_po_perm));
//			AdjMat *l_adj1(_l_adj_mat->getMat(isep1, isep2, l_op_perm, l_po_perm));
//			AdjMat *l_adj2(_l_adj_mat->getMat(isep2, size, l_op_perm, l_po_perm));
//
//			delete[] l_op_perm;
//			delete[] l_po_perm;
//			delete _l_adj_mat;
//			_l_adj_mat = NULL;
//
//			_n_sons = 3;
//			_sons = new ClusterBase*[_n_sons];
//
//			isep1 += _beg;
//			isep2 += _beg;
//
//			// constructing child nodes for index cluster tree
//			_sons[0] = new Cluster(this, _beg, isep1, _g_op_perm, _g_po_perm, _g_adj_mat, l_adj0);
//			_sons[1] = new Cluster(this, isep1, isep2, _g_op_perm, _g_po_perm, _g_adj_mat, l_adj1);
//			_sons[2] = new Separator(this, isep2, _end, _g_op_perm,	_g_po_perm, _g_adj_mat, l_adj2);
//
//			dynamic_cast<Cluster*>(_sons[0])->subdivide(bmin);
//			dynamic_cast<Cluster*>(_sons[1])->subdivide(bmin);
//
//		} else {
//			delete _l_adj_mat;
//			_l_adj_mat = NULL;
//		} // end if next recursion step
    } // end if ( connected && size () > bmin )

}
int main (int argc, char* argv[])
{
	LOGOG_INITIALIZE();
	logog::Cout* logog_cout (new logog::Cout);
	BaseLib::LogogSimpleFormatter *custom_format (new BaseLib::LogogSimpleFormatter);
	logog_cout->SetFormatter(*custom_format);

	TCLAP::CmdLine cmd(
	        "Generates properties for mesh elements of an input mesh deploying a ASC raster file",
	        ' ',
	        "0.1");

	TCLAP::ValueArg<std::string> out_mesh_arg("o",
	                                          "out-mesh",
	                                          "the mesh is stored to a file of this name",
	                                          false,
	                                          "",
	                                          "filename for mesh output");
	cmd.add( out_mesh_arg );

	TCLAP::ValueArg<bool> refinement_raster_output_arg("",
	                                                   "output-refined-raster",
	                                                   "write refined raster to a new ASC file",
	                                                   false,
	                                                   false,
	                                                   "0");
	cmd.add( refinement_raster_output_arg );

	TCLAP::ValueArg<unsigned> refinement_arg(
	        "r",
	        "refine",
	        "refinement factor that raises the resolution of the raster data",
	        false,
	        1,
	        "factor (default = 1)");
	cmd.add( refinement_arg );

	TCLAP::ValueArg<std::string> mapping_arg("",
	                                         "mapping-name",
	                                         "file name of mapping",
	                                         true,
	                                         "",
	                                         "file name");
	cmd.add( mapping_arg );

	TCLAP::ValueArg<std::string> raster_arg("",
	                                        "raster-file",
	                                        "the name of the ASC raster file",
	                                        true,
	                                        "",
	                                        "file name");
	cmd.add( raster_arg );

	TCLAP::ValueArg<std::string> mesh_arg("m",
	                                      "mesh",
	                                      "the mesh is read from this file",
	                                      true,
	                                      "test.msh",
	                                      "file name");
	cmd.add( mesh_arg );

	cmd.parse( argc, argv );

	// read mesh
	MeshLib::Mesh* dest_mesh(FileIO::readMeshFromFile(mesh_arg.getValue()));

	// read raster and if required manipulate it
	GeoLib::Raster* raster(FileIO::AsciiRasterInterface::getRasterFromASCFile(
		raster_arg.getValue()));
	if (refinement_arg.getValue() > 1) {
		raster->refineRaster(refinement_arg.getValue());
		if (refinement_raster_output_arg.getValue()) {
			// write new asc file
			std::string new_raster_fname (BaseLib::dropFileExtension(
			                                      raster_arg.getValue()));
			new_raster_fname += "-" + std::to_string(raster->getNRows()) + "x" +
			                    std::to_string(raster->getNCols()) + ".asc";
			FileIO::AsciiRasterInterface::writeRasterAsASC(*raster, new_raster_fname);
		}
	}

	// put raster data in a std::vector
	GeoLib::Raster::const_iterator raster_it(raster->begin());
	std::size_t n_cols(raster->getNCols()), n_rows(raster->getNRows());
	std::size_t size(n_cols * n_rows);
	std::vector<double> src_properties(size);
	for (unsigned row(0); row<n_rows; row++) {
		for (unsigned col(0); col<n_cols; col++) {
			src_properties[row * n_cols + col] = *raster_it;
			++raster_it;
		}
	}

	{
		double mu, var;
		std::tie(mu, var) = computeMeanAndVariance(src_properties.begin(), src_properties.end());
		INFO("Mean value of source: %f.", mu);
		INFO("Variance of source: %f.", var);
	}

	MeshLib::Mesh* src_mesh(MeshLib::ConvertRasterToMesh(*raster, MeshLib::MeshElemType::QUAD,
					MeshLib::UseIntensityAs::MATERIAL).execute());

	std::vector<std::size_t> src_perm(size);
	std::iota(src_perm.begin(), src_perm.end(), 0);
	BaseLib::Quicksort<double>(src_properties, 0, size, src_perm);

	// compress the property data structure
	const std::size_t mat_map_size(src_properties.size());
	std::vector<std::size_t> mat_map(mat_map_size);
	mat_map[0] = 0;
	std::size_t n_mat(1);
	for (std::size_t k(1); k<mat_map_size; ++k) {
		if (std::fabs(src_properties[k] - src_properties[k-1]) > std::numeric_limits<double>::epsilon()) {
			mat_map[k] = mat_map[k - 1] + 1;
			n_mat++;
		} else
			mat_map[k] = mat_map[k - 1];
	}
	std::vector<double> compressed_src_properties(n_mat);
	compressed_src_properties[0] = src_properties[0];
	for (std::size_t k(1), id(1); k<mat_map_size; ++k) {
		if (std::fabs(src_properties[k] - src_properties[k-1]) > std::numeric_limits<double>::epsilon()) {
			compressed_src_properties[id] = src_properties[k];
			id++;
		}
	}
	compressed_src_properties[n_mat - 1] = src_properties[mat_map_size - 1];

	// reset materials in source mesh
	const std::size_t n_mesh_elements(src_mesh->getNElements());
	for (std::size_t k(0); k<n_mesh_elements; k++) {
		const_cast<MeshLib::Element*>(src_mesh->getElement(src_perm[k]))->setValue(mat_map[k]);
	}

	// do the interpolation
	MeshLib::Mesh2MeshPropertyInterpolation mesh_interpolation(src_mesh,
	                                                           &compressed_src_properties);
	std::vector<double> dest_properties(dest_mesh->getNElements());
	mesh_interpolation.setPropertiesForMesh(const_cast<MeshLib::Mesh*>(dest_mesh),
	                                        dest_properties);

	const std::size_t n_dest_mesh_elements(dest_mesh->getNElements());

	{ // write property file
		std::string property_fname(mapping_arg.getValue());
		std::ofstream property_out(property_fname.c_str());
		if (!property_out)
		{
			ERR("Could not open file %s for writing the mapping.", property_fname.c_str());
			return -1;
		}

		for (std::size_t k(0); k < n_dest_mesh_elements; k++)
			property_out << k << " " << dest_properties[k] << "\n";
		property_out.close();
	}

	{
		double mu, var;
		std::tie(mu, var) = computeMeanAndVariance(dest_properties.begin(), dest_properties.end());
		INFO("Mean value of destination: %f.", mu);
		INFO("Variance of destination: %f.", var);
	}

	if (! out_mesh_arg.getValue().empty()) {
		std::vector<std::size_t> dest_perm(n_dest_mesh_elements);
		std::iota(dest_perm.begin(), dest_perm.end(), 0);
		BaseLib::Quicksort<double>(dest_properties, 0, n_dest_mesh_elements, dest_perm);

		// reset materials in destination mesh
		for (std::size_t k(0); k<n_dest_mesh_elements; k++) {
			const_cast<MeshLib::Element*>(dest_mesh->getElement(dest_perm[k]))->setValue(k);
		}

		FileIO::Legacy::MeshIO mesh_writer;
		mesh_writer.setPrecision(12);
		mesh_writer.setMesh(dest_mesh);
		mesh_writer.writeToFile(out_mesh_arg.getValue());
	}

	delete raster;
	delete src_mesh;
	delete dest_mesh;

	delete custom_format;
	delete logog_cout;
	LOGOG_SHUTDOWN();

	return 0;
}