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 {
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; }
/// \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 << "]"; }
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; }
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; }
/// 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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()); } }
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; }
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; }