Help needed to use multimap

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Jan 2007
Posts: 7
Reputation: anupamsps is an unknown quantity at this point 
Solved Threads: 0
anupamsps anupamsps is offline Offline
Newbie Poster

Help needed to use multimap

 
0
  #1
Nov 6th, 2008
hi friends;
i am trying to build a class using multimap, the idea is something like this:
I have say N no of particles and each particle has fix position in 3d space

something like this:

Coordinate: Particle level
(1,2,3) ----------------> 1
(1,2,3) ----------------> 7
(1,0,0) ----------------> 2
(0,0,0) ----------------> 0
..... and so on

I tried this with 4d array like Pos[x][y][z][I], but i dont like the approach and thought maybe using multimap from stl will be more effivient in this kind of mapping. Please put your inputs in this regard.

i'll now show the class i have devolopped so far
// Container class that define (i,j,k) triplet

#include<iostream>
#include<map>
#include<set>
#include<iomanip>

typedef class container store;
typedef std::pair<const store, int> Pair;
typedef std::multimap< store, int > Box;

// 1st class container definition
class container
{
      private:
              int _i;
              int _j;
              int _k;
      public:
             container():_i(0),_j(0),_k(0){} //constructor
                       
             container(const int&i, const int&j,
                       const int&k):_i(i),_j(j),_k(k){} //constructor
                       
             container(const container& t)  //copy constructor
             { _i=t._i;
               _j=t._j;
               _k=t._k;}          
                       
             bool operator>(const container& t)const     // need to understand
                           { return _k>t._k||_j>t._j||_i>t._i;}    
                                                                                                                           
            bool operator<(const container& t)const
                           {return _k<t._k||_j<t._j||_i<t._i;}    // need to understand

             bool operator()(const container& __x, const container& __y) const
                             { return __x < __y; }   
                                 
            container & operator=(const container & t) //Assignment Operator
            {
                      if (this == &t) // object assigned to itself
                      return *this; // all done
                      _i=t._i;
                      _j=t._j;
                      _k=t._k;
                       return *this;                 
            }   
                  
                                      
             friend std::ostream & operator<<(std::ostream & os, const container & t)
                           {
                              os << "(" << t._i << "," << t._j<<","<<t._k<<")";
                              return os;
                            }
             ~container(){}
      };

Next i write the mapping class using particle and data triplet defined in container class

  1.  
  2. class _Map
  3. {
  4. private:
  5. Box xx;
  6.  
  7. public:
  8. _Map(){} //default constructor
  9. void int_insert(const store &HOLD, const int &the_number)
  10. {xx.insert(Pair(HOLD,the_number));} //HOLD is the key index where the number is inserted
  11.  
  12. int WholeEraseByKey(const store &HOLD) //it also returns the number of erased elements
  13. {
  14. Box::size_type n;
  15. n = xx.erase(HOLD);
  16. return n;
  17. }
  18.  
  19.  
  20. void ShowMap()
  21. {
  22. Box::iterator pos;
  23. std::cout.setf(std::ios::left, std::ios::adjustfield);
  24.  
  25. for (pos=xx.begin(); pos!=xx.end(); ++pos) {
  26. std::cout << pos->first << " ->"
  27. << pos->second << std::endl;
  28. }
  29. }
  30.  
  31. ~_Map(){}
  32. };


This code so far works fine. But i need to put some more functionality where i am getting confused.

1. remove a particular particle.
say i have: (0,0,0) ----> 7
(0,0,0) -----> 8
(0,0,0) ------> 10
(1,1,1) --------> 1

and i need to erase the value 10 only. I am only able to erase the whole map with key value (0,0,0).

2. Secondly is it possible by looking at value, to retrive the information about is coordinate without doing a full search.

Please comment.
thanks
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 397
Reputation: StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light 
Solved Threads: 72
StuXYZ StuXYZ is offline Offline
Posting Whiz

Re: Help needed to use multimap

 
0
  #2
Nov 22nd, 2008
You seem to be doing what every condensed matter phys. student does a sometime that is to write an atomic simulation.
So I am assuming that is so. What you want is to have a multimap
that allows you to quickly obtain those particle of a particular type or
you use level (spin state maybe?), then process them. However, it is 99.99% certain that you are going to need to do it efficiently.

So use first off make your life easy and define a Atom class which holds 3D position and anything else you need. Here is a minimalistic
structure. Add cons/dest/copy etc

  1. struct Atom
  2. {
  3. double x;
  4. double y;
  5. double z;
  6. };

Next:

Let us create a multimap and insert some atoms (I am using a typedef
because to keep the typing down. (let me know if you want it written completely)

  1. typedef std::multimap<int,Atom> mmTYPE;
  2. mmTYPE Amap; // Make a multimap called Amap
  3. Amap.insert(mmTYPE::value_type(7,Atom(3,4,5)) ;
  4. Amap.insert(mmTYPE::value_type(8,Atom(1,2,3)) ;
  5. Amap.insert(mmTYPE::value_type(7,Atom(6,-3,5)) ;

Note that we have two atoms (different position) at index 7.
Let us erase all atoms at level 7 AND with a negative Y position.
That is only ONE of the level 7 atoms.

  1. mmTYPE::iterator mc=Amap.find(7);
  2. for(;mc!=Amap.end() && mc->first==7;mc++)
  3. if (mc->second.y<0)
  4. {
  5. Amap.erase(mc);
  6. mc=Amap.find(7);
  7. }

Ok the loop is messy, because the deletion invalidates the map iterator, so it has to be re-created. It is also very inefficient if
the secondary test is complex. However, if you need to improve the optimization here, then looking at your version of the STL, can show you how much you can rely on the iterator after the find.

All of the above can be done with a functor class. If the secondary test is expensive, then caching the results etc, is often done. (as is marking stuff dead and doing local garbage collection later when the dead score gets about x%)

Finally, yes I have re-ordered you map, from Point -> level to level->point. That will give you a large performance improvement.
Reply With Quote Quick reply to this message  
Join Date: Jan 2007
Posts: 7
Reputation: anupamsps is an unknown quantity at this point 
Solved Threads: 0
anupamsps anupamsps is offline Offline
Newbie Poster

Re: Help needed to use multimap

 
0
  #3
Nov 26th, 2008
thanks for digging this out.
And you have guessed it correctly, i am trying to devolop code for event driven simulation of dilute granular gas. To avoid technical details i had phrased the problem that way.

The reason i choose to follow:level->point is that
level resembles box in 3 dimension. I have to hop through different boxes, search for particle, remove, insert, calculate interaction with neighbour boxes.
So apperently information about certain box in 3d is imporatnt not the other way.
Last edited by anupamsps; Nov 26th, 2008 at 5:29 am.
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 397
Reputation: StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light StuXYZ is a glorious beacon of light 
Solved Threads: 72
StuXYZ StuXYZ is offline Offline
Posting Whiz

Re: Help needed to use multimap

 
0
  #4
Nov 26th, 2008
Despite your simulation set up, do not put the point as the first
part of the map.

The map is actually a std::set taking a pair. It is sorted on the first
on a red-black tree. If you use a point, you will end up with a horrific sorting problem, insert removes will take forever, additionally, I know of no way of getting avoiding the problem of different sort criteria for a point. (you need the particle closest to X). So divide you space into N bin and use that as the level and the map index. You can be clever and divide say 1024 and sub-divide each by another 1024 and make a large number for the level. This it is easy to pick-out based on the find.

If you need to do something specialized on the 3d-point write your own map/set class.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C++ Forum
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC