source: orange/source/orange/rconversions.cpp @ 9532:2c6a8bb6ec89

Revision 9532:2c6a8bb6ec89, 4.2 KB checked in by janezd <janez.demsar@…>, 2 years ago (diff)

Conversion to numpy now supports multiple classes (Ticket #1012)

Line 
1/*
2    This file is part of Orange.
3   
4    Copyright 1996-2010 Faculty of Computer and Information Science, University of Ljubljana
5    Contact: janez.demsar@fri.uni-lj.si
6
7    Orange is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Orange is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Orange.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include <vector>
22#include "rconversions.hpp"
23#include "vars.hpp"
24#include "examplegen.hpp"
25
26
27void exampleGenerator2r(PExampleGenerator egen, const int &weightID, const char *contents, const int &multiTreatment,
28                        double *&X, double *&y, double *&w, int &rows, int &columns)
29{
30  bool hasClass, classVector, multiclassVector, weightVector, classIsDiscrete;
31  vector<bool> include;
32
33  parseMatrixContents(egen, weightID, contents, multiTreatment,
34                          hasClass, classVector, multiclassVector, weightVector, classIsDiscrete, columns, include);
35
36  // this does not work if the domain includes multiple classes -- which is irrelevant
37  // since nobody calls this function anyway ;)
38
39  rows = egen->numberOfExamples();
40
41  X = columns ? (double *)malloc(rows * columns * sizeof(double)) : NULL;
42  y = classVector ? (double *)malloc(rows * sizeof(double)) : NULL;
43  w = weightVector ? (double *)malloc(rows * sizeof(double)) : NULL;
44
45  double *Xi = X;
46  double *yi = y;
47  double *wi = w;
48
49  try {
50    int row = 0;
51    TExampleGenerator::iterator ei(egen->begin());
52    for(; ei; ++ei, row++, Xi += 1 - rows*columns) {
53      int col = 0;
54     
55      /* This is all optimized assuming that each symbol (A, C, W) only appears once.
56         If it would be common for them to appear more times, we could cache the values,
57         but since this is unlikely, caching would usually slow down the conversion */
58      for(const char *cp = contents; *cp && (*cp!='/'); cp++) {
59        switch (*cp) {
60          case 'A':
61          case 'a': {
62            const TVarList &attributes = egen->domain->attributes.getReference();
63            TVarList::const_iterator vi(attributes.begin()), ve(attributes.end());
64            TExample::iterator eei((*ei).begin());
65            vector<bool>::const_iterator bi(include.begin());
66            for(; vi != ve; eei++, vi++, bi++)
67              if (*bi) {
68                if ((*eei).isSpecial())
69                  raiseErrorWho("exampleGenerator2r", "value of attribute '%s' in example '%i' is undefined", (*vi)->get_name().c_str(), row);
70                *Xi = (*vi)->varType == TValue::FLOATVAR ? (*eei).floatV : float((*eei).intV);
71                Xi += rows;
72              }
73            break;
74          }
75
76          case 'C':
77          case 'c': 
78            if (hasClass) {
79              const TValue &classVal = (*ei).getClass();
80              if (classVal.isSpecial())
81                raiseErrorWho("exampleGenerator2r", "example %i has undefined class", row);
82              *Xi = classIsDiscrete ? float(classVal.intV) : classVal.floatV;
83              Xi += rows;
84            }
85            break;
86
87          case 'W':
88          case 'w': 
89            if (weightID)
90              *Xi = WEIGHT(*ei);
91              Xi += rows;
92            break;
93
94          case '0':
95            *Xi = 0.0;
96            Xi += rows;
97            break;
98
99          case '1':
100            *Xi = 1.0;
101            Xi += rows;
102            break;
103        }
104      }
105
106      if (y) {
107        const TValue &classVal = (*ei).getClass();
108        if (classVal.isSpecial())
109          raiseErrorWho("exampleGenerator2r", "example %i has undefined class", row);
110        *(yi++) = classIsDiscrete ? float(classVal.intV) : classVal.floatV;
111      }
112
113      if (w)
114        *(wi++) = WEIGHT(*ei);
115    }
116  }
117  catch (...) {
118    if (X)
119      free(X);
120    if (y)
121      free(y);
122    if (w)
123      free(w);
124    throw;
125  }
126}
Note: See TracBrowser for help on using the repository browser.