C++ main module for emicrom Package  1.0
CORE_MorseArray.hpp
Go to the documentation of this file.
1 #ifndef CORE_MorseArray_HPP
2 #define CORE_MorseArray_HPP
3 
4 template<class T>
6  tString ret="";
7  ret+="Max values number per element:"+CORE_Integer::toString(mLD)+"\n";
8  ret+="Increment for indices:"+CORE_Integer::toString(mIncI)+"\n";
9  ret+="Number of elements:"+CORE_Integer::toString(mSize)+"\n";
10  ret+="Values:"+mValues.toString()+"\n";
11  ret+="Indices:"+mIndices->toString()+"\n";
12  return ret;
13 }
14 
15 template<class T>
17 
18 
19  ofstream f(fileName.c_str(),ios::out);
20 
21  if (f) {
22  f << "# save a morse array \n";
23  f << "# M is the number of element \n";
24  f << "# P: is the max number of values at each element \n";
25  f<< mSize<<"\t"<<mLD<<"\n";
26  f << "# U is 1: if the tensor is uniform over the domain, 0: otherwise \n";
27  f <<((tUSInt)!mIncI)<<"\n";
28  f << "# M[i][0] M[i][1] .... M[i][d] with d< P and i in [0,getSize()[ and line may be empty for no data on element i \n";
29 
30 
31  //index of first element value in increasing order
32  const tUIndex *k0=&(*mIndices.get())[0];
33 
34  //number of values of the element i
35  tUIndex d,n;
36  //values of the morse array
37  const T* Mi=&mValues[0];
38 
39  if (mIncI==1) {
40  for (tUIndex i=0;i<mSize;i++) {
41  //size of the element
42  n=(*(k0+1))-(*k0);
43  if (n>0) {
44  for (d=0;d<n;d++) {
45  f<< (*Mi)<<"\t";
46  Mi++;
47  }
48  }
49  //next element
50  k0++;
51  f<<"\n";
52  }
53  } else {
54  //uniform
55  n=(*(k0+1))-(*k0);
56  if (n>0) {
57  for (d=0;d<n;d++) {
58  f<< (*Mi)<<"\t";
59  Mi++;
60  }
61  }
62  f<<"\n";
63  }
64 
65  //free the file pointer
66  f.close();
67  } else {
68  return false;
69  }
70  return true;
71 }
72 
73 template<class T>
75 
76 
77  ifstream f(fileName.c_str(),ios::in);
78 
79  if (f) {
80 
81  // number of line
82  tUInteger numLine=0;
83  //tUInteger maxLines=CORE_Object::getMaxUInt();
84 
85  //for reading a line
86  tUSInt len=1024;
87  char line[len];
88 
89  //for analysing a line
90  SP::CORE_String tokenizer=CORE_String::New();
91 
92  //number of tokens per line
93  tUInteger i,nTokens;
94 
95  //index of comment char
96  tUIndex iComment;
97 
98  //to stop the reading if all data are read
99  tUIndex nDataRead=0;
100  tUSInt nLinesBeforeData=0;
101  tUSInt nMaxLinesBeforeData=10;
102 
103  tBoolean isUniformRead=false;
104 
105  //reset the attributes
106  mSize=0;
107  mLD=0;
108  mIncI=1;
109  mPacksNumber=0;
110  mIsConstant=false;
111  mValues.setSize(0);
112  mIsIndicesReferenced=false;
113  mIndices=CORE_UIndexArray::New();
114 
115  tReal *Mi=null;
116  tUIndex *indices=null;
117  tUIndex n=0;
118 
119  while ( (!f.eof()) && ((mSize==0) || (nDataRead<mSize)) ) {
120 
121  //read the line
122  f.getline(line,len);
123  numLine++;
124 
125  //analyse the line
126  tokenizer->setString(line);
127 
128  //ignore comment part
129  iComment=tokenizer->getString().find("#");
130  if (iComment!=tString::npos) {
131 
132  //comment line
133  if (iComment==0) continue;
134 
135  //ignore all chars after #
136  tokenizer->setString(tokenizer->getString().substr(0,iComment));
137  }
138 
139  //erase blanks before and after line
140  tokenizer->trim();
141 
142  //anaylyse all the tokens of the line
143  tokenizer->tokenize();
144 
145  //get the number of token
146  nTokens=tokenizer->getTokensNumber();
147 
148  //read the data
149  if (mSize==0) {
150  if (nTokens>=2) {
151  mSize=CORE_Integer::parseInt(tokenizer->nextToken());
152  mLD=CORE_Integer::parseInt(tokenizer->nextToken());
153  if ((mSize==0) || (mLD==0)) {
154  //no data
155  return false;
156  }
157  mValues.setSize(mSize*mLD);
158  mIndices->setSize(mSize+1);
159  Mi=&mValues[0];
160  indices=&(*mIndices.get())[0];
161  *indices=0;
162  indices++;
163  } else {
164  nLinesBeforeData++;
165  if (nLinesBeforeData>nMaxLinesBeforeData) {
166  //no data
167  cout << "warning : no data in file "<<fileName<<"\n";
168  return false;
169  }
170  }
171  continue;
172  }
173 
174  //read uniform data if not read
175  if (!isUniformRead) {
176  if (nTokens>=1) {
177  mIncI=!((tBoolean)CORE_Integer::parseInt(tokenizer->nextToken()));
178  isUniformRead=true;
179  if (mIncI==0) mIsConstant=true;
180  } else {
181  nLinesBeforeData++;
182  if (nLinesBeforeData>nMaxLinesBeforeData) {
183  //no data
184  cout << "warning : no data in file "<<fileName<<"\n";
185  return false;
186  }
187  }
188  continue;
189  }
190 
191  //read the values
192  if (nTokens==0) {
193  //empty lines no data
194  *indices=n;
195  indices+=mIncI;
196 
197  } else {
198  //read the data
199  n+=nTokens;
200  *indices=n;
201  indices+=mIncI;
202  for (i=0;i<nTokens;i++) {
203  (*Mi)=CORE_Real::parseReal(tokenizer->nextToken());
204  Mi++;
205  }
206 
207 
208  }
209 
210  //uniform case
211  if (mIncI==0) {
212  nDataRead=mSize;
213  mIndices->setSize(2);
214  } else {
215  nDataRead++;
216  }
217 
218  } //reading next line
219 
220  //free the file pointer
221  f.close();
222 
223 
224  } else {
225  throw CORE_Exception("common/core",
226  "CORE_MorseArray::loadFromFile("+fileName+")",
227  "impossible to open file");
228  return false;
229  }
230  //fit the size of values
231  fitToSize();
232 
233  return true;
234 }
235 
236 template<class T>
237 void CORE_MorseArray<T>::removeValue(const T& value) {
238  tUIndex *I=&(*mIndices.get())[0];
239  T * Vs=&mValues[0];
240 
241  const T* W=&mValues[0];
242  //index for W in [0,old size of values [
243  tUIndex j=0;
244  //index for Vs in [0,new size of values [
245  tUIndex index=0;
246 
247  //element index in [0,mSize[
248  tUIndex i;
249 
250  I++;
251  for (i=0;i<mSize;i++) {
252  while (j<(*I)) {
253  //copy all the elemenys which are different
254  if ((*W)!=value) {
255  //register the element
256  (*Vs)=(*W);
257  Vs++;
258  index++;
259  }
260 
261  //next value of element
262  W++;
263  j++;
264  }
265 
266  //next index of element
267  (*I)=index;
268  I++;
269 
270  }
271 
272 
273 }
274 
275 template<class T>
277 
278  tBoolean isUni=true;
279  isConstant=true;
280 
281  //no element or 1 element
282  if (mSize<=1) {
283  return isUni;
284  }
285 
286  //if the mose array is already uniform
287  if (isUniform()) {
288  return isUni;
289  }
290 
291  //zero value
292  tReal eps=1.e-12;
293 
294 
295 
296 
297  //curent index element
298  tUIndex i=0;
299  const tUIndex *I=&(*mIndices.get())[i];
300  const T *Vi,*V=&mValues[*I];
301 
302  //get the first refreence element
303  const T *Ri,*R=&mValues[0];
304  //the uniform size
305  tUIndex k,sR=((*(I+1))-(*I));
306  tUIndex s=sR;
307  //next element
308  i++;
309 
310  while (i<mSize) {
311 
312  //read the index & values of the element i
313  I+=mIncI;
314  V+=s*mIncI;
315 
316  //size of the next element
317  s=((*(I+1))-(*I));
318 
319  //verify the size & values of the values of the elemnt is the same as the first element
320  if (s!=sR) {
321  isUni=false;
322  if (s!=0) {
323  isConstant=false;
324  }
325  }
326  Ri=R;
327  Vi=V;
328  for (k=0;k<sR;k++) {
329  if (fabs((*Vi)-(*Ri))>eps) {
330  //different not null value: not constant & not uniform
331  isConstant=false;
332  return false;
333  }
334  Vi++;
335  Ri++;
336  }
337 
338  //next element
339  i++;
340 
341  }
342 
343  if (isUni) {
344  //the morse array is uniform
345  mLD=sR;
346  mIncI=0;
347  //resize the array
348  mIndices->setSize(2);
349  mValues.setSize(mLD);
350  //erase the unused memory
351  mValues.fitToSize();
352  mIndices->fitToSize();
353  }
354  return isUni;
355 }
356 
357 template<class T>
359  CORE_UIndexArray& indices,
360  const tUIndex& ld,
361  CORE_Array<T>& array) {
362  if (nSubsets==1) {
363  array.setSize(indices[indices.getSize()-1]);
364  array.fitToSize();
365  return;
366  }
367 
368  //merge the subset arrays
369  tUInteger subsetId=0;
370 
371  //the size of indices is N+nSubsets : N is the number of elements.
372  tUIndex N=indices.getSize()-nSubsets;
373 
374  tUIndex i,start,end;
375 
376 
377  //copy the endices of the first pack from [start,end[
378  // Ig is the indices of the global indices
379  tUIndex *Ig=&indices[0];
380  tUIndex index=0;
381 
382  // Ip is the indices of the pack indices
383  const tUIndex *Ip=null;
384  // Ag is the global vector values
385  T *Ag=&array[0];
386  // Ap is the pack vector values
387  const T *Ap=null;
388  //Number of elemnts to copy
389  tIndex nA,k;
390 
391 
392  for (subsetId=0;subsetId<nSubsets;subsetId++) {
393 
394  //start index of the packed array subsetId
395  start=subsetId*N/nSubsets;
396 
397  //end index of the packed array subsetId
398  end=(subsetId+1)*N/nSubsets;
399 
400  if (start<end) { //not empty pack
401 
402  //index of the first element of array subsetId in [0,N/nSubsets]
403  Ip=&indices[start+subsetId];
404 
405  //set the pointer of array to start element of the packed array subsetId
406  Ap=&array[start*ld];
407 
408  for (i=start;i<end;i++) {
409 
410  //copy the index of the begining
411  (*Ig)=index;
412 
413  //index of next global element
414  Ig++;
415 
416  //merge indices Ic into Ii
417  //number of element of the row i
418  nA=(*(Ip+1)-(*Ip));
419 
420  //index of next element of subset
421  Ip++;
422 
423  //merge array Ac into Ai
424  for (k=0;k<nA;k++) {
425  (*Ag)=(*Ap);
426  Ag++;
427  Ap++;
428  }
429 
430 
431  //update the new index of the element
432  index+=nA;
433 
434 
435 
436  } //end loop on i
437  }//end not empty pack
438 
439 
440 
441 
442  } //end loop on subset
443 
444 
445 
446 
447 
448  //fit the arrays to util size
449  indices.setSize(N+1);
450  indices[N]=index;
451  indices.fitToSize();
452 
453  array.setSize(index);
454  array.fitToSize();
455 }
456 
457 
458 template<class T>
460  CORE_UIndexArray& indices,
461  const tUIndex& ld,
462  const vector<CORE_Array<T>* >& arrays) {
463  typename vector<CORE_Array<T>* >::const_iterator iArray;
464 
465 
466  if (nSubsets==1) {
467  //index is the index of the last exluded element
468  // which is the size of the usefull array
469  tUIndex index=indices[indices.getSize()-1];
470  iArray=arrays.begin();
471  while(iArray!=arrays.end()) {
472  CORE_Array<T> &array=*(*iArray);
473  array.setSize(index);
474  array.fitToSize();
475  iArray++;
476  }
477  return;
478  }
479  //merge the subset arrays
480  tUInteger subsetId=0;
481 
482  //the size of indices is N+nSubsets
483  tUIndex N=indices.getSize()-nSubsets;
484 
485  tUIndex i,start,end;
486 
487 
488  //copy the endices of the first pack from [start,end[
489  // Ig is the indices of the global indices
490  tUIndex *Ig=&indices[0];
491  tUIndex index=0;
492 
493  // Ip is the indices of the pack indices
494  const tUIndex *Ip=null;
495 
496 
497  //Number of elemnts to copy
498  tIndex nA,k;
499 
500 
501  tUIndex s,nArrays=arrays.size();
502  T* Ags[nArrays];
503  const T* Aps[nArrays];
504 
505 
506 
507  iArray=arrays.begin();
508  if (iArray==arrays.end()) {//no arrays
509  return;
510  }
511 
512  //build the curent general array pointers Ais
513  s=0;
514  while(iArray!=arrays.end()) {
515  CORE_Array<T> *array=(*iArray);
516  if (array==null) {
517  //a null pointer erreor
518  return;
519  }
520  if (array->getSize()<=index) {
521  //all array are full filled
522  return;
523  }
524  Ags[s]=&(*array)[0];
525 
526  //next array
527  iArray++;
528  s++;
529  }
530 
531  //merge the arrays
532  for (subsetId=0;subsetId<nSubsets;subsetId++) {
533 
534  //start index of the packed array subsetId
535  start=subsetId*N/nSubsets;
536 
537  //end exlcued index of the packed array subsetId
538  end=(subsetId+1)*N/nSubsets;
539 
540 
541  if (start<end) { //not empty pack
542 
543  //index of the first element of array subsetId in [0,N/nSubsets]
544  Ip=&indices[start+subsetId];
545 
546  //set the pointer of arrays of subset to start element
547  iArray=arrays.begin();
548  s=0;
549  while(iArray!=arrays.end()) {
550  Aps[s]=&(*(*iArray))[start*ld];
551  s++;
552  iArray++;
553  }
554 
555  for (i=start;i<end;i++) {
556 
557  //copy the index of the begining
558  (*Ig)=index;
559  Ig++;
560 
561  //merge indices Ip into Ig
562  nA=(*(Ip+1)-(*Ip));
563  Ip++;
564 
565 
566 
567  //merge array Ac into Ai
568  for (s=0;s<nArrays;s++) {
569  T* &Ag=Ags[s];
570  const T* &Ap=Aps[s];
571 
572  for (k=0;k<nA;k++) {
573  (*Ag)=(*Ap);
574  Ag++;
575  Ap++;
576  }
577  }
578 
579  index+=nA;
580  } //end loop on i
581 
582  }//end not empty pack
583 
584 
585  } //end subset loop
586 
587  //fit the arrays to util size
588  indices.setSize(N+1);
589  indices[N]=index;
590  indices.fitToSize();
591 
592  iArray=arrays.begin();
593  while(iArray!=arrays.end()) {
594  CORE_Array<T> &array=*(*iArray);
595  array.setSize(index);
596  array.fitToSize();
597  iArray++;
598  }
599 
600 
601 
602 }
603 #endif
const tUIndex & getSize() const
return the size of the array for reading
Definition: CORE_Array.h:1018
static tLLInt parseInt(const tString &str)
return the integer associated to the string
Definition: CORE_Integer.cpp:102
static boost::shared_ptr< CORE_Array< tUIndex > > New()
return a CORE_Array shared pointer
Definition: CORE_Array.h:120
#define tUInteger
Definition: types.h:91
tBoolean loadFromFile(const tString &fn)
load the morse array from file
Definition: CORE_MorseArray.hpp:74
static tLDouble parseReal(const tString &str)
return the real associated to the string
Definition: CORE_Real.h:201
#define tUSInt
Definition: types.h:28
#define tBoolean
Definition: types.h:139
void setSize(const tUIndex &n)
set the size
Definition: CORE_Array.h:292
tBoolean uniformize()
uniformize the array
Definition: CORE_MorseArray.h:558
tString toString() const
return the string associated to the integer
Definition: CORE_Integer.h:106
#define null
Definition: types.h:144
tBoolean saveToFile(const tString &fn) const
save the morse array into file
Definition: CORE_MorseArray.hpp:16
static void MergeMorseArrays(const tUInteger &nSubsets, CORE_UIndexArray &indices, const tUIndex &ld, const vector< CORE_Array< T > * > &arrays)
merge morse arrays
Definition: CORE_MorseArray.hpp:459
#define tIndex
Definition: types.h:129
this class describes the exceptions raised for CORE package
Definition: CORE_Exception.h:15
void removeValue(const T &v)
remove the value
Definition: CORE_MorseArray.hpp:237
virtual tString toString() const
return the string reprensetaion of the morse array
Definition: CORE_MorseArray.hpp:5
virtual void fitToSize()
fit the array alocation exactly to size fit the allocation of the array to its size ...
Definition: CORE_Array.hpp:128
#define tUIndex
Definition: types.h:126
#define tString
Definition: types.h:135
static SP::CORE_String New()
create a class String
Definition: CORE_String.h:96
#define tReal
Definition: types.h:118
static void MergeMorseArray(const tUInteger &P, CORE_UIndexArray &indices, const tUIndex &ld, CORE_Array< T > &array)
merge morse arrays
Definition: CORE_MorseArray.hpp:358