8 #include "StMultyKeyMap.h"
10 #define MAX(a,b) ((a) > (b) ? (a) : (b))
11 #define MIN(a,b) ((a) < (b) ? (a) : (b))
14 StMultyKeyMap::StMultyKeyMap(
int nkeys,
int nbins)
19 mLink.resize(mNBin, 0);
20 mDow.resize (mNKey, 1e11);
21 mStp.resize (mNKey,-1e11);
25 StMultyKeyMap::~StMultyKeyMap()
30 void StMultyKeyMap::Clear(
const char *)
35 StMultyKeyDivd::Clear();
39 void StMultyKeyMap::Add(
const void *obj,
const double *keys)
42 for (
int i=0;i<mNKey;i++) {buf[i]=(float)keys[i];}
46 void StMultyKeyMap::Add(
const void *obj,
const float *keys)
50 for (
int ik=0;ik<mNKey;ik++) {
51 if (mDow[ik]>keys[ik]) mDow[ik]=keys[ik];
52 if (mStp[ik]<keys[ik]) mStp[ik]=keys[ik];
59 int StMultyKeyMap::GetJKey()
61 mJKey+=1000000007;
return mJKey%mNKey;
67 if (!mPairs.empty()) {
68 pair = mPairs.front(); mPairs.pop_front();}
71 pair->mKeys.resize(mNKey,0);
80 if (!mNodes.empty()) {
81 node = mNodes.front();mNodes.pop_front();}
86 node->mLink.resize(mNBin,0);
91 int StMultyKeyMap::MakeTree(
int keepArray)
93 int nNodes = mArr.size();
94 if (!nNodes)
return 0;
95 for (
int ik=0;ik<mNKey;ik++) {mStp[ik] = 1.001*(mStp[ik]-mDow[ik])/mNBin;}
99 for (
int i=0;i<nNodes;i++) {Add(mArr[i]);}
101 if (keepArray)
return nNodes;
102 std::vector<StMultyKeyNode*> tmp(0);
107 StMultyKeyDivd::StMultyKeyDivd()
112 StMultyKeyDivd::~StMultyKeyDivd()
120 int StMultyKeyNode::GetNumb()
const
123 if (GetKeys())
return 1;
125 for (
int ik=0;ik<nk;ik++) {
if (Link(ik)) nb += Link(ik)->GetNumb();}
130 void StMultyKeyDivd::Clear(
const char *)
133 for (
int ik=0;ik<nk;ik++) {
if (mLink[ik]) mLink[ik]->Clear();mLink[ik]=0;}
135 if (
this == mMap)
return;
136 mMap->mNodes.push_front(
this);
139 StMultyKeyPair::StMultyKeyPair()
141 mId = ++gMyId; mObj = 0;
144 void StMultyKeyPair::Clear(
const char *)
146 mKeys.clear(); mObj = 0;
147 mMap->mPairs.push_front(
this);
150 void StMultyKeyPair::Set(
const void *obj,
const float *keys)
154 int nk = mMap->GetNKey();
155 for (
int i=0;i<nk;i++) {mKeys.push_back(keys[i]);}
160 static int nCall=0; nCall++;
161 const float *keyA = pair->GetKeys();
162 int nBin = mMap->GetNBin();
163 int ibin = (keyA[mIKey]-mDow[mIKey])/mStp[mIKey];
164 assert(ibin>=0 && ibin<nBin);
166 const float *keyB = 0;
167 if (!node) { mLink[ibin] = pair;
return;}
168 else if (!(keyB=node->GetKeys())) { node->Add(pair);
return;}
173 bode->mDow = mDow; bode->mStp = mStp;
174 bode->mDow[mIKey] += mStp[mIKey]*ibin;
175 bode->mStp[mIKey] /= nBin;
176 bode->mIKey=mMap->GetJKey();;
182 double StMultyKeyNode::Quality(
int *numb)
const
184 static int nCall=0; nCall++;
185 if (GetKeys()) { *numb = 1;
return 0;}
190 for (
int ib=0;ib<nb;ib++) {
191 if (!Link(ib))
continue;
192 qi = Link(ib)->Quality(&ni);
193 nt +=ni; ni2 += ni*ni; qa +=qi*ni;
195 qa = (qa + nt*nt-ni2)/nt;
196 if (numb) {*numb = nt;}
else { qa/=nt;}
200 int StMultyKeyNode::MaxDeep(
int *deep)
const
202 if (GetKeys()) { *deep = 1;
return 0;}
203 int nk = GetNKey();
int maxi=0;
204 for (
int ik=0;ik<nk;ik++) {
205 int ni = (deep)? *deep+1:1;
208 if (Link(ik)) mxi = Link(ik)->MaxDeep(&ni);
209 if (maxi<mxi) maxi=mxi;
215 int StMultyKeyNode::ls(
const char *file)
const
220 if (file && file[0]) out=fopen(file,
"w");
228 int lev = iter.Level();
229 const float *keys = node->GetKeys();
230 fprintf(out,
"%4d - ",n);
231 fprintf(out,
"Lev(%d) \t(%10p keys=)",lev,(
void*)node);
232 int nk = node->GetNKey();
233 for (
int k=0;k<nk;k++) {fprintf(out,
"%g ",keys[k]);}
242 StMultyKeyMapIter::StMultyKeyMapIter(
const StMultyKeyNode *node,
const float *kMin,
const float *kMax)
249 void StMultyKeyMapIter::Reset()
251 memset(mTouched,0,
sizeof(mTouched));
255 if (ini<0 && FullCheck()==0)
return;
259 void StMultyKeyMapIter::Set(
const StMultyKeyNode *node,
const float *kMin,
const float *kMax)
261 memset(mTouched,0,
sizeof(mTouched));
264 mNK = node->GetNKey();
265 mNB = node->GetNBin();
268 mMinMax.resize(2*mNK);
271 int sk = mNK*
sizeof(mKMin[0]);
272 memcpy(mKMin,kMin,sk);
273 memcpy(mKMax,kMax,sk);
275 mLev = 0; mStk[0].node=0;
276 mLev = 1; mStk[1].node=node;
279 if (ini<0 && !FullCheck())
return;
283 int StMultyKeyMapIter::InitLev()
288 if (node->GetKeys())
return -1;
289 int iKey = node->GetIKey();
290 mStk[mLev].rite = mNB-1;
293 float dow = node->GetDow()[iKey];
294 float stp = node->GetStp()[iKey];
295 int left = (mKMin[iKey]-dow)/stp;
if (left< 0) {left= 0;};
if(left>=mNB)
return 1;
296 int rite = (mKMax[iKey]-dow)/stp;
if (rite>=mNB) {rite=mNB-1;};
if(rite< 0)
return 2;
297 mStk[mLev].rite = rite;
298 mStk[mLev].ibin = left-1;
303 void StMultyKeyMapIter::Update(
const float *kMin,
const float *kMax)
305 int sk = mNK*
sizeof(mKMin[0]);
306 if (kMin) memcpy(mKMin,kMin,sk);
307 if (kMax) memcpy(mKMax,kMax,sk);
310 StMultyKeyMapIter::~StMultyKeyMapIter()
318 myStk_t &stk =mStk[mLev];
322 while (++stk.ibin<=stk.rite) {
323 binNode = node->Link(stk.ibin);
if (binNode)
break;
325 if (!binNode) { mLev--;
continue;}
326 mStk[++mLev].node = binNode;
328 if (ini==0) {
continue;}
329 if (ini>0) { mLev--;
continue;}
330 if (FullCheck()) { mLev--;
continue;}
336 int StMultyKeyMapIter::FullCheck()
341 if (!mKMin)
return 0;
342 const float *fk = node->GetKeys();
344 for (
int k=0;k<mNK;k++) {
345 if (mKMin[k]>fk[k] || fk[k] >= mKMax[k])
return 1;
353 #include "TStopwatch.h"
356 void StMultyKeyMap::Test()
358 printf(
"StMultyKeyMap::Test() started\n");
362 for (
int i=0;i<nEVTS;i++) {
363 rnd = 1 - (i+1.)/nEVTS;
364 map.Add((
void*)(-1),&rnd);
368 double qa = map.Quality();
369 printf(
" Quality of tree = %g\n\n",qa);
375 printf(
"\n%d evts No bounds\n",nEVTS);
378 const float * keys = node->GetKeys();
387 printf(
"\nNo bounds OK, touched %d %d %d\n"
388 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);
391 float kMin=0.5,kMax=0.6;
392 iter.Set(map.GetTop(),&kMin,&kMax);
394 int nEst = int((nEVTS)*(kMax-kMin)+0.5);
395 printf(
"\n%d ~evts bounds=%g %g\n",nEst,kMin,kMax);
398 rnd = node->GetKeys()[0];
399 n++; rnd = node->GetKeys()[0];
402 assert((kMin<=rnd) && (rnd < kMax));
405 printf(
"\nGot %d. Bounds OK, Touched %d %d %d\n",n
406 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);
410 void StMultyKeyMap::Test2()
412 printf(
"StMultyKeyMap::Test2() started\n");
421 for (
int iEv=0;iEv<nEvts ;iEv++) {
422 for (
int ik=0;ik<4;ik++) { key[ik]= gRandom->Rndm();}
423 map.Add((
void*)1,key);
427 printf (
"MakeTree Cpu = %g\n",TW.CpuTime());
431 double qa = map.Quality();
432 int maxDeep = map.MaxDeep();
433 int etaDeep = log(nEvts)/log(2.)+0.5;
434 printf(
" Quality of tree = %g maxDeep=%d etaDeep %d",qa,maxDeep,etaDeep);
437 float dow[4]={0, 0.1,0.2,0.3};
438 float upp[4]={0.2,0.3,0.4,0.5};
439 double ev = nEvts;
for (
int i=0;i<4;i++){ev*=(upp[i]-dow[i]);};
440 printf(
"\n%d ~evts \n",
int(ev+0.5));
441 int nk = map.GetNKey();
447 for (
int jkl=0;jkl<nkl;jkl++) {
461 printf (
"Search Cpu = %g\n",TW.CpuTime()/nkl);
465 for (
int i=0;i<nb;i++)
468 const float *key = node->GetKeys();
470 for (
int k=0;k<nk;k++) {
471 if (dow[k]<=key[k] && key[k] < upp[k])
continue;
480 printf(
"\nSelected %d bad %d and must be %d\n",nSel,nBad,nMust);
481 printf(
"Touched %d %d %d\n"
482 ,iter.Touched()[0],iter.Touched()[1],iter.Touched()[2]);