Пример #1
0
Assignments CorrespondenceGenerator::generateGroupAssignments()
{		
	Assignments generatedAssignments;

	auto & segsA = sA->property["segments"].value<Segments>();
	auto & segsB = sB->property["segments"].value<Segments>();

	auto boxA = sA->bbox(), boxB = sB->bbox();

	auto & groupsA = sA->property["groups"].value< std::vector< std::vector<size_t> > >();
	auto & groupsB = sB->property["groups"].value< std::vector< std::vector<size_t> > >();

	/// Build similarity matrix of groups:
	Eigen::MatrixXd similiarity = Eigen::MatrixXd::Ones( groupsA.size(), groupsB.size() + 1 );

	for(size_t i = 0; i < similiarity.rows(); i++){
		double minVal = DBL_MAX;
		for(size_t j = 0; j < similiarity.cols(); j++){
			double val = 0;

			if( j < groupsB.size() )
			{
				Eigen::AlignedBox3d groupBoxA, groupBoxB;

				for(auto sid : groupsA[i]) groupBoxA.extend( segsA[sid].property["bbox"].value<Eigen::AlignedBox3d>() );
				for(auto sid : groupsB[j]) groupBoxB.extend( segsB[sid].property["bbox"].value<Eigen::AlignedBox3d>() );

				Vector3 relativeCenterA = (groupBoxA.center()-boxA.min()).array() / boxA.sizes().array();
				Vector3 relativeCenterB = (groupBoxB.center()-boxB.min()).array() / boxB.sizes().array();

				val = ( relativeCenterA - relativeCenterB ).norm();

				minVal = std::min(minVal, val);
			}

			similiarity(i,j) = val;
		}
		double maxVal = similiarity.row(i).maxCoeff();
		if(maxVal == 0) maxVal = 1.0;

		for(size_t j = 0; j < groupsB.size(); j++)
			similiarity(i,j) = (similiarity(i,j) - minVal) / maxVal;
	}

	std::vector< std::vector<float> > data;
	for(int i = 0; i < similiarity.rows(); i++){
		std::vector<float> dataRow;
		for(int j = 0; j < similiarity.cols(); j++) 
			dataRow.push_back( similiarity(i,j) );
		data.push_back(dataRow);
	}
	if(false) showTableColorMap(data, true); // DEBUG

	// Parameters:
	double similarity_threshold = 0.25;
	int count_threshold = 1;

	// Collect good candidates
	Assignments candidates;
	for(size_t i = 0; i < similiarity.rows(); i++){
		QVector<size_t> candidate;
		for(size_t j = 0; j < similiarity.cols(); j++){
			if(similiarity(i,j) < similarity_threshold)
				candidate << j;
		}
		candidates << candidate;
	}

	Assignments assignments;
	cart_product(assignments, candidates);

	// Filter assignments
	Assignments filtered;
	for(auto & a : assignments)
	{
		QMap<size_t,size_t> counts;
		bool accept = true;
		auto NOTHING_SEGMENT = similiarity.cols()-1;

		for(auto i : a) counts[i]++;
		for(auto k : counts.keys()){
			if(k != NOTHING_SEGMENT && counts[k] > count_threshold){
				accept = false;
				break;
			}
		}

		if( accept ) filtered << a;
	}

	// DEBUG:
	if(true) saveToTextFile("assignments.txt", vecToString2(filtered));

	generatedAssignments = filtered;
	
	return generatedAssignments;
}
//MAIN LOGIC BEGINS
int main() {

  //first unsigned int=total length of the actual representation, char = first 8 digits of the actual representation,
  //each KeyObject has these properties:
  //unsigned int unencodedLength; the total length of the unencoded number
  //unsigned int firstNDigits; the first 32 digits of the unencoded number
  //unsigned int primeRepresentation; the encoded representation of the number/key
  std::vector<KeyObject> keys;
  for(unsigned int i=0; i < 10000; i++){
      keys.push_back(KeyObject());
  }

  //unsigned int initialLowerBoundIndex = 0;
  //recursiveFillKeys(lowerBounds,upperBounds,initialLowerBoundIndex,keys,primes);

  //simple examle of generating the keys structure. (these are the numbers we will reduce the file to,
  //we store them in our ultra compact representation with some identifying info)
  //for (unsigned int i=6; i<10; i++){
  //  for (unsigned int j=6; j<10; j++){
  //    keys[(h-6)*16 + (i-6)*4 + (j-6)] = unsigned integerExponent(prime[0],i)*unsigned integerExponent(prime[1],j)....
  //  }
  //}

  Vvi input(build_input());
  std::cout << input << "\n";

  Vvi output;
  cart_product(input, output);
  std::cout << output << "\n";

  //sample input/output
  //input
  //  (
  //   (0, 1, 2, )
  //   (10, 11, 12, )
  //   (20, 21, 22, )
  //   )
  //  output
  //  (
  //   (0, 10, 20, )
  //   (1, 10, 20, )
  //   (2, 10, 20, )
  //   (0, 11, 20, )
  //   (1, 11, 20, )
  //   (2, 11, 20, )
  //   (0, 12, 20, )
  //   (1, 12, 20, )
  //   (2, 12, 20, )
  //   (0, 10, 21, )
  //   (1, 10, 21, )
  //   (2, 10, 21, )
  //   (0, 11, 21, )
  //   (1, 11, 21, )
  //   (2, 11, 21, )
  //   (0, 12, 21, )
  //   (1, 12, 21, )
  //   (2, 12, 21, )
  //   (0, 10, 22, )
  //   (1, 10, 22, )
  //   (2, 10, 22, )
  //   (0, 11, 22, )
  //   (1, 11, 22, )
  //   (2, 11, 22, )
  //   (0, 12, 22, )
  //   (1, 12, 22, )
  //   (2, 12, 22, ))
  unsigned int counter = 0;
  for(Vvi::iterator it = output.begin(); ; ) {
    //keyExponentValues gives us a vector with all the exponents we need to use
    //to create a key
    //here we calculate the number represented by the exponents

    mpz_t n;
    mpz_init(n);
    mpz_set(n,1);
    for (Vi::iterator keyExponentValues = it->begin(); ; ){
      mpz_t k;
      mpz_init(k);
      mpz_set(k,globals.primes[counter]);
      mpz_mul(n,n,k);
      n *= k;
      mpz_clear (k);
      //mpz_sizeinbase (mpz_t op, int base)
      //mpz_sizeinbase (mpz_t op, int base)
      //base can only be up to size 62 max!
      //here we store the length of the number represented by the exponents
      keys[counter].unencodedLength = 0;

      //here we store the first n digits of the number represented by the exponents
      keys[counter].firstNDigits = 0;
      mpz_clear (n);

      //this simulates log base 2
      unsigned int bitsToStoreExponent= 0;
      unsigned int exponentRange = globals.exponentMax - globals.exponentMin;
      while (exponentRange >>= 1) ++bitsToStoreExponent;
      //IMPORTANT ENCODING LOCATED RIGHT HERE IN THIS COMMENT!!!
      //00 = 6th power, 01=7th, 10=8th, 11=9th,
      //first 2 bits are for 2, next 2 are for 3, next 2 are for 5, etc. etc.
      unsigned int exponentCounter = 0;
      for(Vi::iterator keyExponentValues = it->begin(); ; ) {
        for (int j=globals.exponentMin; j<globals.exponentMax; j++){
          for (int k=0;k<bitsToStoreExponent;k++){
            //set i'th prime number bits to appropiate value between 0 and 2^k for exponent value j
            //globals.exponentMin - j want to turn this into binary representation, get appropriate number for ith place
            if (k==j){
              //keys[counter].primeRepresentation();
              //(globals.exponentMin - j) might be useful
              if (*keyExponentValues % intPow(2,k)==0){//base 10 number convert to base two, get ith digit.
                keys[counter].primeRepresentation.set(globals.howManyOfFirstNBitsStoredInKey
                                                      - exponentCounter*bitsToStoreExponent,1);
              }
              else{
                keys[counter].primeRepresentation.set(globals.howManyOfFirstNBitsStoredInKey
                                                      - exponentCounter*bitsToStoreExponent,0);
              }
            }
          }
        }
        //illustrative but less general example
        //switch(keyExponentValues->me[i]){
        //  case 6:
        //    keys[counter].primeRepresentation();
        //    keys[counter].primeRepresentation.set[32-i*2,0];
        //    keys[counter].primeRepresentation.set[31-i*2,0];
        //    break;
        //  case 7:
        //    keys[counter].primeRepresentation();
        //    keys[counter].primeRepresentation.set[32,0];
        //    keys[counter].primeRepresentation.set[31,1];
        //    break;
        //  case 8:
        //    keys[counter].primeRepresentation();
        //    keys[counter].primeRepresentation.set[32,1];
        //    keys[counter].primeRepresentation.set[31,0];
        //    break;
        //  case 9:
        //    keys[counter].primeRepresentation();
        //    keys[counter].primeRepresentation.set[32,1];
        //    keys[counter].primeRepresentation.set[31,1];
        //    break;
        //}
        exponentCounter++;
        keyExponentValues++;
      }
    }
    counter++;
    it++;
  }



  //HERE IS WHERE WE READ THE FILE IN THAT WE WILL ENCODE
  //TODO move this to a different section
  //char* input = getInputFromFile();

  //unsigned int i = 0;
  //while (input[i] != '\0'){
  //}
  return 0;
}
Пример #3
0
Paths CorrespondenceGenerator::generate()
{
	Paths result;

	auto boxA = a->bbox(), boxB = b->bbox();

	QStringList nodesA, nodesB;
	for (auto n : a->nodes) nodesA << n->id;
	for (auto n : b->nodes) nodesB << n->id;
	for (auto g : a->groups) for (auto nid : g) nodesA.removeAll(nid);
	for (auto g : b->groups) for (auto nid : g) nodesB.removeAll(nid);
	Structure::NodeGroups tmpA, tmpB;
	for (auto nid : nodesA) tmpA.push_back( QVector<QString>() << nid );
	for (auto nid : nodesB) tmpB.push_back( QVector<QString>() << nid );
	for (auto g : a->groups) tmpA.push_back(g);
	for (auto g : b->groups) tmpB.push_back(g);
	a->groups = tmpA;
	b->groups = tmpB;

	/// Build similarity matrix of groups:
	Eigen::MatrixXd similiarity = Eigen::MatrixXd::Ones(a->groups.size(), b->groups.size() + 1);

	for (size_t i = 0; i < similiarity.rows(); i++){
		double minVal = DBL_MAX;
		for (size_t j = 0; j < similiarity.cols(); j++){
			double val = 0;

			if (j < b->groups.size())
			{
				Eigen::AlignedBox3d groupBoxA, groupBoxB;
				for (auto sid : a->groups[i]) groupBoxA.extend(a->getNode(sid)->bbox(1.01));
				for (auto sid : b->groups[j]) groupBoxB.extend(b->getNode(sid)->bbox(1.01));

				Vector3 relativeCenterA = (groupBoxA.center() - boxA.min()).array() / boxA.sizes().array();
				Vector3 relativeCenterB = (groupBoxB.center() - boxB.min()).array() / boxB.sizes().array();

				val = (relativeCenterA - relativeCenterB).norm();

				minVal = std::min(minVal, val);
			}

			similiarity(i, j) = val;
		}
		double maxVal = similiarity.row(i).maxCoeff();
		if (maxVal == 0) maxVal = 1.0;

		for (size_t j = 0; j < b->groups.size(); j++)
			similiarity(i, j) = (similiarity(i, j) - minVal) / maxVal;
	}

	std::vector< std::vector<float> > data;
	for (int i = 0; i < similiarity.rows(); i++){
		std::vector<float> dataRow;
		for (int j = 0; j < similiarity.cols(); j++)
			dataRow.push_back(similiarity(i, j));
		data.push_back(dataRow);
	}
	//if (false) showTableColorMap(data, true); // DEBUG

	// Parameters:
	double similarity_threshold = 0.4;

	if (similiarity.rows() < 4) similarity_threshold = 1.0;

	// Collect good candidates
	Assignments candidates;
	for (size_t i = 0; i < similiarity.rows(); i++){
		QVector<size_t> candidate;
		for (size_t j = 0; j < similiarity.cols(); j++){
			if (similiarity(i, j) < similarity_threshold)
				candidate << j;
		}
		candidates << candidate;
	}

	int count_threshold = 1;

	Assignments assignments;
	if (candidates.size() > 7)
	{
		debugBox(QString("%1 candidates. Too complex (lower similairty?)").arg(candidates.size()));

		similarity_threshold = 0.1;

		Assignments candidates;
		for (size_t i = 0; i < similiarity.rows(); i++){
			QVector<size_t> candidate;
			for (size_t j = 0; j < similiarity.cols(); j++){
				if (similiarity(i, j) < similarity_threshold)
					candidate << j;
			}
			candidates << candidate;
		}

		cart_product(assignments, candidates, 10000);
		count_threshold = 12;
	}
	else
	{
		cart_product(assignments, candidates);
	}

	// Filter assignments
	Assignments filtered;
	for (auto & a : assignments)
	{
		QMap<size_t, size_t> counts;
		bool accept = true;
		auto NOTHING_SEGMENT = similiarity.cols() - 1;

		for (auto i : a) counts[i]++;
		for (auto k : counts.keys())
		{
			if (k != NOTHING_SEGMENT && counts[k] > count_threshold){
				accept = false;
				break;
			}
		}

		if (accept) filtered << a;
	}

	for (auto & assignment : filtered)
	{
		QVector < QStringList > landmarksA, landmarksB;

		for (size_t i = 0; i < assignment.size(); i++)
		{
			if (assignment[i] == b->groups.size()) continue;

			auto grpA = a->groups[i];
			auto grpB = b->groups[assignment[i]];

			// Resolve many-to-many
			if (grpA.size() > 1 && grpB.size() > 1)
			{
				QVector<QString> tmpA, tmpB;

				Eigen::AlignedBox3d groupBoxA, groupBoxB;
				for (auto sid : grpA) groupBoxA.extend(a->getNode(sid)->bbox(1.01));
				for (auto sid : grpB) groupBoxB.extend(b->getNode(sid)->bbox(1.01));

				for (auto nodeid_i : grpA){
					auto nodeA = a->getNode(nodeid_i);

					QMap < QString, double > dists;
					for (auto nodeid_j : grpB){
						auto nodeB = b->getNode(nodeid_j);

						Vector3 posA = (nodeA->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxA.min()).array() / boxA.sizes().array();
						Vector3 posB = (nodeB->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxB.min()).array() / boxB.sizes().array();

						dists[nodeid_j] = (posA - posB).norm();
					}
					auto nodeid_j = sortQMapByValue(dists).first().second;

					landmarksA << (QStringList() << nodeid_i);
					landmarksB << (QStringList() << nodeid_j);
				}
			}
			else
			{
				landmarksA << QStringList::fromVector(grpA);
				landmarksB << QStringList::fromVector(grpB);
			}
		}

		result.push_back( qMakePair(landmarksA, landmarksB) );
	}

    return result;
}
Пример #4
0
  void Worker::operator()() {
    for (private_index=get_index(); private_index!=-1; private_index=get_index()) {
      {boost::mutex::scoped_lock lock(io_mutex);
      std::cout << "THREAD " << id << " GOT " << private_index+1 << "/" << Globals::wspd_centers.size() << std::endl;}
    //Find the side length, radius, radius squared and center of circle/ring for
    //each one of the circle/rings that I'm going to draw
      for (int j=0; j<=Globals::wspd_circs_num[private_index]; j++) {
        //1 as argument because I insert parents of leaves
        //This means that when I do find a square with this side, I'm going to call
        //bear_children method again. This essentially reduces processing time by 3/4
        sides.push_back(side_discr(pow(2,j)*Globals::wspd_distances[private_index]/denominator,3));//1
//        sides.push_back(side_discr(pow(2,j)*Globals::wspd_distances[private_index]/denominator,0));
        //make radius an exact multiple of side
        radiuses.push_back(radius_discr(pow(2,j)*Globals::wspd_distances[private_index], sides[j]));
        radiuses_sqr.push_back(radiuses[j]*radiuses[j]);
        //Center of circle should fall neatly on the center of a grid square
        ANNpoint center = annAllocPt(Globals::dim);
        for (int k=0; k<Globals::dim; k++) {
          center[k] = center_discr(Globals::wspd_centers[private_index][k], sides[j], 0.5);
        }
        centers.push_back(center);
      }

      //first iteration is for the core, the inner circle which is completely filled
      //the rest of the iteration are rings, essentially 2 concentric cirles where I fill
      //the difference
      core=true;
      for (int circ=0; circ<=Globals::wspd_circs_num[private_index]; circ++) {
        //Generate all the possible values of a coordinate, based on side and radius
        //for example if radius is 8 and side is 2 this is going to be 0,2,4,6,8
        for (ANNcoord v=0.0; v<=radiuses[circ]; v+=sides[circ]) {
          all_values.push_back(v);
        }
        //cart_prod_counter=0;
        cart_product(all_values, result, circ);
        if (Globals::qbs[id]->children!=0)
        depth_all_reprs(Globals::qbs[id]);

//        find_all_reprs(Globals::qbs[id], &Globals::hypercube_center, 1.0, kdtree, asdf, id);
        
        //CLEANUP
        all_values.clear();
        core=false;
      }
    
      //CLEANUP
      radiuses.clear();
      radiuses_sqr.clear();
      sides.clear();
      for (unsigned int d=0; d<centers.size(); d++)
        annDeallocPt(centers[d]);
      centers.clear();

    }
    std::cout << "THREAD " << id << " DIES" << std::endl;
    annDeallocPt(qb_center);
    annDeallocPts(leaf_centers);
    delete[] leaf_reprs;
    pos_neg_result.clear();
    pos_neg_final.clear();
    vd1.clear();
    vd2.clear();
    delete asdf;
    delete kdtree;
//    delete qb;
    return;
  }