source: orange/source/orange/table.cpp @ 11703:9b8d8ab7820c

Revision 11703:9b8d8ab7820c, 21.1 KB checked in by janezd <janez.demsar@…>, 7 months ago (diff)

Removed the GPL copyright notice from all files except orangeqt.

Line 
1#include "random.hpp"
2#include "vars.hpp"
3#include "domain.hpp"
4#include "domaindepot.hpp"
5#include "filter.hpp"
6#include "distvars.hpp"
7#include "stladdon.hpp"
8
9#include "crc.h"
10
11#include "table.ppp"
12
13
14TExampleTable::TExampleTable(const TExampleTable& orig)
15: TExampleGenerator(orig.domain),
16  examples(NULL),
17  _Last(NULL),
18  _EndSpace(NULL),
19  ownsExamples(true)
20{
21  reserve(orig.size());
22  for(int i = 0; i < orig.size(); ++i){
23      push_back(new TExample(orig.at(i)));
24  }
25}
26
27TExampleTable::TExampleTable(PDomain dom, bool owns)
28: TExampleGenerator(dom),
29  examples(NULL),
30  _Last(NULL),
31  _EndSpace(NULL),
32  ownsExamples(owns)
33{ version = ++generatorVersion; }
34
35
36/* Careful: the meaning of 'owns' is the opposite of what we have
37   in Python: if owns==true, then the table doesn't hold only the
38   references to examples (in another table) but has its own examples! */
39TExampleTable::TExampleTable(PExampleGenerator gen, bool owns)
40: TExampleGenerator(gen->domain),
41  examples(NULL),
42  _Last(NULL),
43  _EndSpace(NULL),
44  ownsExamples(owns)
45{ 
46  if (!ownsExamples) {
47    lock = fixedExamples(gen);
48    addExamples(lock);
49  }
50  else
51    addExamples(gen);
52}
53
54
55TExampleTable::TExampleTable(PDomain dom, PExampleGenerator gen, bool filterMetas)
56: TExampleGenerator(dom),
57  examples(NULL),
58  _Last(NULL),
59  _EndSpace(NULL),
60  ownsExamples(true)
61{ 
62  addExamples(gen, filterMetas);
63}
64
65
66TExampleTable::TExampleTable(PExampleGenerator alock, int)
67: TExampleGenerator(alock ? alock->domain : PDomain()),
68  examples(NULL),
69  _Last(NULL),
70  _EndSpace(NULL),
71  ownsExamples(false),
72  lock(alock)
73{ 
74  version = ++generatorVersion;
75}
76
77
78TExampleTable::TExampleTable(PExampleGeneratorList tables)
79: TExampleGenerator(PDomain()),
80  examples(NULL),
81  _Last(NULL),
82  _EndSpace(NULL),
83  ownsExamples(true),
84  lock()
85{
86  if (!tables->size())
87    raiseError("merging constructor was given no datasets to merge");
88
89  TDomainList domains;
90  int size = tables->front()->numberOfExamples();
91  vector<TExampleIterator> iterators;
92  PITERATE(TExampleGeneratorList, sdi, tables) {
93    if ((*sdi)->numberOfExamples() != size)
94      raiseError("cannot merge dataset of unequal sizes");
95    domains.push_back((*sdi)->domain);
96    iterators.push_back((*sdi)->begin());
97  }
98
99  TDomainMultiMapping mapping;
100  domain = combineDomains(PDomainList(domains), mapping);
101
102  int exno = 0;
103  for(; iterators.front(); exno++) {
104    TExample *example = mlnew TExample(domain);
105    addExample(example);
106    TDomainMultiMapping::const_iterator dmmi(mapping.begin());
107    TExample::iterator ei(example->begin()), ee(example->end());
108    TVarList::const_iterator vi(domain->variables->begin());
109    for(; ei!=ee; ei++, dmmi++, vi++) {
110      bool notfirst = 0;
111      for(vector<pair<int, int> >::const_iterator sdmmi((*dmmi).begin()), sdmme((*dmmi).end()); sdmmi!=sdmme; sdmmi++) {
112        if (!mergeTwoValues(*ei, (*iterators[(*sdmmi).first])[(*sdmmi).second], notfirst++ != 0))
113          raiseError("mismatching value of attribute '%s' in example #%i", (*vi)->get_name().c_str(), exno);
114      }
115    }
116
117    // copy meta attributes and increase the iterators
118    for(vector<TExampleIterator>::iterator ii(iterators.begin()), ie(iterators.end()); ii!=ie; ++*(ii++)) {
119      ITERATE(TMetaValues, mvi, (**ii).meta) {
120        if (example->hasMeta((*mvi).first)) {
121          if (!mergeTwoValues(example->getMeta((*mvi).first), (*mvi).second, true)) {
122            PVariable metavar = domain->getMetaVar((*mvi).first, false);
123            if (metavar && metavar->get_name().length())
124              raiseError("Meta attribute '%s' has ambiguous values on example #%i", metavar->get_name().c_str(), exno);
125            else
126              raiseError("Meta attribute %i has ambiguous values on example #%i", (*mvi).first, exno);
127          }
128        }
129        else
130          example->setMeta((*mvi).first, (*mvi).second);
131      }
132    }
133  }
134
135  version = ++generatorVersion;
136}
137
138
139TExampleTable::~TExampleTable()
140{ 
141  if (examples) {
142    if (ownsExamples)
143      for(TExample **t = examples; t != _Last; )
144        delete *(t++);
145    free(examples);
146  }
147}
148
149
150int TExampleTable::traverse(visitproc visit, void *arg) const
151{ 
152  TRAVERSE(TExampleGenerator::traverse);
153  if (ownsExamples)
154    for(TExample **ee = examples; ee != _Last; ee++)
155      TRAVERSE((*ee)->traverse)
156
157  return 0;
158}
159
160
161int TExampleTable::dropReferences() 
162{ 
163  DROPREFERENCES(TExampleGenerator::dropReferences);
164  clear();
165  return 0;
166}
167
168
169void TExampleTable::reserve(const int &i)
170{ 
171  if (!examples) {
172    if (i) {
173      examples = (TExample **)malloc(i * sizeof(TExample *));
174      _Last = examples;
175      _EndSpace = examples + i;
176    }
177    else {
178      _Last = _EndSpace = examples;
179    }
180  }
181
182  else {
183    if (!i) {
184      if (examples) {
185        if (_Last == examples) {
186          free(examples);
187          _Last = _EndSpace = examples = NULL;
188        }
189        // else do nothing: reserve should not remove examples!
190      }
191      else {
192        _Last = _EndSpace = examples;
193      }
194    }
195    else {
196      if (i>_Last - examples) {
197        int lastofs = _Last - examples;
198        TExample **newexamples = (TExample **)realloc(examples, i * sizeof(TExample));
199        if (!newexamples)
200          raiseErrorWho("resize", "out of memory");
201        examples = newexamples;
202        _Last = examples + lastofs;
203        _EndSpace = examples + i;
204      }
205      // else do nothing: i is too small and reserve should not remove examples!
206    }
207  }
208}
209
210
211void TExampleTable::growTable()
212{
213  reserve(!examples ? 256 : int(1.25 * (_EndSpace - examples)));
214}
215
216
217void TExampleTable::shrinkTable()
218{
219  if (_Last == examples)
220    reserve(0);
221  else {
222    int sze = int(1.25 * (_Last-examples));
223    if (sze < 256)
224      sze = 256;
225    if (sze < _EndSpace - examples)
226      reserve(sze);
227  }
228}
229
230
231TExample &TExampleTable::at(const int &i)
232{
233  if (_Last == examples)
234    raiseError("no examples");
235  if ((i<0) || (i >= _Last-examples))
236    raiseError("index %i out of range 0-%i", i, _Last-examples-1);
237
238  return *examples[i];
239}
240
241
242const TExample &TExampleTable::at(const int &i) const
243{
244  if (_Last == examples)
245    raiseError("no examples");
246  if ((i<0) || (i >= _Last-examples))
247    raiseError("index %i out of range 0-%i", i, _Last-examples-1);
248
249  return *examples[i];
250}
251
252
253TExample &TExampleTable::back() 
254{
255  if (_Last == examples)
256    raiseError("no examples");
257
258  return *_Last[-1];
259}
260
261
262const TExample &TExampleTable::back() const
263{
264  if (_Last == examples)
265    raiseError("no examples");
266
267  return *_Last[-1];
268}
269
270
271void TExampleTable::clear()
272{
273  if (examples) {
274    if (ownsExamples)
275      while (_Last != examples)
276        delete *--_Last;
277    free(examples);
278  }
279  _Last = _EndSpace = examples = NULL;
280  examplesHaveChanged();
281}
282
283
284bool TExampleTable::empty() const
285{ 
286  return (_Last == examples);
287}
288
289
290TExample &TExampleTable::front() 
291{
292  if (_Last == examples)
293    raiseError("no examples");
294
295  return **examples;
296}
297
298
299const TExample &TExampleTable::front() const
300{
301  if (_Last == examples)
302    raiseError("no examples");
303
304  return **examples;
305}
306
307
308TExample &TExampleTable::operator[](const int &i)
309{
310  return *examples[i];
311}
312
313
314const TExample &TExampleTable::operator[](const int &i) const
315{
316  return *examples[i];
317}
318
319
320void TExampleTable::push_back(TExample *x)
321{
322  if (_Last == _EndSpace)
323    growTable();
324  *(_Last++) = x;
325
326  examplesHaveChanged();
327}
328
329
330TExample &TExampleTable::new_example()
331{
332  TExample *x = mlnew TExample(domain);
333  push_back(x);
334  return *x;
335}
336
337
338void TExampleTable::delete_last()
339{ if (_Last == examples)
340    raiseError("no examples");
341  erase(_Last-1);
342}
343
344
345int TExampleTable::size() const
346{
347  return examples ? _Last - examples : 0;
348}
349
350
351void TExampleTable::erase(const int &sti)
352{
353  if (_Last == examples)
354    raiseError("no examples");
355  if (sti >= _Last-examples)
356    raiseError("index %i out of range 0-%i", sti, _Last-examples-1);
357  erase(examples + sti);
358}
359
360
361void TExampleTable::erase(const int &sti, const int &eni)
362{
363  if (_Last == examples)
364    raiseError("no examples");
365  if (sti >= _Last-examples)
366    raiseError("index %i out of range 0-%i", sti, _Last-examples-1);
367  erase(examples + sti, examples + eni);
368}
369
370
371void TExampleTable::erase(TExample **ptr)
372{
373  if (ownsExamples)
374    delete *ptr;
375  memmove(ptr, ptr+1, sizeof(TExample **)*(_Last - ptr - 1));
376  _Last--;
377  examplesHaveChanged();
378}
379
380
381void TExampleTable::erase(TExample **fromPtr, TExample **toPtr)
382{
383  if (ownsExamples) {
384    TExample **ee = fromPtr;
385    while (ee != toPtr)
386      delete *(ee++);
387  }
388
389  memmove(fromPtr, toPtr, sizeof(TExample **)*(_Last - toPtr));
390
391  _Last -= (toPtr - fromPtr);
392
393  shrinkTable();
394  examplesHaveChanged();
395}
396
397
398void TExampleTable::insert(const int &sti, const TExample &ex)
399{
400  if (ex.domain != domain)
401    raiseError("examples has invalid domain (ExampleTable.insert doesn't convert)");
402  if (sti > _Last-examples)
403    raiseError("index %i out of range 0-%i", sti, _Last-examples);
404 
405  if (_Last == _EndSpace)
406    growTable();
407
408  TExample **sp = examples + sti;
409  memmove(sp+1, sp, sizeof(TExample **)*(_Last - sp));
410  *sp = ownsExamples ? CLONE(TExample, &ex) : const_cast<TExample *>(&ex);
411  _Last++;
412
413  examplesHaveChanged();
414}
415
416
417TExampleIterator TExampleTable::begin()
418{
419  return TExampleIterator(this, examples ? *examples : NULL, (void *)examples);
420}
421
422
423void TExampleTable::copyIterator(const TExampleIterator &src, TExampleIterator &dest)
424{ 
425  TExampleGenerator::copyIterator(src, dest);
426  dest.data = src.data;
427}
428
429
430void TExampleTable::increaseIterator(TExampleIterator &it)
431{
432  if (++((TExample **&)(it.data)) == _Last)
433    deleteIterator(it);
434  else
435    it.example = *(TExample **)(it.data);
436}
437
438
439bool TExampleTable::sameIterators(const TExampleIterator &i1, const TExampleIterator &i2)
440{
441  return (i1.data==i2.data);
442}
443
444
445bool TExampleTable::remove(TExampleIterator &it)
446{
447  erase( (TExample **)it.data );
448  examplesHaveChanged();
449  return true;
450}
451
452
453bool TExampleTable::randomExample(TExample &ex)
454{
455  if (!randomGenerator)
456    randomGenerator = mlnew TRandomGenerator();
457
458  if (!size())
459    return 0;
460  ex = operator[](randomGenerator->randint(size()));
461  return true;
462}
463
464
465/*  Searches for the example in the table and returns its class, if found. If there are more
466    different classes, it raises an exception, if example has no DK's, or returns DK otherwise.
467    If there's no corresponding example, it returns DK.
468    IN FUTURE: This method should return distributed values if more answers are possible.
469*/
470TValue TExampleTable::operator ()(const TExample &exam)
471{
472  if (empty())
473    return domain->classVar->DK();
474  TExample cexam(exam);
475  cexam.setClass(domain->classVar->DK());
476
477  bool hasValue = false;
478  TValue toret;
479  for(TExample **ri = examples; ri!=_Last; ri++)
480    if (cexam.compatible(**ri)) {
481      if (!hasValue) {
482        hasValue = true;
483        toret = (**ri).getClass(); 
484      }
485      else if (!toret.compatible((**ri).getClass())) {
486        // returns DK if the query contains specials, raises an exception otherwise
487        int Na = domain->attributes->size();
488        for(TExample::iterator vi(cexam.begin()); !((*vi).isSpecial()) && --Na; ++vi);
489        if (Na)
490          return domain->classVar->DK();
491        else
492          raiseError("ambiguous example (cannot determine the class value)");
493      }
494    }
495  return hasValue ? toret : domain->classVar->DK();
496}
497
498
499int TExampleTable::numberOfExamples()
500{
501  return size();
502}
503
504
505float TExampleTable::weightOfExamples(const int &weightID) const
506{
507  float weight = 0;
508  for(TExample **ri = examples; ri != _Last; ri++)
509    weight += WEIGHT(**ri);
510  return weight;
511}
512
513
514void TExampleTable::addExample(const TExample &example, bool filterMetas)
515{
516  if (ownsExamples)
517    if (example.domain == domain)
518      push_back(CLONE(TExample, &example));
519    else
520      push_back(mlnew TExample(domain, example, !filterMetas));
521  else
522    if (example.domain == domain)
523      push_back(const_cast<TExample *>(&example));
524    else
525      raiseError("domain mismatch (cannot convert a reference to example)");
526
527  examplesHaveChanged();
528}
529
530
531void TExampleTable::addExample(TExample *example)
532{
533  if (example->domain != domain)
534    raiseError("cannot add pointers to examples of different domains");
535  push_back(example);
536  examplesHaveChanged();
537}
538
539void TExampleTable::addExamples(PExampleGenerator gen, bool filterMetas)
540{
541  if (ownsExamples)
542    if (gen->domain == domain)
543      PEITERATE(ei, gen)
544        push_back(CLONE(TExample, &*ei)); 
545    else
546      PEITERATE(ei, gen)
547        push_back(mlnew TExample(domain, *ei, !filterMetas)); 
548
549  else {
550    if (gen->domain == domain)
551      PEITERATE(ei, gen)
552        push_back(&*ei); 
553    else
554      raiseError("domain mismatch (cannot convert a reference to example)");
555  }
556
557  examplesHaveChanged();
558}
559
560
561bool TExampleTable::removeExamples(TFilter &filter)
562{ 
563  TExample **ri = examples, **ci;
564  for( ; (ri!=_Last) && !filter(**ri); ri++);
565  if ((ci=ri)==_Last)
566    return 0;
567
568  while(++ri!=_Last)
569    if (!filter(**ri)) {
570      if (ownsExamples)
571        delete *ci;
572      **(ci++) = **ri;
573    }
574  erase(ci, _Last);
575
576  examplesHaveChanged();
577  return 1;
578}
579
580
581bool TExampleTable::removeExample(TExample &exam)
582{ // 'filter' dies before 'exam' and may contain a wrapped reference
583  TFilter_sameExample filter = TFilter_sameExample(PExample(exam));
584  return removeExamples(filter);
585}
586
587
588bool TExampleTable::removeCompatible(TExample &exam)
589{ // 'filter' dies before 'exam' and may contain a wrapped reference
590  TFilter_compatibleExample filter = TFilter_compatibleExample(PExample(exam));
591  return removeExamples(filter);
592}
593
594
595class TExI {
596public:
597  TExample *example;
598  int i;
599 
600  TExI(TExample *ex = NULL, const int ii=0)
601  : example(ex),
602    i(ii)
603  {}
604};
605
606
607bool lesstexi(const TExI &a, const TExI &b)
608{ return *a.example < *b.example; }
609
610
611void TExampleTable::removeDuplicates(const int &weightID)
612{ 
613  if (empty())
614    return;
615
616  vector<TExI> exi(_Last - examples);
617  int i = 0;
618  for(TExample **ep = examples; ep!=_Last; exi[i] = TExI(*(ep++), i), i++);
619  stable_sort(exi.begin(), exi.end(), lesstexi);
620
621  bool removed = false;
622  vector<TExI>::iterator fromPtr(exi.begin()), toPtr(fromPtr), ePtr(exi.end()); 
623  while(++fromPtr != ePtr) {
624    if (*(*fromPtr).example == *(*toPtr).example) {
625      if (weightID)
626        (*(*toPtr).example)[weightID].floatV += WEIGHT(*(*fromPtr).example);
627      if (ownsExamples)
628        delete examples[(*fromPtr).i];
629      examples[(*fromPtr).i] = NULL;
630      removed = true;
631    }
632    else
633      toPtr = fromPtr;
634  }
635
636  if (!removed)
637    return;
638
639  TExample **fromE = examples;
640  while (*fromE) // do not need to check !=_Last; there is a null pointer somewhere
641    fromE++;
642
643  TExample **toE = fromE++; // toE points to the next free spot
644  for(; fromE != _Last; fromE++)
645    if (*fromE)
646      *toE++ = *fromE;
647
648  _Last = toE;
649
650  shrinkTable();
651  examplesHaveChanged();
652}
653
654
655// Changes the domain and converts all the examples.
656void TExampleTable::changeDomain(PDomain dom, bool filterMetas)
657{
658  domain = dom;
659  if (ownsExamples)
660    for (TExample **ri = examples; ri!=_Last; ri++) {
661      TExample *tmp = mlnew TExample(dom, **ri, !filterMetas);
662      delete *ri;
663      *ri = tmp;
664    }
665
666  else {
667    for (TExample **ri = examples; ri!=_Last; ri++)
668      *ri = mlnew TExample(dom, **ri, !filterMetas);
669    ownsExamples = false;
670    lock = PExampleGenerator();
671  }
672
673  examplesHaveChanged();
674}
675
676
677void TExampleTable::pickClass(PVariable classVar)
678{
679    if (!ownsExamples) {
680        raiseError("Cannot change the class in a table of references");
681    }
682    const int attrs = domain->attributes->size();
683    const int classes = domain->classVars->size();
684    TDomain *newDomain;
685    int classPos;
686    int end_off = 0;
687    if (!classVar) {
688        if (!classes) {
689            return;
690        }
691        end_off = -1;
692        newDomain = mlnew TDomain(classVar, domain->attributes.getReference()); // No class
693        newDomain->classVars->push_back(domain->classVar);
694        PITERATE(TVarList, ci, domain->classVars) {
695            if (*ci != classVar) {
696                newDomain->classVars->push_back(*ci);
697            }
698        }
699        classPos = attrs;
700    }
701    else {
702        classPos = attrs;
703        if (domain->classVar) {
704            classPos += 1;
705        }
706        else {
707            end_off += 1;
708        }
709        TVarList::const_iterator mci(domain->classVars->begin()), mce(domain->classVars->end());
710        for(; (mci != mce) && (*mci != classVar); ++mci, ++classPos);
711        if (mci == mce) {
712            raiseError("Domain has no class %s", classVar->get_name().c_str());
713        }
714        newDomain = mlnew TDomain(classVar, domain->attributes.getReference());
715        newDomain->classVars = mlnew TVarList();
716        TVarList::iterator ci(domain->classVars->begin());
717        TVarList::const_iterator const ce(domain->classVars->end());
718        if (!domain->classVar && (classPos != attrs)) {
719            ci++;
720        }
721        for(; ci != ce; ci++) {
722            if (*ci == classVar) {
723                if (domain->classVar) {
724                    newDomain->classVars->push_back(domain->classVar);
725                }
726                else if (classPos != attrs) {
727                    newDomain->classVars->push_back(domain->classVars->front());
728                }
729            }
730            else {
731                newDomain->classVars->push_back(*ci);
732            }
733        }
734    }
735    ITERATE(TMetaVector, mi, domain->metas) {
736        newDomain->metas.push_back(*mi);
737    }
738    PDomain wdomain = newDomain;
739    domain = wdomain;
740    for(TExample **ri = examples; ri != _Last; ri++) {
741        (**ri).domain = wdomain;
742        if (classPos != attrs) {
743            TValue t = (**ri).values[attrs];
744            (**ri).values[attrs] = (**ri).values[classPos];
745            (**ri).values[classPos] = t;
746        }
747        (**ri).values_end += end_off;
748    }
749}
750
751void TExampleTable::addMetaAttribute(const int &id, const TValue &value)
752{ 
753  PEITERATE(ei, this)
754    (*ei).setMeta(id, value);
755
756  examplesHaveChanged();
757}
758
759
760void TExampleTable::copyMetaAttribute(const int &id, const int &source, TValue &defaultVal)
761{
762  if (source) {
763    PEITERATE(ei, this)
764      (*ei).setMeta(id, (*ei)[source]);
765    examplesHaveChanged();
766  }
767  else
768    addMetaAttribute(id, defaultVal);
769}
770
771
772void TExampleTable::removeMetaAttribute(const int &id)
773{
774  PEITERATE(ei, this)
775    (*ei).removeMetaIfExists(id);
776
777  examplesHaveChanged();
778}
779
780
781class TCompVar {
782public:
783  int varNum;
784
785  TCompVar(int vn) : varNum(vn) {}
786  bool operator()(const TExample *e1, const TExample *e2) const { return (*e1)[varNum].compare((*e2)[varNum])<0; }
787};
788
789
790void TExampleTable::sort()
791{
792  vector<int> empty;
793  sort(empty);
794}
795
796
797// Sort order is reversed (least important first!)
798void TExampleTable::sort(vector<int> &sortOrder)
799{ 
800  if (!sortOrder.size()) 
801    for(int i = domain->variables->size(); i; )
802      sortOrder.push_back(--i);
803
804  int ssize = _EndSpace-examples;
805  int lastOfs = _Last - examples;
806  TExample **temp = (TExample **)malloc(ssize * sizeof(TExample *));
807
808  try {
809    const_ITERATE(vector<int>, bi, sortOrder) {
810      int noVal = domain->getVar(*bi)->noOfValues();
811      if (noVal>0) {
812        vector<int> valf(noVal+1, 0);
813        TExample **t;
814        int id = 0;
815
816        for(t = examples; t!= _Last; t++) {
817          const TValue &val = (**t)[*bi];
818          const int intV = val.isSpecial() ? noVal : val.intV;
819          if (intV > noVal) {
820            free(temp);
821            raiseError("value out attribute '%s' of range", domain->variables->operator[](*bi)->get_name().c_str());
822          }
823          valf[intV]++;
824        }
825
826        for(vector<int>::iterator ni = valf.begin(); ni!=valf.end(); ni++) {
827          const int ini = *ni;
828          *ni = id;
829          id += ini;
830        }
831
832        for(t = examples; t!= _Last; t++) {
833          const TValue &val = (**t)[*bi];
834          const int intV = val.isSpecial() ? noVal : val.intV;
835          temp[valf[intV]++] = *t;
836        }
837
838        t = examples;
839        examples = temp;
840        temp = t;
841        _Last = examples + lastOfs;
842        _EndSpace = examples + ssize;
843      }
844
845      else
846        stable_sort(examples, _Last, TCompVar(*bi));
847    }
848  }
849  catch (...) {
850    examplesHaveChanged();
851    free(temp);
852    throw;
853  }
854
855  free(temp);
856
857  examplesHaveChanged();
858}
859
860void TExampleTable::shuffle()
861{
862  if (size() <= 1)
863    return;
864
865  if (!randomGenerator)
866    randomGenerator = mlnew TRandomGenerator();
867   
868  for(TExample **ei = examples+1; ei != _Last; ei++) {
869    const int st = randomGenerator->randint(ei - examples);
870    TExample *s = *ei;
871    *ei = examples[st];
872    examples[st] = s;
873  }
874}
875
876int TExampleTable::checkSum(const bool includeMetas)
877{ unsigned int crc;
878  INIT_CRC(crc);
879
880  for(TExample **ei = examples, **ee = _Last; ei!=ee; (*ei++)->addToCRC(crc, includeMetas));
881
882  FINISH_CRC(crc);
883  return int(crc & 0x7fffffff);
884}
885
886int TExampleTable::checkSum(const bool includeMetas) const
887{ unsigned int crc;
888  INIT_CRC(crc);
889
890  for(TExample **ei = examples, **ee = _Last; ei!=ee; (*ei++)->addToCRC(crc, includeMetas));
891
892  FINISH_CRC(crc);
893  return int(crc & 0x7fffffff);
894}
895
896bool TExampleTable::hasMissing() const
897{
898  for(TExample **ei = examples, **ee = _Last; ei != ee; ei++)
899    if ((*ei)->hasMissing())
900      return true;
901  return false;
902}
903
904
905bool TExampleTable::hasMissingClass() const
906{
907  if (!domain->classVar)
908    raiseError("data has no class");
909   
910  for(TExample **ei = examples, **ee = _Last; ei != ee; ei++)
911    if ((*ei)->missingClass())
912      return true;
913  return false;
914}
915
916void TExampleTable::sortByPointers()
917{
918  std::sort((int *)examples, (int *)_Last);
919}
Note: See TracBrowser for help on using the repository browser.