Example #1
0
File: main.cpp Project: CCJY/coliru
Map3 foo( Map1 const & m1, Map2 const & m2 ) {
    auto m2end = m2.end(); // a constant call is move outside the loop
    Map3 result;
    for( auto & v1 : m1 ) { // each entry in m1 is made of the key as first and the value as second
        for( auto & p1 : v1.second ) { // iterate over the vector of pair
            auto v2it = m2.find( p1 ); // search for the pair
            if ( v2it != m2end ) {
                result[v1.first] += v2it->second; // if the pair was found, add the value for it to the result, using the map1 key as key
            }
        }
    }
    return result;
}
Example #2
0
void BBFind::squash(Map2 &map, float scaleMin, float scaleMax)
{
   // Overloaded to work on Map2 or Map3. Normalizes, but sets
   // initial min / max values to given arguments. If the given
   // range is larger than the data's range, the data is scaled
   // down proportionally. Otherwise, it just normalizes to the
   // given range.

   int mapWidth = (int)map[0].size();
   int mapHeight = (int)map.size();

   float maxVal = scaleMax;
   float minVal = scaleMin;

   for(int x = 0; x < mapWidth; x++)
   {
      for(int y = 0; y < mapHeight; y++)
      {
         float val = map[y][x];
         maxVal = val > maxVal ? val : maxVal;
         minVal = val < minVal ? val : minVal;
      }
   }
   float range = maxVal - minVal;
   #ifdef PV_USE_OPENMP_THREADS
      #pragma omp parallel for
   #endif
   for(int x = 0; x < mapWidth; x++)
   {
      for(int y = 0; y < mapHeight; y++)
      {
         map[y][x] = scaleMin + ((map[y][x] - minVal) / range) * scaleMax;
      }
   }
}
Example #3
0
float BBFind::sigmoidedRMS(const Map2 confMap, const Rectangle &bounds)
{
   // Takes the RMS of the given sub area and applies a sigmoid to
   // smoothly cap values at 1.0

	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	float sum = 0.0f;
	for(int x = 0; x < bounds.width; x++)
	{
		for(int y = 0; y < bounds.height; y++)
		{
			int _x = bounds.left() + x;
			int _y = bounds.top()  + y;
			if(_x < 0 || _x >= mapWidth || _y < 0 || _y >= mapHeight) continue;
			sum += pow(confMap[_y][_x], 2);
		}
	}
	float avg = sqrt(sum / (mapWidth*mapHeight));
	float e = exp(1);
	// This is a very easy curve that still soft caps at 1.0.
	// Combined with the increaseContrast function, it allows
   // values > 0.85 to bring the average up based on the contrast argument.
	return  (1.0f / (1.0f + pow(e,-e*avg)) - 0.5f) * 2.0f;
}
Example #4
0
BBFind::Map2 BBFind::scale(const Map2 &source, int newWidth, int newHeight, bool bilinear)
{
   // Rescales the map's dimensions using either
   // bilinear interpolation or nearest neighbor.

   Map2 result(newHeight);
   int sourceWidth = source[0].size();
   int sourceHeight = source.size();

   if(bilinear) // Bilinear scaling
   {
      for(int j = 0; j < newHeight; j++)
      {
         result[j].resize(newWidth);
         for(int i = 0; i < newWidth; i++)
         {
            float xSource = i / (float)(newWidth-1) * (sourceWidth-1);
            float ySource = j / (float)(newHeight-1) * (sourceHeight-1);

            int leftIndex   = (int)xSource;
            int rightIndex  = (int)ceil(xSource);
            int topIndex    = (int)ySource;
            int bottomIndex = (int)ceil(ySource);

            if(topIndex < 0)  topIndex = 0;
            if(leftIndex < 0) leftIndex = 0;
            if(rightIndex >= sourceWidth)   rightIndex = sourceWidth-1;
            if(bottomIndex >= sourceHeight) bottomIndex = sourceHeight-1;

            float xAlign = xSource - leftIndex;
            float yAlign = ySource - topIndex;

            float tl = source[topIndex][leftIndex]     * (1.0f - xAlign) * (1.0f - yAlign);
            float tr = source[topIndex][rightIndex]    * xAlign * (1.0f - yAlign);
            float bl = source[bottomIndex][leftIndex]  * (1.0f - xAlign) * yAlign;
            float br = source[bottomIndex][rightIndex] * xAlign * yAlign;
            result[j][i] = tl+tr+bl+br;
         }
      }
   }
   else // Nearest neighbor scaling, no interpolation
   {
      float xRatio = sourceWidth / (float)(newWidth);
      float yRatio = sourceHeight / (float)(newHeight);

      #ifdef PV_USE_OPENMP_THREADS
			#pragma omp parallel for
		#endif
      for(int j = 0; j < newHeight; j++)
      {
         result[j].resize(newWidth);
         for(int i = 0; i < newWidth; i++)
         {
            result[j][i] = source[(int)(j*yRatio)][(int)(i*xRatio)];
         }
      }
   }
   return result;
}
static void BENCH_Dart_count_single_threaded(benchmark::State& state)
{
	while (state.KeepRunning())
	{
		unsigned nb_darts = 0u;
		bench_map.foreach_dart([&nb_darts] (cgogn::Dart) { nb_darts++; });
	}
}
static void BENCH_Dart_count_multi_threaded(benchmark::State& state)
{
	while (state.KeepRunning())
	{
		uint32 nb_darts_2 = 0u;
		std::vector<uint32> nb_darts_per_thread(cgogn::nb_threads() + 2);
		for (auto& n : nb_darts_per_thread)
			n = 0u;
		nb_darts_2 = 0u;
		bench_map.parallel_foreach_dart([&nb_darts_per_thread] (cgogn::Dart, uint32 thread_index)
		{
			nb_darts_per_thread[thread_index]++;
		});
		for (uint32 n : nb_darts_per_thread)
			nb_darts_2 += n;

		cgogn_assert(nb_darts_2 == bench_map.nb_darts());
	}
}
Example #7
0
void Viewer::import(const std::string& surfaceMesh)
{
	cgogn::io::import_surface<Vec3>(map_, surfaceMesh);

	map_.get_attribute(vertex_position_, "position");

	cgogn::geometry::compute_AABB(vertex_position_, bb_);

	setSceneRadius(bb_.diag_size()/2.0);
	Vec3 center = bb_.center();
	setSceneCenter(qoglviewer::Vec(center[0], center[1], center[2]));
	showEntireScene();
}
Example #8
0
BBFind::Map2 BBFind::applyThreshold(const Map2 confMap, float threshold)
{
   // Clips any values below threshold
   // TODO: Can this just modify the map in-place?
	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	Map2 resultMap = confMap;

   #ifdef PV_USE_OPENMP_THREADS
		#pragma omp parallel for
   #endif
   for(int x = 0; x < mapWidth; x++)
	{
		for(int y = 0; y < mapHeight; y++)
		{
         resultMap[y][x] = (confMap[y][x] >= threshold ? confMap[y][x] : 0.0f);
		}
	}
	return resultMap;
}
static void BENCH_vertices_normals_cache_multi_threaded(benchmark::State& state)
{
	while(state.KeepRunning())
	{
		state.PauseTiming();
		VertexAttribute<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
		cgogn_assert(vertex_position.is_valid());
		VertexAttribute<Vec3> vertices_normal = bench_map.get_attribute<Vec3, VERTEX>("normal");
		cgogn_assert(vertices_normal.is_valid());

		cgogn::CellCache<Map2> cache(bench_map);
		cache.template build<Vertex>();
		state.ResumeTiming();

		bench_map.parallel_foreach_cell([&] (Vertex v, uint32)
		{
			vertices_normal[v] = cgogn::geometry::normal<Vec3>(bench_map, v, vertex_position);
		},
		cache);
	}
}
static void BENCH_faces_normals_cache_single_threaded(benchmark::State& state)
{
	while(state.KeepRunning())
	{
		state.PauseTiming();
		VertexAttribute<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
		cgogn_assert(vertex_position.is_valid());
		FaceAttribute<Vec3> face_normal = bench_map.get_attribute<Vec3, FACE>("normal");
		cgogn_assert(face_normal.is_valid());

		cgogn::CellCache<Map2> cache(bench_map);
		cache.template build<Face>();
		state.ResumeTiming();

		bench_map.foreach_cell([&] (Face f)
		{
			face_normal[f] = cgogn::geometry::normal<Vec3>(bench_map, f, vertex_position);
		},
		cache);
	}
}
Example #11
0
int main(int , char** )
{
    int32 x = 4;
    int32 y = 4;

    const cgogn::Orbit vertorb = Map2::Vertex::ORBIT;

    {
        Map2 map;
        VertexAttribute<Vec3> vertex_grid = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("grid");
        VertexAttribute<Vec3> vertex_twisted_strip = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("twisted_strip");
        VertexAttribute<Vec3> vertex_helicoid = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("helicoid");

        //		map.add_attribute<int32, Map2::CDart::ORBIT>("darts");
        map.add_attribute<int32, Map2::Edge::ORBIT>("edges");
        map.add_attribute<int32, Map2::Face::ORBIT>("faces");
        map.add_attribute<int32, Map2::Volume::ORBIT>("volumes");

        cgogn::modeling::SquareGrid<Map2> g(map, x, y);

        std::cout << "is good ? " << std::boolalpha << map.check_embedding_integrity() << std::endl;

        g.embed_into_grid(vertex_grid, 10.0f, 10.0f, 0.0f);
        g.embed_into_twisted_strip<Vec3>(vertex_twisted_strip, 10.0f, 5.0f, 3.1f);
        g.embed_into_helicoid<Vec3>(vertex_helicoid, 10.0f, 5.0f, 15.0f, 3.0f, 1);

        cgogn::io::export_surface(map, cgogn::io::ExportOptions("grid.off", {vertorb, "grid"}, {}, false, false));
        cgogn::io::export_surface(map, cgogn::io::ExportOptions("twisted_strip.off", {vertorb, "twisted_strip"}, {}, false, false));
        cgogn::io::export_surface(map, cgogn::io::ExportOptions("helicoid.off", {vertorb, "helicoid"}, {}, false, false));
    }

    {
        Map2 map;
        VertexAttribute<Vec3> vertex_cylinder = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("cylinder");
        VertexAttribute<Vec3> vertex_sphere = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("sphere");
        VertexAttribute<Vec3> vertex_cone = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("cone");

        //		map.add_attribute<int32, Map2::CDart::ORBIT>("darts");
        map.add_attribute<int32, Map2::Edge::ORBIT>("edges");
        map.add_attribute<int32, Map2::Face::ORBIT>("faces");
        map.add_attribute<int32, Map2::Volume::ORBIT>("volumes");

        cgogn::modeling::SquareCylinder<Map2> g(map, x, y);

        std::cout << "is good ? " << std::boolalpha << map.check_embedding_integrity() << std::endl;

        g.close_top();
        g.close_bottom();
        g.triangule_top();
        g.triangule_bottom();

        g.embed_into_cylinder(vertex_cylinder, 10.0f, 8.0f, 5.0f);
        g.embed_into_sphere<Vec3>(vertex_sphere, 10.0f);
        g.embed_into_cone<Vec3>(vertex_cone, 10.0f, 5.0f);

        cgogn::io::export_surface(map, cgogn::io::ExportOptions("cylinder.off", {vertorb, "cylinder"}, {}, false, false));
        cgogn::io::export_surface(map, cgogn::io::ExportOptions("sphere.off", {vertorb, "sphere"}, {}, false, false));
        cgogn::io::export_surface(map, cgogn::io::ExportOptions("cone.off", {vertorb, "cone"}, {}, false, false));
    }

    {
        Map2 map;
        VertexAttribute<Vec3> vertex_tore = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("tore");

        //		map.add_attribute<int32, Map2::CDart::ORBIT>("darts");
        map.add_attribute<int32, Map2::Edge::ORBIT>("edges");
        map.add_attribute<int32, Map2::Face::ORBIT>("faces");
        map.add_attribute<int32, Map2::Volume::ORBIT>("volumes");

        cgogn::modeling::SquareTore<Map2> g(map, x, y);

        std::cout << "is good ? " << std::boolalpha << map.check_embedding_integrity() << std::endl;

        g.embed_into_tore(vertex_tore, 10.0f, 4.0f);

        cgogn::io::export_surface(map, cgogn::io::ExportOptions("tore.off", {vertorb, "tore"}, {}, false, false));
    }

    /*	{
    		Map2 map;
    		cgogn::modeling::TriangularCube<Map2> g(map, x, y, x);

    		VertexAttribute<Vec3> vertex_tore = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("cube");
    		g.embed_into_cube(vertex_tore, 10.0f, 4.0f, 5.0f);

    		std::vector<std::pair<cgogn::Orbit,std::string>> att_vec;
    		att_vec.push_back(std::make_pair(cgogn::Orbit(Map2::Vertex::ORBIT), std::string("cube")));
    		cgogn::io::export_surface(map, cgogn::io::ExportOptions("cube.off", att_vec, false));
    	}
    */
    return 0;
}
Example #12
0
BBFind::Map2 BBFind::makeEdgeDistanceMap(const Map2 confMap)
{
   // Modified Dijkstra map algorithm based on:
   // http://www.roguebasin.com/index.php?title=The_Incredible_Power_of_Dijkstra_Maps
   // The original algorithm finds nearest distance to a goal.
   // This modified version finds the larger distance, horizontal or vertical,
   // to a 0 confidence value (used to find object edges after threshold clipping)

	int mapWidth = confMap[0].size();
	int mapHeight = confMap.size();
	int maxVal = std::max(mapWidth, mapHeight);

   Map2 horizMap(mapHeight);
   Map2 vertMap(mapHeight);

   for(int y = 0; y < mapHeight; y++)
	{
      horizMap[y].resize(mapWidth);
      vertMap[y].resize(mapWidth);
		for(int x = 0; x < mapWidth; x++)
		{
         if(confMap[y][x] > 0)
         {
            horizMap[y][x] = maxVal;
            vertMap[y][x] = maxVal;
         }
      }
   }

   // Finds the shortest distance to 0 conf value in horizontal and vertical direction,
   // and stores the biggest one into result. This allows long, thin confidence chunks
   // to avoid clipping

   bool changed = true;
   while(changed)
   {
      changed = false;
      for(int y = 1; y < mapHeight-1; y++)
      {
         for(int x = 1; x < mapWidth-1; x++)
         {
            float lowest = horizMap[y][x];
            lowest = std::min(lowest, horizMap[y][x-1]);
            lowest = std::min(lowest, horizMap[y][x+1]);

            if(horizMap[y][x] > lowest+1)
            {
               horizMap[y][x] = lowest + 1;
               changed = true;
            }
         }
      }
   }

   changed = true;
   while(changed)
   {
      changed = false;
      for(int y = 1; y < mapHeight-1; y++)
      {
         for(int x = 1; x < mapWidth-1; x++)
         {
            float lowest = vertMap[y][x];
            lowest = std::min(lowest, vertMap[y-1][x]);
            lowest = std::min(lowest, vertMap[y+1][x]);

            if(vertMap[y][x] > lowest+1)
            {
               vertMap[y][x] = lowest + 1;
               changed = true;
            }
         }
      }
   }

   Map2 resultMap = horizMap;

   #ifdef PV_USE_OPENMP_THREADS
		#pragma omp parallel for
   #endif
   for(int y = 0; y < mapHeight; y++)
	{
		for(int x = 0; x < mapWidth; x++)
		{
         if(vertMap[y][x] > resultMap[y][x])
         {
            resultMap[y][x] = vertMap[y][x];
         }
      }
   }

	return resultMap;
}
Example #13
0
int main(int argc, char** argv)
{
	std::string surfaceMesh;
	if (argc < 2)
	{
		cgogn_log_info("cmap2_import") << "USAGE: " << argv[0] << " [filename]";
		surfaceMesh = std::string(DEFAULT_MESH_PATH) + std::string("off/aneurysm_3D.off");
		cgogn_log_info("cmap2_import") << "Using default mesh : " << surfaceMesh;
	}
	else
		surfaceMesh = std::string(argv[1]);

	Map2 map;

	for (uint32 k = 0; k < 2; ++k)
	{
		cgogn::io::import_surface<Vec3>(map, surfaceMesh);

		uint32 nb_darts = 0;
		map.foreach_dart([&nb_darts] (cgogn::Dart) { nb_darts++; });
		cgogn_log_info("cmap2_import") << "nb darts -> " << nb_darts;

		uint32 nb_darts_2 = 0;
		std::vector<uint32> nb_darts_per_thread(cgogn::NB_THREADS - 1);
		for (uint32& n : nb_darts_per_thread)
			n = 0;
		map.parallel_foreach_dart([&nb_darts_per_thread] (cgogn::Dart, uint32 thread_index)
		{
			nb_darts_per_thread[thread_index]++;
		});
		for (uint32 n : nb_darts_per_thread)
			nb_darts_2 += n;
		cgogn_log_info("cmap2_import")<< "nb darts // -> " << nb_darts_2;

		VertexAttribute<Vec3> vertex_position = map.get_attribute<Vec3, Map2::Vertex::ORBIT>("position");
		VertexAttribute<Vec3> vertex_normal = map.add_attribute<Vec3, Map2::Vertex::ORBIT>("normal");
		FaceAttribute<Vec3> face_normal = map.add_attribute<Vec3, Map2::Face::ORBIT>("normal");

		cgogn_log_info("cmap2_import")  << "Map integrity : " << std::boolalpha << map.check_map_integrity();

		uint32 nb_vertices = 0;
		cgogn::CellCache<Map2> cache(map);
		cache.build<Map2::Vertex>();
		map.foreach_cell([&nb_vertices] (Map2::Vertex) { nb_vertices++; }, cache);
		cgogn_log_info("cmap2_import") << "nb vertices -> " << nb_vertices;

		uint32 nb_boundary_faces = 0;
		cgogn::BoundaryCache<Map2> bcache(map);
		map.foreach_cell([&nb_boundary_faces] (Map2::Boundary) { nb_boundary_faces++; }, bcache);
		cgogn_log_info("cmap2_import") << "nb boundary faces -> " << nb_boundary_faces;

		uint32 nb_faces = 0;
		map.foreach_cell([&nb_faces] (Map2::Face) { nb_faces++;});
		cgogn_log_info("cmap2_import") << "nb faces -> " << nb_faces;

		uint32 nb_faces_2 = 0;
		std::vector<uint32> nb_faces_per_thread(cgogn::NB_THREADS - 1);
		for (uint32& n : nb_faces_per_thread)
			n = 0;
		map.parallel_foreach_cell([&nb_faces_per_thread] (Map2::Face, uint32 thread_index)
		{
			nb_faces_per_thread[thread_index]++;
		});
		for (uint32 n : nb_faces_per_thread)
			nb_faces_2 += n;
		cgogn_log_info("cmap2_import") << "nb faces // -> " << nb_faces_2;

		std::chrono::time_point<std::chrono::system_clock> start, end;
		start = std::chrono::system_clock::now();

		for	(uint32 i = 0; i < 10; ++i)
			cgogn::geometry::compute_normal<Vec3>(map, vertex_position, face_normal);

		for	(uint32 i = 0; i < 10; ++i)
			cgogn::geometry::compute_normal<Vec3>(map, vertex_position, vertex_normal);

		end = std::chrono::system_clock::now();
		std::chrono::duration<float64> elapsed_seconds = end - start;
		cgogn_log_info("cmap2_import") << "elapsed time: " << elapsed_seconds.count() << "s";
	}

	return 0;
}
Example #14
0
// ==========================================================================
/// Main execution
// ==========================================================================
StatusCode MapAlg::execute()
{
  using namespace Gaudi::Utils ;

  Rndm::Numbers gauss   ( randSvc() , Rndm::Gauss       (   0.0 ,   1.0 ) ) ;
  Rndm::Numbers gauss2  ( randSvc() , Rndm::Gauss       (   0.0  , 10.0 ) ) ;

  const Key   key    = Key ( gauss2  () ) ;
  const Value value1 =  Value( int( 100 * gauss () ) ) / 100.0 ;

  always()
    << " Inserting key " << toString(key) << " 1st: "
    << " " << toString ( m_map1.insert ( std::make_pair ( key , value1 ) ).second )
    << " " << toString ( m_map2.insert ( std::make_pair ( key , value1 ) ).second )
    << " " << toString ( m_map3.insert ( std::make_pair ( key , value1 ) ).second )
    << " " << toString ( m_map4.insert ( std::make_pair ( key , value1 ) ).second )
    << endmsg ;

  always() << "1 Map1: " << toString ( m_map1 ) << endmsg ;
  always() << "1 Map2: " << toString ( m_map2 ) << endmsg ;
  always() << "1 Map3: " << toString ( m_map3 ) << endmsg ;
  always() << "1 Map4: " << toString ( m_map4 ) << endmsg ;

  print1 ( (Key) 1 ) ;

  always() << "2 Map1: " << toString ( m_map1 ) << endmsg ;
  always() << "2 Map2: " << toString ( m_map2 ) << endmsg ;
  always() << "2 Map3: " << toString ( m_map3 ) << endmsg ;
  always() << "2 Map4: " << toString ( m_map4 ) << endmsg ;

  print2 ( (Key) 7  ) ;

  always() << "3 Map1: " << toString ( m_map1 ) << endmsg ;
  always() << "3 Map2: " << toString ( m_map2 ) << endmsg ;
  always() << "3 Map3: " << toString ( m_map3 ) << endmsg ;
  always() << "3 Map4: " << toString ( m_map4 ) << endmsg ;

  const Value value2 =       gauss   () ;

  always()
    << " Inserting key " << toString(key) << " 2nd: "
    << " " << toString ( m_map1.insert ( std::make_pair ( key , value2 ) ).second )
    << " " << toString ( m_map2.insert ( std::make_pair ( key , value2 ) ).second )
    << " " << toString ( m_map3.insert ( std::make_pair ( key , value2 ) ).second )
    << " " << toString ( m_map4.insert ( std::make_pair ( key , value2 ) ).second )
    << endmsg ;

  always() << "4 Map1: " << toString ( m_map1 ) << endmsg ;
  always() << "4 Map2: " << toString ( m_map2 ) << endmsg ;
  always() << "4 Map3: " << toString ( m_map3 ) << endmsg ;
  always() << "4 Map4: " << toString ( m_map4 ) << endmsg ;

  if ( 0 == ::labs(key)%2 )
  {
    always()
      << " Erased : "
      << " " << toString ( 0 != m_map1.erase ( key ) )
      << " " << toString ( 0 != m_map2.erase ( key ) )
      << " " << toString ( 0 != m_map3.erase ( key ) )
      << " " << toString ( 0 != m_map4.erase ( key ) )
      << endmsg ;
  }

  always() << "5 Map1: " << toString ( m_map1 ) << endmsg ;
  always() << "5 Map2: " << toString ( m_map2 ) << endmsg ;
  always() << "5 Map3: " << toString ( m_map3 ) << endmsg ;
  always() << "5 Map4: " << toString ( m_map4 ) << endmsg ;

  always()
    << " Count key    0 : "
    << " " << m_map1.count ( 0 )
    << " " << m_map2.count ( 0 )
    << " " << m_map3.count ( 0 )
    << " " << m_map4.count ( 0 )
    << endmsg ;
  always()
    << " Count key    1 : "
    << " " << m_map1.count ( 1 )
    << " " << m_map2.count ( 1 )
    << " " << m_map3.count ( 1 )
    << " " << m_map4.count ( 1 )
    << endmsg ;
  always()
    << " Count key    7 : "
    << " " << m_map1.count ( 7 )
    << " " << m_map2.count ( 7 )
    << " " << m_map3.count ( 7 )
    << " " << m_map4.count ( 7 )
    << endmsg ;
  always()
    << " Count key -100 : "
    << " " << m_map1.count ( -100 )
    << " " << m_map2.count ( -100 )
    << " " << m_map3.count ( -100 )
    << " " << m_map4.count ( -100 )
    << endmsg ;


  return StatusCode::SUCCESS;
}
Example #15
0
void intersectValues(Map const& map, Map2 const& map2, DotProductResult& dotResult) {
  if (map.size() < map2.size())
    intersectValues(map.begin(), map.end(), map2, dotResult);
  else
    intersectValues(map, map2.begin(), map2.end(), dotResult);
}