SISCone  2.0.5
siscone/spherical/hash.cpp
00001 
00002 // File: hash.cpp                                                            //
00003 // Description: source file for classes sph_hash_element and sph_hash_cones  //
00004 // This file is part of the SISCone project.                                 //
00005 // WARNING: this is not the main SISCone trunk but                           //
00006 //          an adaptation to spherical coordinates                           //
00007 // For more details, see http://projects.hepforge.org/siscone                //
00008 //                                                                           //
00009 // Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez                          //
00010 //                                                                           //
00011 // This program is free software; you can redistribute it and/or modify      //
00012 // it under the terms of the GNU General Public License as published by      //
00013 // the Free Software Foundation; either version 2 of the License, or         //
00014 // (at your option) any later version.                                       //
00015 //                                                                           //
00016 // This program is distributed in the hope that it will be useful,           //
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of            //
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             //
00019 // GNU General Public License for more details.                              //
00020 //                                                                           //
00021 // You should have received a copy of the GNU General Public License         //
00022 // along with this program; if not, write to the Free Software               //
00023 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
00024 //                                                                           //
00025 // $Revision:: 294                                                          $//
00026 // $Date:: 2009-05-01 17:15:04 +0200 (Fri, 01 May 2009)                     $//
00028 
00029 #include <math.h>
00030 #include <stdio.h>
00031 #include "hash.h"
00032 #include <iostream>
00033 
00034 namespace siscone_spherical{
00035 
00036 using namespace std;
00037 
00038 /**************************************************************
00039  * implementation of sph_hash_cones                           *
00040  * list of cones candidates.                                  *
00041  * We store in this class all the sph_hash_element and give   *
00042  * functions to manipulate them.                              *
00043  **************************************************************/
00044 
00045 // constructor with initialisation
00046 //  - _Np      number of particles
00047 //  - _radius  cone radius
00048 //-----------------------------------
00049 sph_hash_cones::sph_hash_cones(int _Np, double _radius){
00050   int i;
00051 
00052   n_cones = 0;
00053 #ifdef DEBUG_STABLE_CONES
00054   n_occupied_cells = 0;
00055 #endif
00056 
00057   // determine hash size
00058   // for a ymax=5 and R=0.7, we observed an occupancy around 1/8 N^2 ~ N2 R2/4
00059   //mask = 1 << (int) (2*log(double(_Np))/log(2.0));
00060   //if (mask<=1) mask=2;
00061   int nbits = (int) (log(_Np*_radius*_radius*_Np/4.0)/log(2.0));
00062   if (nbits<1) nbits=1;
00063   mask = 1 << nbits;
00064 
00065   // create hash
00066   hash_array = new sph_hash_element*[mask];
00067   mask--;
00068 
00069   // set the array to 0
00070   //? needed ?
00071   for (i=0;i<mask+1;i++)
00072     hash_array[i] = NULL;
00073 
00074   tan2R = tan(_radius);
00075   tan2R *= tan2R;
00076 }
00077 
00078 // destructor
00079 //------------
00080 sph_hash_cones::~sph_hash_cones(){
00081   int i;
00082   sph_hash_element *elm;
00083 
00084   for (i=0;i<mask+1;i++){
00085     while (hash_array[i]!=NULL){
00086       elm = hash_array[i];
00087       hash_array[i] = hash_array[i]->next;
00088       delete elm;
00089     }
00090   }
00091 
00092   delete[] hash_array;
00093 }
00094 
00095 
00096 /*
00097  * insert a new candidate into the hash.
00098  *  - v       4-momentum of the cone to add
00099  *  - parent  parent particle defining the cone
00100  *  - child   child particle defining the cone
00101  *  - p_io    whether the parent has to belong to the cone or not
00102  *  - c_io    whether the child has to belong to the cone or not
00103  * return 0 on success, 1 on error
00104  ***********************************************************************/
00105 int sph_hash_cones::insert(CSphmomentum *v, CSphmomentum *parent, CSphmomentum *child, bool p_io, bool c_io){
00106   sph_hash_element *elm;
00107   int index = (v->ref.ref[0]) & mask;
00108 
00109   // check the array cell corresponding to our reference
00110   elm = hash_array[index];
00111 
00112 #ifdef DEBUG_STABLE_CONES
00113   if (elm==NULL)
00114     n_occupied_cells++;
00115 #endif
00116 
00117   do{
00118     // if it is not present, add it
00119     if (elm==NULL){
00120       // create element
00121       elm = new sph_hash_element;
00122 
00123       // set its varibles
00124       // Note: at this level, eta and phi have already been computed
00125       //       through CSphmomentum::build_thetaphi.
00126       elm->centre = *v;
00127       
00128       // if at least one of the two is_closer tests gives a result != from the expected,
00129       // the || will be true hence !(...) false as wanted
00130       elm->is_stable = !((is_closer(v, parent, tan2R)^p_io)||(is_closer(v, child, tan2R)^c_io));
00131       //cout << "-- new status of " <<  v->ref[0] << ":" << elm->is_stable << endl;
00132 
00133       // update hash
00134       elm->next = hash_array[index];
00135       hash_array[index] = elm;
00136       
00137       n_cones++;
00138       return 0;
00139     }
00140 
00141     // if the cone is already there, simply update stability status
00142     if (v->ref == elm->centre.ref){
00143       // there is only an update to perform to see if the cone is still stable
00144       if (elm->is_stable){
00145         elm->is_stable = !((is_closer(v, parent, tan2R)^p_io)||(is_closer(v, child, tan2R)^c_io));
00146         //cout << " parent/child: " 
00147         //     << parent->ref[0] << ":" << is_closer(v, parent) << ":" << p_io << " "
00148         //     << child->ref[0] << ":" << is_closer(v, child) << ":" << c_io << endl;
00149         //cout << "-- rep status of " <<  v->ref[0] << ":" << elm->is_stable << endl;
00150         //cout << v->eta << " " << v->phi << endl;
00151         //cout << (child->eta) << " " << child->phi << endl;
00152       }
00153       return 0;
00154     }
00155 
00156     elm = elm->next;
00157   } while (1);
00158 
00159   return 1;
00160 }
00161 
00162 /*
00163  * insert a new candidate into the hash.
00164  *  - v       4-momentum of te cone to add
00165  * Note, in this case, we assume stability. We also assume
00166  * that eta and phi are computed for v
00167  * return 0 on success, 1 on error
00168  ***********************************************************************/
00169 int sph_hash_cones::insert(CSphmomentum *v){
00170   sph_hash_element *elm;
00171   int index = (v->ref.ref[0]) & mask;
00172   //cout << "-- stable candidate: " << v->ref[0] << ":" << endl;
00173 
00174   // check the array cell corresponding to our reference
00175   elm = hash_array[index];
00176   do{
00177     // if it is not present, add it
00178     if (elm==NULL){
00179       // create element
00180       elm = new sph_hash_element;
00181 
00182       // set its varibles
00183       // Note: at this level, eta and phi have already been computed
00184       //       through CSphmomentum::build_thetaphi.
00185       elm->centre = *v;
00186       elm->is_stable = true;
00187 
00188       // update hash
00189       elm->next = hash_array[index];
00190       hash_array[index] = elm;
00191       
00192       n_cones++;
00193       return 0;
00194     }
00195 
00196     // if the cone is already there, we have nothing to do
00197     if (v->ref == elm->centre.ref){
00198       return 0;
00199     }
00200 
00201     elm = elm->next;
00202   } while (1);
00203 
00204   return 1;
00205 }
00206 
00207 }
The SISCone project has been developed by Gavin Salam and Gregory Soyez
Documentation generated on Mon Jun 4 2012 18:23:38 for SISCone by  Doxygen 1.7.6.1