예제 #1
0
void wotreplay::read_png(std::istream &is, boost::multi_array<uint8_t, 3> &image) {
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    png_infop end_info = png_create_info_struct(png_ptr);
    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        return;
    }
    
    png_set_read_fn(png_ptr, &is, &user_read_data);

    png_read_info(png_ptr, info_ptr);
    int width = png_get_image_width(png_ptr, info_ptr);
    int height = png_get_image_height(png_ptr, info_ptr);
    png_byte color_type = png_get_color_type(png_ptr, info_ptr);
    if (color_type == PNG_COLOR_TYPE_RGB) {
        // add alpha channel
        png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
    } else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
        // do nothing extra
    } else {
        throw std::runtime_error("Unsupported image type");
    }

    image.resize(boost::extents[height][width][4]);
    std::vector<png_bytep> row_pointers;
    get_row_pointers(image, row_pointers);
    png_read_image(png_ptr, &row_pointers[0]);
    png_read_end(png_ptr, info_ptr);
}
예제 #2
0
//-----------------------------------------------------------------------------
void DofMap::tabulate_coordinates(boost::multi_array<double, 2>& coordinates,
                                  const ufc::cell& ufc_cell) const
{
  // FIXME: This is a hack because UFC wants a double pointer for coordinates
  dolfin_assert(_ufc_dofmap);

  // Check dimensions
  if (coordinates.shape()[0] != cell_dimension(ufc_cell.index) ||
      coordinates.shape()[1] != _ufc_dofmap->geometric_dimension())
  {
    boost::multi_array<double, 2>::extent_gen extents;
    const std::size_t cell_dim = cell_dimension(ufc_cell.index);
    coordinates.resize(extents[cell_dim][_ufc_dofmap->geometric_dimension()]);
  }

  // Set vertex coordinates
  const std::size_t num_points = coordinates.size();
  std::vector<double*> coords(num_points);
  for (std::size_t i = 0; i < num_points; ++i)
    coords[i] = &(coordinates[i][0]);

  // Tabulate coordinates
  _ufc_dofmap->tabulate_coordinates(coords.data(),
                                    &ufc_cell.vertex_coordinates[0]);
}
예제 #3
0
파일: multi_array.hpp 프로젝트: K-ballo/hpx
    void load(input_archive& ar, boost::multi_array<T, N, Allocator>& marray, unsigned)
    {
        boost::array<std::size_t, N> shape;
        ar & shape;

        marray.resize(shape);
        ar & make_array(marray.data(), marray.num_elements());
    }
