void TConditionalProbabilityEstimator_ByRows::checkCondition(const TValue &condition) const { checkProperty(estimatorList); if (!estimatorList->size()) raiseError("empty 'estimatorList'"); if (condition.isSpecial()) raiseError("undefined attribute value for condition"); if (condition.varType != TValue::INTVAR) raiseError("value for condition is not discrete"); if (condition.intV >= estimatorList->size()) raiseError("value for condition out of range"); }
float TProbabilityEstimator_FromDistribution::operator()(const TValue &classVal) const { checkProperty(probabilities); if (classVal.isSpecial()) raiseError("undefined attribute value"); /* This is a harmless shortcut to make things run faster in the most usual case */ if (classVal.varType == TValue::INTVAR) { const TDiscDistribution *ddist = probabilities.AS(TDiscDistribution); if (ddist) return (*ddist)[classVal.intV]; // else, let probabilities->p do something or (more probably) report an error } return probabilities->p(classVal); }
int validateLine(char *Line, int nWords) { char *token; int wordCount = 0; while(wordCount < nWords) { token = getToken(Line); if(wordCount < 1) { addKeyWordToken(token); //!This is a keyword } else { if(!checkProperty(token)){ //!This is a property addValue(token); //! Not a property add a value } } free(token); token = NULL; wordCount++; } return 0; }
void TExampleForMissing::resetExample() { checkProperty(dataDescription); DCs.clear(); DKs.clear(); float averageWeight=1; TVarList::const_iterator vi(domain->attributes->begin()), vie(domain->attributes->end()); TExample::iterator ei(begin()), bei(ei); vector<float>::const_iterator ai(dataDescription->averages.begin()), aei(dataDescription->averages.end()); for(; vi!=vie; ei++, vi++) { if ((*ei).isSpecial()) { if ((*vi)->varType==TValue::FLOATVAR) *ei=TValue(*ai); else if (dataDescription->missingWeight && (*ei).isDK()) { DKs.push_back(ei-bei); averageWeight/=float((*vi)->noOfValues()); } else DCs.push_back(ei-bei); (*vi)->firstValue(*ei); } if (ai!=aei) ai++; } if (dataDescription->missingWeight) { float weight = dataDescription->originalWeight ? getMeta(dataDescription->originalWeight).floatV : 1; if (dataDescription->domainDistributions) { TDomainDistributions::const_iterator di(dataDescription->domainDistributions->begin()); ITERATE(vector<int>, ci, DKs) { // DKs contain only discrete variables, so it is safe to cast const TDiscDistribution &dist = CAST_TO_DISCDISTRIBUTION(*(di+*ci)); if (dist.abs) weight *= dist.front() / dist.abs; } }
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ //! [0] QDesignerPropertyEditorInterface *propertyEditor = 0; propertyEditor = formEditor->propertyEditor(); connect(propertyEditor, SIGNAL(propertyChanged(QString, QVariant)), this, SLOT(checkProperty(QString, QVariant))); //! [0] //! [1] void checkProperty(QString property, QVariant value) { QDesignerPropertyEditorInterface *propertyEditor = 0; propertyEditor = formEditor->propertyEditor(); QObject *object = propertyeditor->object(); MyCustomWidget *widget = qobject_cast<MyCustomWidget>(object); if (widget && property == aProperty && value != expectedValue) { ... }
PClassifier TTreeSplitConstructor_Combined::operator()( PStringList &descriptions, PDiscDistribution &subsetSizes, float &quality, int &spentAttribute, PExampleGenerator gen, const int &weightID , PDomainContingency dcont, PDistribution apriorClass, const vector<bool> &candidates, PClassifier nodeClassifier ) { checkProperty(discreteSplitConstructor); checkProperty(continuousSplitConstructor); vector<bool> discrete, continuous; bool cse = candidates.size()==0; vector<bool>::const_iterator ci(candidates.begin()), ce(candidates.end()); TVarList::const_iterator vi(gen->domain->attributes->begin()), ve(gen->domain->attributes->end()); for(; (cse || (ci!=ce)) && (vi!=ve); vi++) { if (cse || *(ci++)) if ((*vi)->varType == TValue::INTVAR) { discrete.push_back(true); continuous.push_back(false); continue; } else if ((*vi)->varType == TValue::FLOATVAR) { discrete.push_back(false); continuous.push_back(true); continue; } discrete.push_back(false); continuous.push_back(false); } float discQuality; PStringList discDescriptions; PDiscDistribution discSizes; int discSpent; PClassifier discSplit = discreteSplitConstructor->call(discDescriptions, discSizes, discQuality, discSpent, gen, weightID, dcont, apriorClass, discrete, nodeClassifier); float contQuality; PStringList contDescriptions; PDiscDistribution contSizes; int contSpent; PClassifier contSplit = continuousSplitConstructor->call(contDescriptions, contSizes, contQuality, contSpent, gen, weightID, dcont, apriorClass, continuous, nodeClassifier); int N = gen ? gen->numberOfExamples() : -1; if (N<0) N = dcont->classes->cases; if ( discSplit && ( !contSplit || (discQuality>contQuality) || (discQuality==contQuality) && (N%2>0))) { quality = discQuality; descriptions = discDescriptions; subsetSizes = discSizes; spentAttribute = discSpent; return discSplit; } else if (contSplit) { quality = contQuality; descriptions = contDescriptions; subsetSizes = contSizes; spentAttribute = contSpent; return contSplit; } else return returnNothing(descriptions, subsetSizes, quality, spentAttribute); }
PClassifier TTreeSplitConstructor_ExhaustiveBinary::operator()( PStringList &descriptions, PDiscDistribution &subsetSizes, float &quality, int &spentAttribute, PExampleGenerator gen, const int &weightID , PDomainContingency dcont, PDistribution apriorClass, const vector<bool> &candidates, PClassifier ) { checkProperty(measure); measure->checkClassTypeExc(gen->domain->classVar->varType); PIntList bestMapping; int wins, bestAttr; PVariable bvar; if (measure->needs==TMeasureAttribute::Generator) { bool cse = candidates.size()==0; bool haveCandidates = false; vector<bool> myCandidates; myCandidates.reserve(gen->domain->attributes->size()); vector<bool>::const_iterator ci(candidates.begin()), ce(candidates.end()); TVarList::const_iterator vi, ve(gen->domain->attributes->end()); for(vi = gen->domain->attributes->begin(); vi != ve; vi++) { bool co = (*vi)->varType == TValue::INTVAR && (!cse || (ci!=ce) && *ci); myCandidates.push_back(co); haveCandidates = haveCandidates || co; } if (!haveCandidates) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); PDistribution thisSubsets; float thisQuality; wins = 0; int thisAttr = 0; int N = gen->numberOfExamples(); TSimpleRandomGenerator rgen(N); ci = myCandidates.begin(); for(vi = gen->domain->attributes->begin(); vi != ve; ci++, vi++, thisAttr++) { if (*ci) { thisSubsets = NULL; PIntList thisMapping = /*throughCont ? measure->bestBinarization(thisSubsets, thisQuality, *dci, dcont->classes, apriorClass, minSubset) : */measure->bestBinarization(thisSubsets, thisQuality, *vi, gen, apriorClass, weightID, minSubset); if (thisMapping && ( (!wins || (thisQuality>quality)) && ((wins=1)==1) || (thisQuality==quality) && rgen.randbool(++wins))) { bestAttr = thisAttr; quality = thisQuality; subsetSizes = thisSubsets; bestMapping = thisMapping; } } /*if (thoughCont) dci++; */ } if (!wins) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); if (quality<worstAcceptable) return returnNothing(descriptions, subsetSizes, spentAttribute); if (subsetSizes && subsetSizes->variable) bvar = subsetSizes->variable; else { TEnumVariable *evar = mlnew TEnumVariable(""); evar->addValue("0"); evar->addValue("1"); bvar = evar; } } else { bool cse = candidates.size()==0; if (!cse && noCandidates(candidates)) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); if (!dcont || dcont->classIsOuter) { dcont = PDomainContingency(mlnew TDomainContingency(gen, weightID)); // raiseWarningWho("TreeSplitConstructor_ExhaustiveBinary", "this class is not optimized for 'candidates' list and can be very slow"); } int N = gen ? gen->numberOfExamples() : -1; if (N<0) N = dcont->classes->cases; TSimpleRandomGenerator rgen(N); PDistribution classDistribution = dcont->classes; vector<bool>::const_iterator ci(candidates.begin()), ce(candidates.end()); TDiscDistribution *dis0, *dis1; TContDistribution *con0, *con1; int thisAttr = 0; bestAttr = -1; wins = 0; quality = 0.0; float leftExamples, rightExamples; TDomainContingency::iterator dci(dcont->begin()), dce(dcont->end()); for(; (cse || (ci!=ce)) && (dci!=dce); dci++, thisAttr++) { // We consider the attribute only if it is a candidate, discrete and has at least two values if ((cse || *(ci++)) && ((*dci)->outerVariable->varType==TValue::INTVAR) && ((*dci)->discrete->size()>=2)) { const TDistributionVector &distr = *(*dci)->discrete; if (distr.size()>16) raiseError("'%s' has more than 16 values, cannot exhaustively binarize", gen->domain->attributes->at(thisAttr)->get_name().c_str()); // If the attribute is binary, we check subsetSizes and assess the quality if they are OK if (distr.size()==2) { if ((distr.front()->abs<minSubset) || (distr.back()->abs<minSubset)) continue; // next attribute else { float thisMeas = measure->call(thisAttr, dcont, apriorClass); if ( ((!wins || (thisMeas>quality)) && ((wins=1)==1)) || ((thisMeas==quality) && rgen.randbool(++wins))) { bestAttr = thisAttr; quality = thisMeas; leftExamples = distr.front()->abs; rightExamples = distr.back()->abs; bestMapping = mlnew TIntList(2, 0); bestMapping->at(1) = 1; } continue; } } vector<int> valueIndices; int ind = 0; for(TDistributionVector::const_iterator dvi(distr.begin()), dve(distr.end()); (dvi!=dve); dvi++, ind++) if ((*dvi)->abs>0) valueIndices.push_back(ind); if (valueIndices.size()<2) continue; PContingency cont = prepareBinaryCheat(classDistribution, *dci, bvar, dis0, dis1, con0, con1); // A real job: go through all splits int binWins = 0; float binQuality = -1.0; float binLeftExamples = -1.0, binRightExamples = -1.0; // Selection: each element correspons to a value of the original attribute and is 1, if the value goes right // The first value always goes left (and has no corresponding bit in selection. TBoolCount selection(valueIndices.size()-1), bestSelection(0); // First for discrete classes if (dis0) { do { *dis0 = CAST_TO_DISCDISTRIBUTION(distr[valueIndices[0]]); *dis1 *= 0; vector<int>::const_iterator ii(valueIndices.begin()); ii++; for(TBoolCount::const_iterator bi(selection.begin()), be(selection.end()); bi!=be; bi++, ii++) *(*bi ? dis1 : dis0) += distr[*ii]; cont->outerDistribution->setint(0, dis0->abs); cont->outerDistribution->setint(1, dis1->abs); if ((dis0->abs < minSubset) || (dis1->abs < minSubset)) continue; // cannot split like that, to few examples in one of the branches float thisMeas = measure->operator()(cont, classDistribution, apriorClass); if ( ((!binWins) || (thisMeas>binQuality)) && ((binWins=1) ==1) || (thisMeas==binQuality) && rgen.randbool(++binWins)) { bestSelection = selection; binQuality = thisMeas; binLeftExamples = dis0->abs; binRightExamples = dis1->abs; } } while (selection.next()); } // And then exactly the same for continuous classes else { do { *con0 = CAST_TO_CONTDISTRIBUTION(distr[0]); *con1 = TContDistribution(); vector<int>::const_iterator ii(valueIndices.begin()); for(TBoolCount::const_iterator bi(selection.begin()), be(selection.end()); bi!=be; bi++, ii++) *(*bi ? con1 : con0) += distr[*ii]; if ((con0->abs<minSubset) || (con1->abs<minSubset)) continue; // cannot split like that, to few examples in one of the branches float thisMeas = measure->operator()(cont, classDistribution, apriorClass); if ( ((!binWins) || (thisMeas>binQuality)) && ((binWins=1) ==1) || (thisMeas==binQuality) && rgen.randbool(++binWins)) { bestSelection = selection; binQuality = thisMeas; binLeftExamples = con0->abs; binRightExamples = con1->abs; } } while (selection.next()); } if ( binWins && ( (!wins || (binQuality>quality)) && ((wins=1)==1) || (binQuality==quality) && rgen.randbool(++wins))) { bestAttr = thisAttr; quality = binQuality; leftExamples = binLeftExamples; rightExamples = binRightExamples; bestMapping = mlnew TIntList(distr.size(), -1); vector<int>::const_iterator ii = valueIndices.begin(); bestMapping->at(*(ii++)) = 0; ITERATE(TBoolCount, bi, bestSelection) bestMapping->at(*(ii++)) = *bi ? 1 : 0; } } } if (!wins) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); subsetSizes = mlnew TDiscDistribution(); subsetSizes->addint(0, leftExamples); subsetSizes->addint(1, rightExamples); } PVariable attribute = gen->domain->attributes->at(bestAttr); if (attribute->noOfValues() == 2) { spentAttribute = bestAttr; descriptions = mlnew TStringList(attribute.AS(TEnumVariable)->values.getReference()); TClassifierFromVarFD *cfv = mlnew TClassifierFromVarFD(attribute, gen->domain, bestAttr, subsetSizes); cfv->transformUnknowns = false; return cfv; } string s0, s1; int ns0 = 0, ns1 = 0; TValue ev; attribute->firstValue(ev); PITERATE(TIntList, mi, bestMapping) { string str; attribute->val2str(ev, str); if (*mi==1) { s1 += string(ns1 ? ", " : "") + str; ns1++; } else if (*mi==0) { s0 += string(ns0 ? ", " : "") + str; ns0++; } attribute->nextValue(ev); }
PClassifier TTreeSplitConstructor_Attribute::operator()( PStringList &descriptions, PDiscDistribution &subsetSizes, float &quality, int &spentAttribute, PExampleGenerator gen, const int &weightID, PDomainContingency dcont, PDistribution apriorClass, const vector<bool> &candidates, PClassifier nodeClassifier ) { checkProperty(measure); measure->checkClassTypeExc(gen->domain->classVar->varType); bool cse = candidates.size()==0; vector<bool>::const_iterator ci(candidates.begin()), ce(candidates.end()); if (!cse) { if (noCandidates(candidates)) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); ci = candidates.begin(); } int N = gen ? gen->numberOfExamples() : -1; if (N<0) N = dcont->classes->cases; TSimpleRandomGenerator rgen(N); int thisAttr = 0, bestAttr = -1, wins = 0; quality = 0.0; if (measure->needs == TMeasureAttribute::Contingency_Class) { vector<bool> myCandidates; if (cse) { myCandidates.reserve(gen->domain->attributes->size()); PITERATE(TVarList, vi, gen->domain->attributes) myCandidates.push_back((*vi)->varType == TValue::INTVAR); } else { myCandidates.reserve(candidates.size()); TVarList::const_iterator vi(gen->domain->attributes->begin()); for(; ci != ce; ci++, vi++) myCandidates.push_back(*ci && ((*vi)->varType == TValue::INTVAR)); } if (!dcont || dcont->classIsOuter) dcont = PDomainContingency(mlnew TDomainContingency(gen, weightID, myCandidates)); ci = myCandidates.begin(); ce = myCandidates.end(); TDomainContingency::iterator dci(dcont->begin()), dce(dcont->end()); for(; (ci != ce) && (dci!=dce); dci++, ci++, thisAttr++) if (*ci && checkDistribution((const TDiscDistribution &)((*dci)->outerDistribution.getReference()), minSubset)) { float thisMeas = measure->call(thisAttr, dcont, apriorClass); if ( ((!wins || (thisMeas>quality)) && ((wins=1)==1)) || ((thisMeas==quality) && rgen.randbool(++wins))) { quality = thisMeas; subsetSizes = (*dci)->outerDistribution; bestAttr = thisAttr; } } } else if (measure->needs == TMeasureAttribute::DomainContingency) { if (!dcont || dcont->classIsOuter) dcont = PDomainContingency(mlnew TDomainContingency(gen, weightID)); TDomainContingency::iterator dci(dcont->begin()), dce(dcont->end()); for(; (cse || (ci!=ce)) && (dci!=dce); dci++, thisAttr++) if ( (cse || *(ci++)) && ((*dci)->outerVariable->varType==TValue::INTVAR) && checkDistribution((const TDiscDistribution &)((*dci)->outerDistribution.getReference()), minSubset)) { float thisMeas = measure->call(thisAttr, dcont, apriorClass); if ( ((!wins || (thisMeas>quality)) && ((wins=1)==1)) || ((thisMeas==quality) && rgen.randbool(++wins))) { quality = thisMeas; subsetSizes = (*dci)->outerDistribution; bestAttr = thisAttr; } } } else { TDomainDistributions ddist(gen, weightID); TDomainDistributions::iterator ddi(ddist.begin()), dde(ddist.end()-1); for(; (cse || (ci!=ce)) && (ddi!=dde); ddi++, thisAttr++) if (cse || *(ci++)) { TDiscDistribution *discdist = (*ddi).AS(TDiscDistribution); if (discdist && checkDistribution(*discdist, minSubset)) { float thisMeas = measure->call(thisAttr, gen, apriorClass, weightID); if ( ((!wins || (thisMeas>quality)) && ((wins=1)==1)) || ((thisMeas==quality) && rgen.randbool(++wins))) { quality = thisMeas; subsetSizes = PDiscDistribution(*ddi); // not discdist - this would be double wrapping! bestAttr = thisAttr; } } } } if (!wins) return returnNothing(descriptions, subsetSizes, quality, spentAttribute); if (quality<worstAcceptable) return returnNothing(descriptions, subsetSizes, spentAttribute); PVariable attribute = gen->domain->attributes->at(bestAttr); TEnumVariable *evar = attribute.AS(TEnumVariable); if (evar) descriptions = mlnew TStringList(evar->values.getReference()); else descriptions = mlnew TStringList(subsetSizes->size(), ""); spentAttribute = bestAttr; TClassifierFromVarFD *cfv = mlnew TClassifierFromVarFD(attribute, gen->domain, bestAttr, subsetSizes); cfv->transformUnknowns = false; return cfv; }
TestResult checkTestable(Testable &&testable, Args &&... args) { return checkProperty(toProperty(std::forward<Testable>(testable)), std::forward<Args>(args)...); }
PDistribution TLogRegClassifier::classDistribution(const TExample &origexam) { checkProperty(domain); TExample cexample(domain, origexam); TExample *example2; if (imputer) example2 = imputer->call(cexample); else { if (dataDescription) for(TExample::const_iterator ei(cexample.begin()), ee(cexample.end()-1); ei!=ee; ei++) if ((*ei).isSpecial()) return TClassifier::classDistribution(cexample, dataDescription); example2 = &cexample; } TExample *example = continuizedDomain ? mlnew TExample(continuizedDomain, *example2) : example2; float prob1; try { // multiply example with beta TAttributedFloatList::const_iterator b(beta->begin()), be(beta->end()); // get beta 0 prob1 = *b; b++; // multiply beta with example TVarList::const_iterator vi(example->domain->attributes->begin()); TExample::const_iterator ei(example->begin()), ee(example->end()); for (; (b!=be) && (ei!=ee); ei++, b++, vi++) { if ((*ei).isSpecial()) raiseError("unknown value in attribute '%s'", (*vi)->get_name().c_str()); prob1 += (*ei).floatV * (*b); } prob1 = exp(prob1)/(1+exp(prob1)); } catch (...) { if (imputer) mldelete example2; if (continuizedDomain) mldelete example; throw; } if (imputer) mldelete example2; if (continuizedDomain) mldelete example; if (classVar->varType == TValue::INTVAR) { TDiscDistribution *dist = mlnew TDiscDistribution(classVar); PDistribution res = dist; dist->addint(0, 1-prob1); dist->addint(1, prob1); return res; } else { TContDistribution *dist = mlnew TContDistribution(classVar); PDistribution res = dist; dist->addfloat(prob1, 1.0); return res; } }
PDistanceMap TDistanceMapConstructor::operator ()(const float &unadjustedSqueeze, float &abslow, float &abshigh) { checkProperty(distanceMatrix); const TSymMatrix &distMat = distanceMatrix.getReference(); abshigh = -1e30f; abslow = 1e30f; if (order) { if (order->size() != distMat.dim) raiseError("size of 'order' does not match the size of the distance matrix"); if (unadjustedSqueeze < 1.0 - 1e-5) { int nLines = int(floor(0.5 + order->size() * unadjustedSqueeze)); if (!nLines) nLines++; PIntList psqi = new TIntList(); TOrangeVector<int, false> &squeezedIndices = psqi.getReference(); computeSqueezedIndices(distMat.dim, nLines, squeezedIndices); nLines = squeezedIndices.size() - 1; PDistanceMap dm = mlnew TDistanceMap(nLines); dm->elementIndices = psqi; TIntList::const_iterator row_squeezei(squeezedIndices.begin()), row_squeezen(row_squeezei+1), squeezee(squeezedIndices.end()); for(int row = 0; row_squeezen != squeezee; row_squeezei++, row_squeezen++, row++) { // this needs to be float (to avoid int division) float row_elements = *row_squeezen - *row_squeezei; // to diagonal, exclusive TIntList::const_iterator col_squeezei(squeezedIndices.begin()), col_squeezen(col_squeezei+1); for(int column = 0; col_squeezei != row_squeezei; col_squeezei++, col_squeezen++, column++) { float incell = 0.0; TIntList::const_iterator row_orderi(order->begin()+*row_squeezei), row_ordere(order->begin()+*row_squeezen); for(; row_orderi != row_ordere; row_orderi++) { TIntList::const_iterator col_orderi(order->begin()+*col_squeezei), col_ordere(order->begin()+*col_squeezen); for(; col_orderi != col_ordere; col_orderi++) incell += distMat.getitem(*row_orderi, *col_orderi); } incell /= row_elements * (*col_squeezen - *col_squeezei); dm->cells[row*nLines+column] = dm->cells[column*nLines+row] = incell; UPDATE_LOW_HIGH; } // diagonal { float incell = 0.0; TIntList::const_iterator row_orderi(order->begin()+*row_squeezei), row_ordere(order->begin()+*row_squeezen); for(; row_orderi != row_ordere; row_orderi++) { TIntList::const_iterator col_orderi(order->begin()+*row_squeezei); for(; col_orderi != row_orderi; col_orderi++) incell += distMat.getitem(*row_orderi, *col_orderi); incell += distMat.getitem(*row_orderi, *row_orderi); } incell /= row_elements * (row_elements+1) / 2.0; dm->cells[row*(nLines+1)] = incell; UPDATE_LOW_HIGH; } } return dm; } else { // order && no squeeze const int &dim = distMat.dim; PDistanceMap dm = mlnew TDistanceMap(dim); TIntList::const_iterator row_orderi(order->begin()), row_ordere(order->end()); for(int row = 0; row_orderi != row_ordere; row_orderi++, row++) { TIntList::const_iterator col_orderi(order->begin()); for(int column = 0; col_orderi != row_orderi; col_orderi++, column++) { const float &incell = distMat.getref(*row_orderi, *col_orderi); dm->cells[row*dim+column] = dm->cells[column*dim+row] = incell; UPDATE_LOW_HIGH; } const float &incell = distMat.getref(*row_orderi, *row_orderi); dm->cells[row*(dim+1)] = incell; UPDATE_LOW_HIGH; } return dm; } } else { // no order if (unadjustedSqueeze < 1 - 1e-5) { int nLines = int(floor(0.5 + distMat.dim * unadjustedSqueeze)); if (!nLines) nLines++; PIntList psqi = new TIntList(); TOrangeVector<int, false> &squeezedIndices = psqi.getReference(); computeSqueezedIndices(distMat.dim, nLines, squeezedIndices); nLines = squeezedIndices.size() - 1; PDistanceMap dm = mlnew TDistanceMap(nLines); dm->elementIndices = psqi; TIntList::const_iterator row_squeezei(squeezedIndices.begin()), row_squeezen(row_squeezei+1), squeezee(squeezedIndices.end()); for(int row = 0; row_squeezen != squeezee; row_squeezei++, row_squeezen++, row++) { // this needs to be float (to avoid int division) float row_elements = *row_squeezen - *row_squeezei; // to diagonal, exclusive TIntList::const_iterator col_squeezei(squeezedIndices.begin()), col_squeezen(col_squeezei+1); for(int column = 0; col_squeezei != row_squeezei; col_squeezei++, col_squeezen++, column++) { int col_elements = *col_squeezen - *col_squeezei; float incell = 0.0; int origrow = *row_squeezei, origrowe = *row_squeezen; for(; origrow != origrowe; origrow++) { const float *origval = &distMat.getref(origrow, *col_squeezei); for(int ce = col_elements; ce--; incell += *(origval++)); } incell /= row_elements * col_elements; dm->cells[row*nLines+column] = dm->cells[column*nLines+row] = incell; UPDATE_LOW_HIGH; } // diagonal { float incell = 0.0; int origrow = *row_squeezei, origrowe = *row_squeezen; for(; origrow != origrowe; origrow++) { const float *origval = &distMat.getref(origrow, *col_squeezei); for(int ce = origrow - *row_squeezei+1; ce--; incell += *(origval++)); } incell /= row_elements * (row_elements+1) / 2.0; dm->cells[row*(nLines+1)] = incell; UPDATE_LOW_HIGH; } } return dm; } else {// no order && no squeeze const int &dim = distMat.dim; PDistanceMap dm = mlnew TDistanceMap(dim); dm->elementIndices = new TIntList(); TOrangeVector<int, false> &squeezedIndices = dm->elementIndices.getReference(); for(int row = 0; row < dim; row++) { squeezedIndices.push_back(row); for(int column = 0; column < row; column++) { const float &incell = distMat.getref(row, column); dm->cells[row*dim+column] = dm->cells[column*dim+row] = incell; UPDATE_LOW_HIGH; } const float &incell = distMat.getref(row, row); dm->cells[row*(dim+1)] = incell; UPDATE_LOW_HIGH; } squeezedIndices.push_back(dim); return dm; } } }