Changeset 9401:412768944677 in orange


Ignore:
Timestamp:
12/21/11 02:53:18 (2 years ago)
Author:
janezd <janez.demsar@…>
Branch:
default
Convert:
27664d6b6ce0ae71513d557f472348245832a15f
Message:

Added multiple classes (Ticket #1012)

Location:
source/orange
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • source/orange/c45inter.cpp

    r7665 r9401  
    123123  TDomainDepot::TPAttributeDescriptions adescs; 
    124124  TDomainDepot::pattrFromtAttr(attributeDescriptions, adescs); 
    125   return domainDepot.prepareDomain(&adescs, true, NULL, createNewOn, status, metaStatus); 
     125  return domainDepot.prepareDomain(&adescs, true, NULL, NULL, createNewOn, status, metaStatus); 
    126126} 
    127127 
  • source/orange/cls_example.cpp

    r7715 r9401  
    594594 
    595595 
     596PyObject *Example_get_classes(TPyExample *pex) PYARGS(METH_NOARGS, "()  -> [Values]; Returns example's class") 
     597{ PyTRY 
     598      const TExample &example = PyExample_AS_ExampleReference(pex); 
     599      PyObject *list=PyList_New(0); 
     600      if (example.domain->classes) { 
     601          TExample::const_iterator ei=example.values_end; 
     602          const_PITERATE(TVarList, vi, example.domain->classes) { 
     603            PyObject *valo = Value_FromVariableValue(*vi, *ei++); 
     604            PyList_Append(list, valo); 
     605            Py_DECREF(valo); 
     606          } 
     607      } 
     608      return list; 
     609  PyCATCH 
     610} 
     611 
     612 
    596613PyObject *Example_set_class(TPyExample *pex, PyObject *val) PYARGS(METH_O, "(value); Sets example's class") 
    597614{ PyTRY 
     
    610627  PyCATCH 
    611628} 
     629 
     630 
     631PyObject *Example_set_classes(TPyExample *pex, PyObject *val) PYARGS(METH_O, "(list-of-Values); Returns example's class") 
     632{ PyTRY 
     633      const TExample &example = PyExample_AS_ExampleReference(pex); 
     634      if (!PyList_Check(val)) { 
     635          PYERROR(PyExc_TypeError, "list of values expected", PYNULL); 
     636      } 
     637      if (!example.domain->classes) { 
     638          if (PyList_Size(val) != 0) { 
     639              PYERROR(PyExc_ValueError, "domain does not have multiple classes", PYNULL); 
     640          } 
     641          else { 
     642              RETURN_NONE; 
     643          } 
     644      } 
     645      if (PyList_Size(val) != example.domain->classes->size()) { 
     646          PyErr_Format(PyExc_IndexError, "expected %i values, got %i", example.domain->classes->size(), PyList_Size(val)); 
     647          return NULL; 
     648      } 
     649      TExample::iterator ei=example.values_end; 
     650      int pos = 0; 
     651      const_PITERATE(TVarList, vi, example.domain->classes) { 
     652          if (!convertFromPython(PyList_GET_ITEM(val, pos++), *ei++, *vi)) 
     653              return PYNULL; 
     654      } 
     655      RETURN_NONE; 
     656  PyCATCH 
     657} 
     658 
    612659 
    613660 
     
    839886void Example_pack(const TExample &example, TCharBuffer &buf, PyObject *&otherValues) 
    840887{ 
    841   for(TValue *vali = example.values; vali != example.values_end; vali++) 
     888  for(TValue *vali = example.values; vali != example.classes_end; vali++) 
    842889    Value_pack(*vali, buf, otherValues); 
    843890 
     
    864911{ 
    865912  TVarList::const_iterator vi = example.domain->variables->begin(); 
    866   for(TValue *vali = example.values; vali != example.values_end; vali++, vi++) { 
     913  for(TValue *vali = example.values; vali != example.classes_end; vali++, vi++) { 
    867914    vali->varType = (*vi)->varType; 
    868915    Value_unpack(*vali, buf, otherValues, otherValuesIndex); 
  • source/orange/cls_misc.cpp

    r7654 r9401  
    235235    TDomainDepot::pattrFromtAttr(attributeDescriptions, adescs); 
    236236    TDomainDepot::pattrFromtAttr(metaDescriptions, mdescs); 
    237     PDomain newDomain = ((TPyDomainDepot *)(self))->domainDepot->prepareDomain(&adescs, hasClass, &mdescs, createNewOn, status, metaStatus); 
     237    PDomain newDomain = ((TPyDomainDepot *)(self))->domainDepot->prepareDomain(&adescs, hasClass, NULL,  &mdescs, createNewOn, status, metaStatus); 
    238238 
    239239    return Py_BuildValue("NNN", WrapOrange(newDomain), encodeStatus(status), encodeStatus(metaStatus)); 
  • source/orange/domain.cpp

    r7665 r9401  
    4242: classVar((TVariable *)NULL), 
    4343  attributes(mlnew TVarList()), 
    44   variables(mlnew TVarList()),  
     44  variables(mlnew TVarList()), 
     45  classes(PVarList()), 
    4546  version(++domainVersion), 
    4647  lastDomain(knownDomains.end()), 
     
    5354  attributes(mlnew TVarList(vl)), 
    5455  variables(mlnew TVarList(vl)), 
     56  classes(PVarList()), 
    5557  version(++domainVersion), 
    5658  lastDomain(knownDomains.end()), 
     
    6567  attributes(mlnew TVarList(vl)), 
    6668  variables(mlnew TVarList(vl)), 
     69  classes(PVarList()), 
    6770  version(++domainVersion), 
    6871  lastDomain(knownDomains.end()), 
     
    7982  attributes(mlnew TVarList(old.attributes.getReference())), 
    8083  variables(mlnew TVarList(old.variables.getReference())),  
     84  classes(old.classes ? mlnew TVarList(old.classes.getReference()) : NULL), 
    8185  metas(old.metas), 
    8286  version(++domainVersion), 
     
    204208int TDomain::getVarNum(PVariable var, bool throwExc) const 
    205209{ int pos = 0; 
    206   for(TVarList::const_iterator vi(variables->begin()), ve(variables->end()); vi!=ve; vi++, pos++) 
     210  TVarList::const_iterator vi, ve; 
     211  for(vi = variables->begin(), ve = variables->end(); vi!=ve; vi++, pos++) 
    207212    if (*vi == var) 
    208213      return pos; 
     214  if (classes) 
     215    for(vi = classes->begin(), ve = classes->end(); vi != ve; vi++, pos++) 
     216        if (*vi == var) 
     217            return pos; 
    209218 
    210219  pos = getMetaNum(var, false); 
     
    218227int TDomain::getVarNum(const string &name, bool throwExc) const 
    219228{ int pos = 0; 
    220   for(TVarList::const_iterator vi(variables->begin()), ve(variables->end()); vi!=ve; vi++, pos++) 
     229  TVarList::const_iterator vi, ve; 
     230  for(vi = variables->begin(), ve = variables->end(); vi!=ve; vi++, pos++) 
    221231    if ((*vi)->get_name()== name) 
    222232      return pos; 
     233  if (classes) 
     234    for(vi = classes->begin(), ve = classes->end(); vi != ve; vi++, pos++) 
     235        if ((*vi)->get_name() == name) 
     236            return pos; 
    223237 
    224238  pos = getMetaNum(name, false); 
     
    234248   
    235249  if (num>=0) { 
    236     if (num>=int(variables->size())) 
     250      if (num < variables->size()) 
     251          return variables->at(num); 
     252 
     253      if (classes && (num - variables->size() < classes->size())) 
     254          return classes->at(num - variables->size()); 
     255 
    237256      if (throwExc) 
    238257        if (!variables->size()) 
    239258          raiseError("no attributes in domain"); 
    240259        else 
    241           raiseError("index %i out of range 0-%i", num, variables->size()-1); 
     260          raiseError("index %i out of range", num); 
    242261      else 
    243262        return PVariable(); 
    244  
    245     return variables->at(num); 
    246263  } 
    247264  else { 
     
    264281   
    265282  if (num>=0) { 
    266     if (num>=int(variables->size())) 
     283      if (num < variables->size()) 
     284          return variables->at(num); 
     285 
     286      if (classes && (num - variables->size() < classes->size())) 
     287          return classes->at(num - variables->size()); 
     288 
    267289      if (throwExc) 
    268290        if (!variables->size()) 
    269291          raiseError("no attributes in domain"); 
    270292        else 
    271           raiseError("index %i out of range 0-%i", num, variables->size()-1); 
     293          raiseError("index %i out of range", num); 
    272294      else 
    273295        return PVariable(); 
    274  
    275     return variables->at(num); 
    276296  } 
    277297  else { 
     
    294314    if ((*vi)->get_name()==name) 
    295315      return *vi; 
    296  
     316  if (classes) { 
     317    PITERATE(TVarList, vi, classes) 
     318    if ((*vi)->get_name()==name) 
     319      return *vi; 
     320  } 
    297321  if (takeMetas) 
    298322    ITERATE(TMetaVector, mi, metas) 
     
    311335    if ((*vi)->get_name()==name) 
    312336      return *vi; 
     337  if (classes) { 
     338    const_PITERATE(TVarList, vi, classes) 
     339    if ((*vi)->get_name()==name) 
     340      return *vi; 
     341  } 
    313342 
    314343  if (takeMetas) 
  • source/orange/domain.hpp

    r6531 r9401  
    6969  PVarList attributes; //PR list of attributes, excluding the class 
    7070  PVarList variables; //PR list of attributes, including the class at the end of the list 
     71  PVarList classes; //PR list of class variables, if multiple; else None 
    7172 
    7273  TMetaVector metas; 
  • source/orange/domaindepot.cpp

    r7665 r9401  
    276276 
    277277PDomain TDomainDepot::prepareDomain(TPAttributeDescriptions *attributes, bool hasClass, 
     278                                    TPAttributeDescriptions *classDescriptions, 
    278279                                    TPAttributeDescriptions *metas, const int createNewOn, 
    279280                                    vector<int> &status, vector<pair<int, int> > &metaStatus) 
     
    287288    status.push_back(tStatus); 
    288289  } 
    289  
     290   
    290291  PDomain newDomain; 
    291292  PVariable classVar; 
     
    296297   
    297298  newDomain = mlnew TDomain(classVar, attrList); 
     299 
     300  if (classDescriptions) { 
     301      newDomain->classes = mlnew TVarList(); 
     302      PITERATE(TPAttributeDescriptions, ai, classDescriptions) { 
     303          newDomain->classes->push_back(makeVariable(**ai, tStatus, createNewOn)); 
     304      } 
     305  } 
    298306 
    299307  metaStatus.clear(); 
  • source/orange/domaindepot.hpp

    r7164 r9401  
    7777 
    7878  PDomain prepareDomain(TPAttributeDescriptions *attributes, bool hasClass, 
     79                        TPAttributeDescriptions *classDescriptions, 
    7980                        TPAttributeDescriptions *metas, const int createNewOn, 
    8081                        vector<int> &status, vector<pair<int, int> > &metaStatus); 
  • source/orange/examples.cpp

    r7665 r9401  
    4343: values(NULL), 
    4444  values_end(NULL), 
     45  classes_end(NULL), 
    4546  name(NULL), 
    4647  id(getExampleId()) 
     
    5253  values(NULL), 
    5354  values_end(NULL), 
     55  classes_end(NULL), 
    5456  name(NULL), 
    5557  id(getExampleId()) 
     
    5860 
    5961  const int attrs = domain->variables->size(); 
    60   TValue *vi = values = mlnew TValue[attrs]; 
     62  const int classes = domain->classes ? domain->classes->size() : 0; 
     63  TValue *vi = values = mlnew TValue[attrs+classes]; 
    6164  values_end = values + attrs; 
     65  classes_end = values_end + classes; 
    6266  PITERATE(TVarList, di, dom->variables) 
    6367    *(vi++) = (*di)->DK(); 
    64  
     68  if (dom->classes) { 
     69    PITERATE(TVarList, ci, dom->classes) { 
     70        *(vi++) = (*ci)->DK(); 
     71    } 
     72  } 
    6573  if (initMetas) 
    6674    ITERATE(TMetaVector, mi, dom->metas) 
     
    7785{ if (domain) { 
    7886    const int attrs = domain->variables->size(); 
    79     TValue *vi = values = mlnew TValue[attrs]; 
     87    const int classes = orig.classes_end - orig.values_end; 
     88    TValue *vi = values = mlnew TValue[attrs+classes]; 
    8089    values_end = values + attrs; 
    81     for(TValue *origi = orig.values, *thisi = values; thisi != values_end; *(thisi++) = *(origi++)); 
    82   } 
    83   else values = values_end = NULL; 
     90    classes_end = values_end + classes; 
     91    for(TValue *origi = orig.values, *thisi = values; thisi != classes_end; *(thisi++) = *(origi++)); 
     92  } 
     93  else  
     94      values = values_end = classes_end = NULL; 
    8495} 
    8596 
     
    94105 
    95106  const int attrs = domain->variables->size(); 
    96   values = mlnew TValue[attrs]; 
     107  const int classes = domain->classes ? domain->classes->size() : 0; 
     108  values = mlnew TValue[attrs + classes]; 
    97109  values_end = values + attrs; 
     110  classes_end = values_end + classes; 
    98111  domain->convert(*this, orig, !copyMetas); 
    99112} 
     
    147160  if (!dom) 
    148161    raiseError("example needs a domain"); 
     162  if (dom->classes) { 
     163      raiseError("example merging does not support multiple classes"); 
     164  } 
    149165 
    150166  const int attrs = domain->variables->size(); 
     167  const int classes = domain->classes ? domain->classes->size() : 0; 
    151168  vector<bool> defined(attrs, false); 
    152169 
     
    193210{ TRAVERSE(TOrange::traverse); 
    194211   
    195   for(TValue *vi = values, *ve = values_end; vi!=ve; vi++) 
     212  for(TValue *vi = values, *ve = classes_end; vi!=ve; vi++) 
    196213    if (vi->svalV) 
    197214      PVISIT(vi->svalV); 
     
    207224int TExample::dropReferences() 
    208225{ 
    209   for(TValue *vi = values, *ve = values_end; vi!=ve; vi++) 
     226  for(TValue *vi = values, *ve = classes_end; vi!=ve; vi++) 
    210227    if (vi->svalV) 
    211228      vi->svalV.~PSomeValue(); 
     
    225242{ 
    226243  if (!orig.domain) { 
    227     values = values_end = NULL; 
     244    if (values) 
     245       mldelete[] values; 
     246    values = values_end = classes_end = NULL; 
    228247    domain = PDomain(); 
    229248  } 
    230249 
    231250  else { 
    232     const int attrs = orig.domain->variables->size(); 
    233  
     251    const int attrs = orig.values_end - orig.values; 
     252    const int classes = orig.classes_end - orig.values_end; 
    234253    if (domain != orig.domain) { 
    235       if (domain->variables->size() != attrs) { 
     254      if ((values_end - values != attrs) || (classes_end - values_end != classes)) { 
    236255        if (values) 
    237256          mldelete[] values; 
    238         values = mlnew TValue[attrs]; 
     257        values = mlnew TValue[attrs+classes]; 
    239258        values_end = values + attrs; 
    240       } 
    241  
     259        classes_end = values_end + classes; 
     260      } 
    242261      domain = orig.domain; 
    243262    } 
    244263 
    245     for(TValue *origi = orig.values, *thisi = values; thisi != values_end; *(thisi++) = *(origi++)); 
     264    for(TValue *origi = orig.values, *thisi = values; thisi != classes_end; *(thisi++) = *(origi++)); 
    246265  } 
    247266 
     
    313332    raiseError("examples are from different domains"); 
    314333 
    315   int Na = domain->variables->size(); 
     334  int Na = domain->variables->size() + (domain->classes ? domain->classes->size() : 0); 
    316335  if (!Na) 
    317336    return true; 
     
    325344    raiseError("examples are from different domains"); 
    326345 
    327   const_iterator i1(begin()), i2(other.begin()); 
    328   int Na = domain->variables->size() - (ignoreClass && domain->classVar ? 1 : 0); 
     346  int Na = domain->variables->size(); 
     347  if (ignoreClass) { 
     348      if (domain->classVar) { 
     349          Na--; 
     350      } 
     351  } 
     352  else { 
     353      if (domain->classes) { 
     354          Na += domain->classes->size(); 
     355      } 
     356  } 
    329357  if (!Na) 
    330358    return true; 
    331359 
     360  const_iterator i1(begin()), i2(other.begin()); 
    332361  int comp; 
    333362  while (0==(comp= (*(i1++)).compare(*(i2++))) && --Na); 
     
    340369    raiseError("examples are from different domains"); 
    341370   
    342   int Na = domain->variables->size() - (ignoreClass && domain->classVar ? 1 : 0); 
     371  int Na = domain->variables->size(); 
     372  if (ignoreClass) { 
     373      if (domain->classVar) { 
     374          Na--; 
     375      } 
     376  } 
     377  else { 
     378      if (domain->classes) { 
     379          Na += domain->classes->size(); 
     380      } 
     381  } 
    343382  if (!Na) 
    344383    return true; 
     
    350389#include "stringvars.hpp" 
    351390 
    352 void TExample::addToCRC(unsigned long &crc, const bool includeMetas) const 
    353 { 
    354   TValue *vli = values; 
    355   const_PITERATE(TVarList, vi, domain->variables) { 
     391inline void addToCRC(unsigned long &crc, const PVarList &vars, TValue *&vli) 
     392{ 
     393  const_PITERATE(TVarList, vi, vars) { 
    356394    if ((*vi)->varType == TValue::INTVAR) 
    357395      add_CRC((const unsigned long)(vli->isSpecial() ? ILLEGAL_INT : vli->intV), crc); 
     
    366404    vli++; 
    367405  } 
     406} 
     407 
     408void TExample::addToCRC(unsigned long &crc, const bool includeMetas) const 
     409{ 
     410  TValue *vli = values; 
     411  ::addToCRC(crc, domain->variables, vli); 
     412  if (domain->classes) 
     413      ::addToCRC(crc, domain->classes, vli); 
    368414   
    369415  if (includeMetas) { 
  • source/orange/examples.hpp

    r6531 r9401  
    4040 
    4141  PDomain domain; //PR Example's domain 
    42   TValue *values, *values_end; 
     42  TValue *values, *values_end, *classes_end; 
    4343  TMetaValues meta; 
    4444  string *name; 
     
    161161  bool hasMissing() const 
    162162  { 
    163     for(TValue const *vi = values, *ve = values_end; vi!=ve; vi++) 
     163    for(TValue const *vi = values, *ve = classes_end; vi!=ve; vi++) 
    164164      if (vi->isSpecial()) 
    165165        return true; 
  • source/orange/tabdelim.cpp

    r7666 r9401  
    121121  vector<string>::iterator ai(atoms.begin()); 
    122122  TIntList::iterator si(attributeTypes->begin()), se(attributeTypes->end()); 
     123  TIntList::iterator cb, cp, ce; 
     124  if (classPoses) { 
     125      cb = cp = classPoses->begin(); 
     126      ce = classPoses->end(); 
     127  } 
    123128  int pos=0; 
    124129  for (; (si!=se); pos++, si++, ai++) { 
     
    139144            domain->classVar->filestr2val(valstr, cval, exam); 
    140145            exam.setClass(cval); 
     146          } 
     147          else if (classPoses && (cp != ce) && (pos == *cp)) { 
     148              const int ind = cp - cb; 
     149              domain->classes->at(ind)->filestr2val(valstr, exam.values_end[ind], exam); 
     150              cp++; 
    141151          } 
    142152          else { // if this is a normal value 
     
    170180  if (pos==classPos) // if class is the last value in the line, it is set here 
    171181    domain->classVar->filestr2val(ai==atoms.end() ? "?" : *(ai++), exam[domain->variables->size()-1], exam); 
     182  /* I'm not sure that this is needed; this code is a mess but I don't wish to 
     183     waste time studying it since we are moving to 3.0 */ 
     184  else if (classPoses && (cp != ce) && (pos == *cp)) { 
     185    const int ind = cp - cb; 
     186    domain->classes->at(ind)->filestr2val(ai==atoms.end() ? "?" : *(ai++), exam.values_end[ind], exam); 
     187  } 
    172188 
    173189  while ((ai!=atoms.end()) && !(*ai).length()) ai++; // line must be empty from now on 
     
    319335   
    320336  TIntList::iterator ati(attributeTypes->begin()); 
    321   TDomainDepot::TPAttributeDescriptions attributeDescriptions, metaDescriptions; 
     337  TDomainDepot::TPAttributeDescriptions attributeDescriptions, metaDescriptions, classDescriptions; 
    322338  int ind = 0, lastRegular = -1; 
     339  TIntList::const_iterator cp, ce; 
     340  if (classPoses) { 
     341      cp = classPoses->begin(); 
     342      ce = classPoses->end(); 
     343  } 
    323344 
    324345  for(TDomainDepot::TAttributeDescriptions::iterator adi(descriptions.begin()), ade(descriptions.end()); adi != ade; adi++, ati++, ind++) { 
     
    351372    if (*ati == 1) 
    352373      metaDescriptions.push_back(&*adi); 
    353        
     374    else if (classPoses && (cp != ce) && (*cp == ind)) { 
     375        classDescriptions.push_back(&*adi); 
     376        cp++; 
     377    } 
    354378    else if ((classPos != ind) && (basketPos != ind)) { 
    355379      attributeDescriptions.push_back(&*adi); 
     
    376400  } 
    377401*/ 
    378   PDomain newDomain = domainDepot.prepareDomain(&attributeDescriptions, classPos>-1, &metaDescriptions, createNewOn, status, metaStatus); 
     402  PDomain newDomain = domainDepot.prepareDomain(&attributeDescriptions, classPos>-1, &classDescriptions, &metaDescriptions, createNewOn, status, metaStatus); 
    379403 
    380404  vector<pair<int, int> >::const_iterator mid(metaStatus.begin()); 
     
    610634{ 
    611635  classPos = -1; 
     636  classPoses = mlnew TIntList; 
    612637  basketPos = -1; 
    613638  headerLines = 3; 
     
    667692        } 
    668693         
     694        else if (direct=="multiclass") { 
     695          classPoses->push_back(ind); 
     696        } 
     697         
    669698        else if ((direct=="m") || (direct=="meta")) 
    670699          *attributeType = 1; 
     
    679708      desc.userFlags = args.unrecognized; 
    680709    } 
    681  
     710     
    682711    if (!strcmp((*ti).c_str(), "basket")) { 
    683712      if (basketPos > -1) 
     
    728757    } 
    729758  } 
     759 
     760  if (!classPoses->size()) 
     761      classPoses = PIntList(); 
    730762} 
    731763 
  • source/orange/tabdelim.hpp

    r6531 r9401  
    7171  char *DC; //P general character that denotes DC 
    7272  int classPos; //P position of the class attribute 
     73  PIntList classPoses; //P positions of class attributes if there are multiple; otherwise None 
    7374  int basketPos; //P position of the (virtual) basket attribute 
    7475  int headerLines; //P number of header lines (3 for .tab, 1 for .txt) 
Note: See TracChangeset for help on using the changeset viewer.