|
SISCone
2.0.5
|
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 }