예제 #4
0
//-----------------------------------------------------------------------------
void HexahedronCell::create_entities(boost::multi_array<unsigned int, 2>& e,
                                        std::size_t dim, const unsigned int* v) const
{
  // We need to know how to create edges and faces
  switch (dim)
  {
  case 1:
    // Resize data structure
    e.resize(boost::extents[12][2]);

    // Create the 12 edges
    e[0][0]  = v[0]; e[0][1]  = v[1];
    e[1][0]  = v[2]; e[1][1]  = v[3];
    e[2][0]  = v[4]; e[2][1]  = v[5];
    e[3][0]  = v[6]; e[3][1]  = v[7];
    e[4][0]  = v[0]; e[4][1]  = v[2];
    e[5][0]  = v[1]; e[5][1]  = v[3];
    e[6][0]  = v[4]; e[6][1]  = v[6];
    e[7][0]  = v[5]; e[7][1]  = v[7];
    e[8][0]  = v[0]; e[8][1]  = v[4];
    e[9][0]  = v[1]; e[9][1]  = v[5];
    e[10][0] = v[2]; e[10][1] = v[6];
    e[11][0] = v[3]; e[11][1] = v[7];
    break;
  case 2:
    // Resize data structure
    e.resize(boost::extents[6][4]);

    // Create the 6 faces
    e[0][0] = v[0]; e[0][1] = v[2]; e[0][2] = v[4]; e[0][3] = v[6];
    e[1][0] = v[1]; e[1][1] = v[3]; e[1][2] = v[5]; e[1][3] = v[7];
    e[2][0] = v[0]; e[2][1] = v[1]; e[2][2] = v[4]; e[2][3] = v[5];
    e[3][0] = v[2]; e[3][1] = v[3]; e[3][2] = v[6]; e[3][3] = v[7];
    e[4][0] = v[0]; e[4][1] = v[1]; e[4][2] = v[2]; e[4][3] = v[3];
    e[5][0] = v[4]; e[5][1] = v[5]; e[5][2] = v[6]; e[5][3] = v[7];
    break;
  default:
    dolfin_error("HexahedronCell.cpp",
                 "create entities of tetrahedron cell",
                 "Don't know how to create entities of topological dimension %d", dim);
  }
}
예제 #5
0
//-----------------------------------------------------------------------------
void IntervalCell::create_entities(boost::multi_array<unsigned int, 2>& e,
                                   std::size_t dim, const unsigned int* v) const
{
  // For completeness, IntervalCell has two 'edges'
  dolfin_assert(dim == 0);

  // Resize data structure
  e.resize(boost::extents[2][1]);
  // Create the three edges
  e[0][0] = v[0]; e[1][0] = v[1];
}
예제 #6
0
void compute_Tnl_legendre(int n_matsubara, int n_legendre, boost::multi_array<std::complex<double>,2> &Tnl) {
  double sign_tmp = 1.0;
  Tnl.resize(boost::extents[n_matsubara][n_legendre]);
  for (int im = 0; im < n_matsubara; ++im) {
    std::complex<double> ztmp(0.0, 1.0);
    for (int il = 0; il < n_legendre; ++il) {
      Tnl[im][il] = sign_tmp * ztmp * std::sqrt(2 * il + 1.0) * boost::math::sph_bessel(il, 0.5 * (2 * im + 1) * M_PI);
      ztmp *= std::complex<double>(0.0, 1.0);
    }
    sign_tmp *= -1;
  }
}
예제 #7
0
    void precompute(double distance, double scalex, double scaley)
    {
        double const radius2 = distance * distance;

        width  = 2* ceil(distance / scalex) + 1;
        height = 2* ceil(distance / scaley) + 1;
        in_distance.resize(boost::extents[height][width]);
        std::fill(in_distance.data(), in_distance.data() + in_distance.num_elements(), false);
        parents.resize(boost::extents[height][width]);
        std::fill(parents.data(), parents.data() + parents.num_elements(), std::make_pair(-1, -1));

        centerx = width  / 2;
        centery = height / 2;
        parents[centery][centerx] = std::make_pair(-1, -1);

        for (unsigned int y = 0; y < height; ++y)
        {
            for (unsigned int x = 0; x < width; ++x)
            {
                int dx = (centerx - x);
                int dy = (centery - y);
                if (dx == 0 && dy == 0) continue;

                double d2 = dx * dx * scalex * scalex + dy * dy * scaley * scaley;
                in_distance[y][x] = (d2 < radius2);
                if (abs(dx) > abs(dy))
                {
                    int parentx = x + dx / abs(dx);
                    int parenty = y + rint(static_cast<double>(dy) / abs(dx));
                    parents[y][x] = std::make_pair(parentx, parenty);
                }
                else
                {
                    int parentx = x + rint(static_cast<double>(dx) / abs(dy));
                    int parenty = y + dy / abs(dy);
                    parents[y][x] = std::make_pair(parentx, parenty);
                }
            }
        }
    }
