9 static int gMyId=0,gMyInst=0;
11 #include "StMultiKeyMap.h"
13 #define MAX(a,b) ((a) > (b) ? (a) : (b))
14 #define MIN(a,b) ((a) < (b) ? (a) : (b))
16 static void random_shuffle(std::vector<StMultiKeyNode*> &arr);
18 StMultiKeyMap::StMultiKeyMap(
int nkeys)
24 StMultiKeyMap::~StMultiKeyMap()
29 void StMultiKeyMap::Clear(
const char *)
35 void StMultiKeyMap::Add(
const void *obj,
const double *keys)
38 for (
int i=0;i<mNKey;i++) {buf[i]=(float)keys[i];}
42 void StMultiKeyMap::Add(
const void *obj,
const float *keys)
51 double StMultiKeyMap::StMultiKeyMap::Quality()
54 return mTop->Quality();
57 int StMultiKeyMap::MakeTree()
59 int nNodes = mArr.size();
60 if (!nNodes)
return 0;
64 if (!mTop ) {mTop = mArr[0];jl=1;mTop->SetIKey(0);}
65 unsigned int myRnd = 1946;
66 for (
int i=jl;i<nNodes;i++) {
67 myRnd+=1000000007; mArr[i]->SetIKey(myRnd%mNKey);
70 std::vector<StMultiKeyNode*> tmp(0);
76 int StMultiKeyMap::ls(
const char *file)
const
78 return mTop->ls(file);
81 int StMultiKeyMap::Size()
const
83 if (mTop)
return mTop->Size();
84 else return mArr.size();
88 StMultiKeyNode::StMultiKeyNode(
int nKeys)
98 if (fr.mObj) Set(fr.mObj,fr.mKeys);
101 void StMultiKeyNode::Init()
103 memset(&mNKey,0,(
char*)&mKeys-&mNKey+
sizeof(mKeys));
104 mId = ++gMyId; gMyInst++; mIKey = -1;
107 void StMultiKeyNode::Clear()
109 memset(&mIKey,0,(
char*)&mObj - &mIKey); mIKey = -1;
112 StMultiKeyNode::~StMultiKeyNode()
120 int StMultiKeyNode::GetNInst()
123 void StMultiKeyNode::Set(
const void *obj,
const float *keys)
126 mObj = obj; mIKey=-1;
127 if (!mKeys) mKeys =
new float[mNKey];
128 memcpy(mKeys,keys,
sizeof(mKeys[0])*mNKey);
131 void StMultiKeyNode::Set(
const void *obj,
const double *keys)
134 for (
int i=0;i<mNKey;i++) {buf[i]=(float)keys[i];}
138 void StMultiKeyNode::Add(
const void *obj,
const float *keys)
147 static int nCall=0; nCall++;
148 assert(
this != node);
149 int way = (node->mKeys[int(mIKey)] > GetKey());
150 if (mLink[way]) { mLink[way]->Add(node);}
151 else { mLink[way] = node ;}
156 double StMultiKeyNode::Quality()
159 int nTot = GetNumb(0)+GetNumb(1)+1;
165 int nL = node->GetNumb(0);
166 int nR = node->GetNumb(1);
167 if (!nL || !nR)
continue;
168 qa += (2.*nL*nR)/nTot;
170 printf(
"Quality() nodes %d\n",n);
174 int StMultiKeyNode::ls(
const char *file)
const
178 if (file && file[0]) out=fopen(file,
"w");
186 int nL = node->GetNumb(0);
187 int nR = node->GetNumb(1);
188 int lev = iter.Level();
189 if (node==
this) {fprintf(out,
"%4d * ",n);}
190 else {fprintf(out,
"%4d - ",n);}
191 fprintf(out,
"Lev(%d) \t(%10p) \tL(%10p(%d)) \tR(%10p(%d)) \tDiv(%g)"
193 ,(
void*)node->mLink[0],nL
194 ,(
void*)node->mLink[1],nR
197 for (
int j=0;j<mNKey;j++) {fprintf(out,
" %g",node->mKeys[j]);}}
200 if (*file) fclose(out);
207 StMultiKeyMapIter::StMultiKeyMapIter(
const StMultiKeyNode *node,
const float *kMin,
const float *kMax)
214 void StMultiKeyMapIter::Set(
const StMultiKeyNode *node,
const float *kMin,
const float *kMax)
216 memset(mTouched,0,
sizeof(mTouched));
219 mNK = node->GetNKey();
222 mMinMax.resize(2*mNK);
225 int sk = mNK*
sizeof(mKMin[0]);
226 memcpy(mKMin,kMin,sk);
227 memcpy(mKMax,kMax,sk);
231 if(!Left(mTop))
return;;
232 if (FullCheck()) ++(*this);
235 void StMultiKeyMapIter::Reset()
237 memset(mTouched,0,
sizeof(mTouched));
241 if (FullCheck()) ++(*this);
244 void StMultiKeyMapIter::Update(
const float *kMin,
const float *kMax)
246 int sk = mNK*
sizeof(mKMin[0]);
247 if (kMin) memcpy(mKMin,kMin,sk);
248 if (kMax) memcpy(mKMax,kMax,sk);
251 StMultiKeyMapIter::~StMultiKeyMapIter()
261 if (rLink) node = Left(rLink);
262 if (!FullCheck())
break;
270 if ((
int)mStk.size() <=mLev) mStk.resize(mLev*2);
273 if (!lLink)
return node;
279 int StMultiKeyMapIter::FullCheck()
284 if (!node || !mKMin)
return 0;
285 const float *fk = node->mKeys;
287 for (
int k=0;k<mNK;k++) {
288 if (mKMin[k]>fk[k] || fk[k] >= mKMax[k])
return 1;
296 int ik = node->GetIKey();
297 float fk = node->GetKey();
299 return ( !mKMin || mKMin[ik]<=fk)? node->LLink():0;
305 int ik = node->GetIKey();
306 float fk = node->GetKey();
308 return (!mKMax || mKMax[ik]>fk)? node->RLink():0;
311 void random_shuffle(std::vector<StMultiKeyNode*> &arr)
313 static const unsigned int us=1000000007;
314 int n = arr.size();
if (n<=3)
return;
326 #include "TStopwatch.h"
327 void StMultiKeyMap::Test()
329 printf(
"StMultiKeyMap::Test() started\n");
333 for (
int i=0;i<nEVTS;i++) {
334 rnd = 2 - (i+1.)/nEVTS;
335 map.Add((
void*)(-1),&rnd);
339 double qa = map.Quality();
340 printf(
" Quality of tree = %g\n\n",qa);
346 printf(
"\n%d evts No bounds\n",nEVTS);
349 n++; rnd = node->GetKeys()[0];
355 printf(
"\nNo bounds OK, touched %d %d %d\n"
356 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);
359 float kMin=0.5,kMax=0.6;
360 iter.Set(map.GetTop(),&kMin,&kMax);
362 int nEst = int((nEVTS)*(kMax-kMin)+0.5);
363 printf(
"\n%d ~evts bounds=%g %g\n",nEst,kMin,kMax);
366 n++; rnd = node->GetKeys()[0];
369 assert((kMin<=rnd) && (rnd < kMax));
372 printf(
"\nGot %d. Bounds OK, Touched %d %d %d\n",n
373 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);
377 void StMultiKeyMap::Test2()
381 printf(
"StMultiKeyMap::Test2() started\n");
386 for (
int iEv=0;iEv<nEvts ;iEv++) {
387 for (
int ik=0;ik<kNKeys;ik++) { key[ik]= gRandom->Rndm();}
388 map.Add((
void*)1,key);
391 assert(nEvts==map.Size());
394 float dow[6]={0 ,0.1,0.2,0.1,0.2,0.3};
395 float upp[6]={0.2,0.3,0.4,0.2,0.3,0.4};
396 double ev = nEvts;
for (
int i=0;i<kNKeys;i++){ev*=(upp[i]-dow[i]);};
397 printf(
"\n%d ~evts \n",
int(ev+0.5));
418 const float *key = node->GetKeys();
420 for (
int k=0;k<nk;k++) {
421 if (dow[k]<=key[k] && key[k] < upp[k])
continue;
427 printf(
"\nSelected %d bad %d and must be %d\n",nSel,nBad,nMust);
428 printf(
"\nEvents %d == %d\n",nEvts,nTot);
429 if (nSel != nMust || nEvts!=nTot) {
430 printf(
"*** BAD BAD BAD BAD BAD BAD BAD BAD BAD BAD ***\n");
432 printf(
"Touched %d %d %d\n"
433 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);