Пример #1
0
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");
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
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;
      }
    }
Пример #5
0
** 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)
    {
        ...
    }
Пример #6
0
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);
}
Пример #7
0
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);
  }
Пример #8
0
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;
}
Пример #9
0
TestResult checkTestable(Testable &&testable, Args &&... args) {
  return checkProperty(toProperty(std::forward<Testable>(testable)),
                       std::forward<Args>(args)...);
}
Пример #10
0
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;
  }
}
Пример #11
0
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;
    }
  }
}