예제 #8
0
void load( Archive & ar,
           boost::multi_array<double,2> & t,
           const unsigned int file_version )
{
    typedef boost::multi_array<double,2> multi_array_;
    typedef typename multi_array_::size_type size_;
    size_ n0;
    ar >> BOOST_SERIALIZATION_NVP( n0 );
    size_ n1;
    ar >> BOOST_SERIALIZATION_NVP( n1 );
    t.resize( boost::extents[n0][n1] );
    ar >> make_array( t.data(), t.num_elements() );
}
예제 #9
0
void
resize_from_MultiArray(boost::multi_array<T,N>& marray, U& other) {

  // U must be a model of MultiArray
  boost::function_requires<
  boost::multi_array_concepts::ConstMultiArrayConcept<U,U::dimensionality> >();
  // U better have U::dimensionality == N
  BOOST_STATIC_ASSERT(U::dimensionality == N);

  boost::array<typename boost::multi_array<T,N>::size_type, N> shape;

  std::copy(other.shape(), other.shape()+N, shape.begin());

  marray.resize(shape);
  
}
예제 #10
0
//-----------------------------------------------------------------------------
void TriangleCell::create_entities(boost::multi_array<unsigned int, 2>&  e,
                                   std::size_t dim, const unsigned int* v) const
{
  // We only need to know how to create edges
  if (dim != 1)
  {
    dolfin_error("TriangleCell.cpp",
                 "create entities of triangle cell",
                 "Don't know how to create entities of topological dimension %d", dim);
  }

  // Resize data structure
  e.resize(boost::extents[3][2]);

  // Create the three edges
  e[0][0] = v[1]; e[0][1] = v[2];
  e[1][0] = v[0]; e[1][1] = v[2];
  e[2][0] = v[0]; e[2][1] = v[1];
}
예제 #11
0
void wotreplay::resize(boost::multi_array<uint8_t, 3> &original, int width, int height, boost::multi_array<uint8_t, 3> &result) {
    const size_t *shape = original.shape();
    result.resize(boost::extents[height][width][shape[2]]);

    float ty = ((float) shape[0] / height);
    float tx = ((float) shape[1] / width);

    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            int xx = (int) (tx * x);
            int yy = (int) (ty * y);
            float dx = (tx * x) - xx;
            float dy = (ty * y) - yy;
            
            for (int c = 0; c < shape[2]; ++c) {
                result[y][x][c] = original[yy][xx][c]*(1-dy)*(1-dx) +
                                    original[std::min(yy + 1, (int) shape[0] - 1)][xx][c]*dy*(1-dx) +
                                    original[std::min(yy + 1, (int) shape[0] - 1)][std::min(xx + 1, (int) shape[1] - 1)][c]*dy*dx +
                                    original[yy][std::min(xx + 1, (int) shape[1]  - 1)][c]*(1-dy)*dx;
            }
        }
    }
}
예제 #12
0
int main(int argc, char** argv){

	ParseCommandLine(argc, argv);
	ParseConfigFile(config_filename);

	volume.resize(boost::extents[D][H][W]);

	FILE* in = fopen(input_filename.c_str(), "r+b");
	short *buff = new short[W];
	for(int k=0; k<D; k++){
		for(int j=0; j<H; j++){
			fread(buff, W, sizeof(short), in);
			for(int i=0; i<W; i++){
				volume[k][j][i] = (float)buff[i];// -(float)log((double)buff[i]);
			}
		}
	}
	fclose(in);


	string basename = split(input_filename, ".").at(0);

	std::ofstream ofs;
	ofs.open((basename + ".inr").c_str(), std::ios::binary);

	stringstream header;
	std::string headerEND = "##}\n";
	//Header
	header << "#INRIMAGE-4#{" << endl;
	header << "XDIM="<< W << endl;
	header << "YDIM="<< H << endl;
	header << "ZDIM="<< D << endl;
	header << "VDIM=" << 1 << endl;
	header << "VX=" << VX << endl;
	header << "VY=" << VY << endl;
	header << "VZ=" << VZ << endl;
	header << "TYPE=float" <<endl;
	header << "PIXSIZE=" << pixel_size << " bits" << endl;
	header << "CPU=decm" << endl;

	int hlen = 256 - header.str().length() - headerEND.length();
	for(int i=0; i<hlen; i++){
		header << "\n";
	}
	header << headerEND;

	ofs.write(header.str().c_str(), header.str().size());

	float *buf = new float[W];

	for(int i=0; i<D; i++){
		for(int j=0; j<H; j++){
			for(int k=0; k<W; k++){
				//ofs << volume[i][j][k];
				//buf[k] = volume[i][j][k];
				ofs.write((char*)&volume[i][j][k], sizeof(float));
			}

		}
	}

	ofs.close();
}
예제 #13
0
//-----------------------------------------------------------------------------
void MeshPartitioning::distribute_vertices(const LocalMeshData& mesh_data,
                    const boost::multi_array<std::size_t, 2>& cell_vertices,
                    std::vector<std::size_t>& vertex_indices,
                    std::map<std::size_t, std::size_t>& vertex_global_to_local,
                    boost::multi_array<double, 2>& vertex_coordinates)
{
  // This function distributes all vertices (coordinates and
  // local-to-global mapping) according to the cells that are stored on
  // each process. This happens in several stages: First each process
  // figures out which vertices it needs (by looking at its cells)
  // and where those vertices are located. That information is then
  // distributed so that each process learns where it needs to send
  // its vertices.

  // Get number of processes
  const std::size_t num_processes = MPI::num_processes();

  // Get geometric dimension
  const std::size_t gdim = mesh_data.gdim;

  // Compute which vertices we need
  std::set<std::size_t> needed_vertex_indices;
  boost::multi_array<std::size_t, 2>::const_iterator vertices;
  for (vertices = cell_vertices.begin(); vertices != cell_vertices.end();
       ++vertices)
  {
    needed_vertex_indices.insert(vertices->begin(), vertices->end());
  }

  // Compute where (process number) the vertices we need are located
  std::vector<std::vector<std::size_t> > send_vertex_indices(num_processes);
  std::vector<std::vector<std::size_t> > vertex_location(num_processes);
  std::set<std::size_t>::const_iterator required_vertex;
  for (required_vertex = needed_vertex_indices.begin();
       required_vertex != needed_vertex_indices.end(); ++required_vertex)
  {
    // Get process that has required vertex
    const std::size_t location
      = MPI::index_owner(*required_vertex, mesh_data.num_global_vertices);
    send_vertex_indices[location].push_back(*required_vertex);
    vertex_location[location].push_back(*required_vertex);
  }

  // Send required vertices to other processes, and receive back vertices
  // required by other processes.
  std::vector<std::vector<std::size_t> > received_vertex_indices;
  MPI::all_to_all(send_vertex_indices, received_vertex_indices);

  // Distribute vertex coordinates
  std::vector<std::vector<double> > send_vertex_coordinates(num_processes);
  const std::pair<std::size_t, std::size_t> local_vertex_range
    = MPI::local_range(mesh_data.num_global_vertices);
  for (std::size_t p = 0; p < num_processes; ++p)
  {
    send_vertex_coordinates[p].reserve(received_vertex_indices[p].size()*gdim);
    for (std::size_t i = 0; i < received_vertex_indices[p].size(); ++i)
    {
      dolfin_assert(received_vertex_indices[p][i] >= local_vertex_range.first
                 && received_vertex_indices[p][i] < local_vertex_range.second);
      const std::size_t location
        = received_vertex_indices[p][i] - local_vertex_range.first;
      for (std::size_t j = 0; j < gdim; ++j)
        send_vertex_coordinates[p].push_back(mesh_data.vertex_coordinates[location][j]);
    }
  }
  std::vector<std::vector<double> > received_vertex_coordinates;
  MPI::all_to_all(send_vertex_coordinates, received_vertex_coordinates);

  // Set index counters to first position in receive buffers
  std::vector<std::size_t> index_counters(num_processes, 0);

  // Clear data
  vertex_indices.clear();
  vertex_global_to_local.clear();

  // Count number of local vertices
  std::size_t num_local_vertices = 0;
  for (std::size_t p = 0; p < num_processes; ++p)
    num_local_vertices += received_vertex_coordinates[p].size()/gdim;

  // Store coordinates and construct global to local mapping
  vertex_coordinates.resize(boost::extents[num_local_vertices][gdim]);
  vertex_indices.resize(num_local_vertices);
  std::size_t v = 0;
  for (std::size_t p = 0; p < num_processes; ++p)
  {
    for (std::size_t i = 0; i < received_vertex_coordinates[p].size();
         i += gdim)
    {
      for (std::size_t j = 0; j < gdim; ++j)
        vertex_coordinates[v][j] = received_vertex_coordinates[p][i + j];

      const std::size_t global_vertex_index
        = vertex_location[p][index_counters[p]++];
      vertex_global_to_local[global_vertex_index] = v;
      vertex_indices[v] = global_vertex_index;

      ++v;
    }
  }
}
예제 #14
0
//-----------------------------------------------------------------------------
void  MeshPartitioning::distribute_cells(const LocalMeshData& mesh_data,
                            const std::vector<std::size_t>& cell_partition,
                            std::vector<std::size_t>& global_cell_indices,
                            boost::multi_array<std::size_t, 2>& cell_vertices)
{
  // This function takes the partition computed by the partitioner
  // (which tells us to which process each of the local cells stored in
  // LocalMeshData on this process belongs. We use MPI::all_to_all to
  // redistribute all cells (the global vertex indices of all cells).

  // Number of MPI processes
  const std::size_t num_processes = MPI::num_processes();

  // Get dimensions of local mesh_data
  const std::size_t num_local_cells = mesh_data.cell_vertices.size();
  dolfin_assert(mesh_data.global_cell_indices.size() == num_local_cells);
  const std::size_t num_cell_vertices = mesh_data.num_vertices_per_cell;
  if (!mesh_data.cell_vertices.empty())
  {
    if (mesh_data.cell_vertices[0].size() != num_cell_vertices)
    {
      dolfin_error("MeshPartitioning.cpp",
                   "distribute cells",
                   "Mismatch in number of cell vertices (%d != %d) on process %d",
                   mesh_data.cell_vertices[0].size(), num_cell_vertices,
                   MPI::process_number());
    }
  }

  // Build array of cell-vertex connectivity and partition vector
  // Distribute the global cell number as well
  std::vector<std::vector<std::size_t> > send_cell_vertices(num_processes);
  for (std::size_t i = 0; i < num_local_cells; i++)
  {
    const std::size_t dest = cell_partition[i];
    send_cell_vertices[dest].push_back(mesh_data.global_cell_indices[i]);
    for (std::size_t j = 0; j < num_cell_vertices; j++)
      send_cell_vertices[dest].push_back(mesh_data.cell_vertices[i][j]);
  }

  // Distribute cell-vertex connectivity
  std::vector<std::vector<std::size_t> > received_cell_vertices(num_processes);
  MPI::all_to_all(send_cell_vertices, received_cell_vertices);

  // Count number of received cells
  std::size_t num_new_local_cells = 0;
  for (std::size_t p = 0; p < received_cell_vertices.size(); ++p)
  {
    num_new_local_cells
      += received_cell_vertices[p].size()/(num_cell_vertices + 1);
  }

  // Put mesh_data back into mesh_data.cell_vertices
  cell_vertices.resize(boost::extents[num_new_local_cells][num_cell_vertices]);
  global_cell_indices.resize(num_new_local_cells);

  // Loop over new cells
  std::size_t c = 0;
  for (std::size_t p = 0; p < num_processes; ++p)
  {
    for (std::size_t i = 0; i < received_cell_vertices[p].size();
         i += (num_cell_vertices + 1))
    {
      global_cell_indices[c] = received_cell_vertices[p][i];
      for (std::size_t j = 0; j < num_cell_vertices; ++j)
        cell_vertices[c][j] = received_cell_vertices[p][i + 1 + j];

      ++c;
    }
  }
}
예제 #15
0
void Octtree::find_cell_ranks( const boost::multi_array<Real,2>& coordinates, std::vector<Uint>& ranks )
{
  ranks.resize(coordinates.size());

  Handle< Elements > element_component;
  Uint element_idx;
  std::deque<Uint> missing_cells;

  RealVector dummy(m_dim);

  for(Uint i=0; i<coordinates.size(); ++i)
  {
    for (Uint d=0; d<m_dim; ++d)
      dummy[d] = coordinates[i][d];
    if( find_element(dummy,element_component,element_idx) )
    {
      ranks[i] = Comm::instance().rank();
    }
    else
    {
      ranks[i] = math::Consts::uint_max();
      missing_cells.push_back(i);
    }
  }

  std::vector<Real> send_coords(m_dim*missing_cells.size());
  std::vector<Real> recv_coords;

  Uint c(0);
  boost_foreach(const Uint i, missing_cells)
  {
    for(Uint d=0; d<m_dim; ++d)
      send_coords[c++]=coordinates[i][d];
  }

  for (Uint root=0; root<PE::Comm::instance().size(); ++root)
  {

    recv_coords.resize(0);
    PE::Comm::instance().broadcast(send_coords,recv_coords,root,m_dim);

    // size is only because it doesn't get resized for this rank
    std::vector<Uint> send_found(missing_cells.size(),math::Consts::uint_max());

    if (root!=Comm::instance().rank())
    {
      std::vector<RealVector> recv_coordinates(recv_coords.size()/m_dim) ;
      boost_foreach(RealVector& realvec, recv_coordinates)
          realvec.resize(m_dim);

      c=0;
      for (Uint i=0; i<recv_coordinates.size(); ++i)
      {
        for(Uint d=0; d<m_dim; ++d)
          recv_coordinates[i][d]=recv_coords[c++];
      }

      send_found.resize(recv_coordinates.size());
      for (Uint i=0; i<recv_coordinates.size(); ++i)
      {
        if( find_element(recv_coordinates[i],element_component,element_idx) )
        {
          send_found[i] = Comm::instance().rank();
        }
        else
          send_found[i] = math::Consts::uint_max();
      }
    }

    std::vector<Uint> recv_found(missing_cells.size()*Comm::instance().size());
    PE::Comm::instance().gather(send_found,recv_found,root);

    if( root==Comm::instance().rank())
    {
      const Uint stride = missing_cells.size();
      for (Uint i=0; i<missing_cells.size(); ++i)
      {
        for(Uint p=0; p<Comm::instance().size(); ++p)
        {
          ranks[missing_cells[i]] = std::min(recv_found[i+p*stride] , ranks[missing_cells[i]]);
        }
      }
    }
  }
}