Exemple #1
0
int main(int argc, char* argv[]) {

  //Here is the input file name:
  ifstream input(argv[1]);
  Network my_net(input);
 
  ComponentPart cp;
  auto_ptr<NetworkPartition> components(cp.partition(my_net));
  int component = 0;
  auto_ptr<Iterator<Network*> > comp_it(components->getComponents());
  while(comp_it->moveNext()) {
    stringstream name;
    name << argv[1] << "." << component;
    component++;
    ofstream output(name.str().c_str());
    Network* this_comp = comp_it->current();
    this_comp->printTo(output);
  }
  return 1;
}
Exemple #2
0
int main(int argc, char** argv) {

  Network my_net(cin);
  cout << "graph G {" << endl; 
  Network::EdgeSet printed_edges;
  //Look on components:
  ComponentPart cp;
  NewmanCom comfinder;
  auto_ptr<NetworkPartition> components_np(cp.partition(my_net));
  const vector<Network*>& components = components_np->asVector();
  vector<Network*>::const_iterator comp_it;
  int community = 0;
  for(comp_it = components.begin(); comp_it != components.end(); comp_it++) {
    stringstream com;
    com << community++;
    Network* this_net = *comp_it;
    printCommunities(comfinder, com.str(), *this_net, cout, printed_edges, 1);
  }
  printEdges(my_net, printed_edges, "[len=16, color=green]");
  cout << "}" << endl;
  return 1;
}
void SearchSpacePruning<T>::filterCandidatesByDepth(Parts& parts, vectorCandidate& candidates, const Mat& depth, const float zfactor) {

	vectorCandidate new_candidates;
	const unsigned int N = candidates.size();
	for (unsigned int n = 0; n < N; ++n) {
		const unsigned int c = candidates[n].component();
		const unsigned int nparts = parts.nparts(c);
		const vector<Rect>& boxes = candidates[n].parts();
		for (unsigned int p = nparts-1; p >= 1; --p) {
			ComponentPart part = parts.component(c,p);
			Point anchor = part.anchor(0);
			Rect child   = boxes[part.self()];
			Rect parent  = boxes[part.parent().self()];
			T cmed_depth = Math::median<T>(depth(child));
			T pmed_depth = Math::median<T>(depth(parent));
			if (cmed_depth > 0 && pmed_depth > 0) {
				if (abs(cmed_depth-pmed_depth) > norm(anchor)*zfactor) break;
			}
			if (p == 1) new_candidates.push_back(candidates[n]);
		}
	}
	candidates = new_candidates;
}
Exemple #4
0
int main(int argc, char* argv[]) {

  if( argc < 4 ) {
    //
    cout << "Usage: " << argv[0] << " graph blacklist whitelist" << endl;
    return 0;
  }
  ifstream input(argv[1]);
  ofstream spam(argv[2]);
  ofstream ham(argv[3]);
  Network graph(input);
  
  double min_cc = 0.1;
  double kmfrac = 0.6;
  int min_size = 10;
  double whole_graph_c = graph.getTransitivity();
  //The subgraphs of spam and nonspam
  set<Network*> spamg, hamg;
  
     ComponentPart cp;
     auto_ptr<NetworkPartition> netpart(cp.partition(graph));
     vector<Network*> components(netpart->asVector());
     vector<Network*>::iterator comp_it;
     Edge* cut_edge = 0;
     while( components.size() > 0 ) {
       //Choose the biggest graph
       comp_it = components.begin();
       Network* this_net = *comp_it;
       Network::NodePSet::const_iterator n_it;
       int kmax = 0;
       auto_ptr<NodeIterator> ni( this_net->getNodeIterator() );
       while( ni->moveNext() ) {
	 Node* this_node = ni->current();
         if( kmax < this_net->getDegree( this_node ) ) {
           kmax = this_net->getDegree( this_node );
	 }
       }
       int size = this_net->getNodeSize();
       if( size > min_size ) {
         if( this_net->getClusterCoefficient() > min_cc ) {
	   //Ham:
	   hamg.insert( this_net );
	 }
	 //Maybe spam:
	 else if( (kmax + 1) < kmfrac * size ) { 
           if( this_net->getClusterCoefficient() == 0.0 ) {
             //Spam:
             spamg.insert( this_net );
	   }
           else {
             //Ambiguous
             map<Edge*, double> bet;
	     Network* this_comp = *comp_it;
             cut_edge = this_comp->getEdgeBetweenness(bet);
             this_comp->remove( cut_edge->first );
             this_comp->remove( cut_edge->second );
	     auto_ptr<NetworkPartition> split_part(cp.partition(*this_comp)); 
             const vector<Network*>& split = split_part->asVector();
             components.insert(components.end(), split.begin(), split.end());
           }
         }
       }
       //cout << "graphs: " << components.size() << endl;
       components.erase( comp_it );
     }

  //Print out the nodes in each spamg and hamg
  Network::NodePSet::const_iterator nit;
  set<Network*>::iterator netsetit;
  for(netsetit = spamg.begin(); netsetit != spamg.end(); netsetit++) {
    auto_ptr<NodeIterator> ni2( (*netsetit)->getNodeIterator() );
    while( ni2->moveNext() ) {
      Node* this_node = ni2->current();
      spam << this_node->toString() << endl;
    }
  }
  for(netsetit = hamg.begin(); netsetit != hamg.end(); netsetit++) {
    auto_ptr<NodeIterator> ni2( (*netsetit)->getNodeIterator() );
    while( ni2->moveNext() ) {
      Node* this_node = ni2->current();
      ham << this_node->toString() << endl;
    }
  }
  //Delete the memory:
  return 1;
}
Exemple #5
0
int main(int argc, char* argv[]) {

     //Here we consider a network for a P2P topology
     Ran1Random r1(time(NULL)), r2(-1000), r3(-1000000), r4(-5678);
     ContentNetwork* my_cnet = 0;
     Node* a_node = 0;
     ContentNode* c_node = 0;
     vector<Node*> node_vector;
     
     //Here is all the content
     vector<ContentNode*> content_vector;
     int cont_count = 10; 
     //Look for each content 10 times:
     int runs = 10*cont_count;
     content_vector.reserve(cont_count);
     for(int i = 0; i < cont_count; i++) {
         content_vector.push_back(new ContentNode);
     }
     
     Network* my_net = 0;
     //my_net = new PrefDelCompNetwork(RandomNetwork(10,1.0,r1),r1,0.75,1,0.6666);
     //my_net = new DoublePrefAtNetwork( RandomNetwork(10,0.6,r1), r1, 1 );
     //my_net = new PrefAtNetwork( RandomNetwork(2,1.0,r1), r1, 1 );
     //ifstream input("internal.dat");
     //my_net = new Network(input);
     /*while(my_net->getNodes().size() < 40000) {
       dynamic_cast<Incrementable*>(my_net)->incrementTime();
       }*/
     //The exponent -2.236 is what we fit to DPA network of the same size
     PowerLawDRV pl(r1, -2.3,2,1000);
     DegreeLawNetFac nf(40000, pl, r1, true);
     my_net = nf.create();
		    
     //my_net = new DegreeLawRandomNetwork(nodes, *pl, r1);
     //my_net = new GnutellaNetwork(argv[1],"limecrawler");
     //my_net = new GnutellaNetwork(argv[1],"ripeanu");

     Network *net = 0;
     int choice = 2;
     if(choice == 1){
       ComponentPart cp;
       auto_ptr<NetworkPartition> netpart(cp.partition(*my_net));
       const vector<Network*>& net_set = netpart->asVector();
       cout << "The number of components of this network is: " << net_set.size() << endl;
       vector<Network*>::const_iterator comp_it;
       cout << "The components have the following sizes: ";
       for(comp_it = net_set.begin(); comp_it != net_set.end(); comp_it++){
	 net = *(comp_it);
	 cout << net->getNodeSize() << " ";
       }
       net = 0;
     }
     else{
       //The exponent -1.81 is what we want for the email network
       int nodes = 10000;
       PowerLawDRV pl(r1,-2.1,2,(int)sqrt(nodes));
       DegreeLawNetFac my_fact(nodes, pl, r1, true);
       net = my_fact.create();
     }
     cout << endl;
     //use the biggest connected component;
     IntStats ns;
     auto_ptr<NodeIterator> ni( net->getNodeIterator() );
     ns.collect(net, &Network::getDegree, ni.get());
     cout << "#nodes: " << net->getNodeSize() << endl 
          << "#edges: " << net->getEdgeSize() << endl
	  << "#<k>: " << ns.getAverage() << endl
	  << "#<k^2>: " << ns.getMoment2() << endl;
     cout << "#ttl p hit_rate edges_crossed nodes_reached" << endl;
     //Put the nodes into a vector so we can randomly select them easier:
     node_vector.clear();
     ni->reset();
     while( ni->moveNext() ) {
       node_vector.push_back( ni->current() );
     }
     
     Message* query = 0;
     Message* implant = 0;
     
     int hits;
     double last_hr = 0.0;
     double hit_rate = 0.0;
     double av_edges = 0.0;
     double av_nodes = 0.0;
     double p, delta_p = 0.01;
     int ttl=15;
     //for(ttl = 2; ttl < 12; ttl++)
     {
       p = 0.01;
       //p = 1.0;
       while(p < 0.51)
       {
	 delete query;
	 query = new WalkAndPercMessage(r2,p,ttl,ttl);
	 //query = new MagnetMessage(r2,p,ttl);
	 //query = new BroadcastMessage(ttl);
	 
	 delete implant;
	 implant = new AnycastMessage(r4,1,ttl);
	 //implant = new MagnetMessage(r2,0.75, 2 * ttl);
	 //implant = new WalkAndPercMessage(r4,p,ttl);
	 //implant = new AnycastMessage(r4,1,0);
	 
	 delete my_cnet;
	 my_cnet = new ContentNetwork(*net);
	 // Insert the content into the network
	 for(int i = 0; i < cont_count; i++) 
	 {
	     a_node = node_vector[ r3.getInt( node_vector.size() - 1 ) ];
	     c_node = content_vector[i];
	     auto_ptr<Network> implantnet( implant->visit( a_node, *net) );
	     auto_ptr<NodeIterator> nit( implantnet->getNodeIterator() );
	     my_cnet->insertContent(c_node, nit.get() );
         }
         //Do a random search for each node and see how many are successful.
         Network::NodePSet res_nodes;
         hits = 0;
      
	 int hit_nodes = 0, crossed_edges = 0;
         for(int i = 0; i < runs; i++) {
	     a_node = node_vector[ r3.getInt( node_vector.size() - 1 ) ];
	     c_node = content_vector[ i % cont_count ];
	     auto_ptr<Network> visited( query->visit(a_node, *net) );
	     auto_ptr<NodeIterator> nit( visited->getNodeIterator() );
	     auto_ptr<Network> res_nodes(
			     my_cnet->queryForContent(c_node, nit.get() ) );
	     if( res_nodes->getNodeSize() != 0) {
	       ++hits;
	     }
	     hit_nodes += visited->getNodeSize();
	     crossed_edges += visited->getEdgeSize();
         }
	 hit_rate = (double)hits/(double)runs;
	 av_edges = (double)crossed_edges/(double)runs;
	 av_nodes = (double)hit_nodes/(double)runs;
	 cout << ttl << " " << p
		     << " " << hit_rate
		     << " " << av_edges
		     << " " << av_nodes
		     << endl;
	 /* Do an adapative step:
	 delta_p = 0.00005/abs(hit_rate - last_hr);
	 if( delta_p < 0.001 ) {
           delta_p = 0.001;
	 }
	 if( delta_p > 0.1 ) {
           delta_p = 0.1;
	 }*/
	 p += delta_p;
       }
     }
     //Delete all the content
     my_cnet->deleteContent();
     delete my_cnet;
     delete my_net;
     delete net;
	
  return 1;
	
}
void DynamicProgram<T>::argmin(Parts& parts, const vector2DMat& rootv, const vector2DMat& rooti, const vectorf scales, const vector4DMat& Ix, const vector4DMat& Iy, const vector4DMat& Ik, vectorCandidate& candidates) {

	// for each scale, and each component, traverse back down the tree to retrieve the part positions
	int nscales = scales.size();
	#ifdef _OPENMP
	#pragma omp parallel for
	#endif
	for (int n = 0; n < nscales; ++n) {
		T scale = scales[n];
		for (int c = 0; c < parts.ncomponents(); ++c) {

			// get the scores and indices for this tree of parts
			const vector2DMat& Iknc = Ik[n][c];
			const vector2DMat& Ixnc = Ix[n][c];
			const vector2DMat& Iync = Iy[n][c];
			int nparts = parts.nparts(c);

			// threshold the root score
			Mat over_thresh = rootv[n][c] > thresh_;
			Mat rootmix     = rooti[n][c];
			vectorPoint inds;
			find(over_thresh, inds);

			for (int i = 0; i < inds.size(); ++i) {
				Candidate candidate;
				vectori     xv(nparts);
				vectori     yv(nparts);
				vectori     mv(nparts);
				for (int p = 0; p < nparts; ++p) {
					ComponentPart part = parts.component(c, p);
					// calculate the child's points from the parent's points
					int x, y, m;
					if (part.isRoot()) {
						x = xv[0] = inds[i].x;
						y = yv[0] = inds[i].y;
						m = mv[0] = rootmix.at<int>(inds[i]);
					} else {
						int idx = part.parent().self();
						x = xv[idx];
						y = yv[idx];
						m = mv[idx];
						xv[p] = Ixnc[p][m].at<int>(y,x);
						yv[p] = Iync[p][m].at<int>(y,x);
						mv[p] = Iknc[p][m].at<int>(y,x);
					}

					// calculate the bounding rectangle and add it to the Candidate
					Point ptwo = Point(2,2);
					Point pone = Point(1,1);
					Point xy1 = (Point(xv[p],yv[p])-ptwo)*scale;
					Point xy2 = xy1 + Point(part.xsize(m), part.ysize(m))*scale - pone;
					if (part.isRoot()) candidate.addPart(Rect(xy1, xy2), rootv[n][c].at<T>(inds[i]));
					else candidate.addPart(Rect(xy1, xy2), 0.0);
				}
				#ifdef _OPENMP
				#pragma omp critical(addcandidate)
				#endif
				{
					candidates.push_back(candidate);
				}
			}
		}
	}
}
void DynamicProgram<T>::min(Parts& parts, vector2DMat& scores, vector4DMat& Ix, vector4DMat& Iy, vector4DMat& Ik, vector2DMat& rootv, vector2DMat& rooti) {

	// initialize the outputs, preallocate vectors to make them thread safe
	// TODO: better initialisation of Ix, Iy, Ik
	const int nscales = scores.size();
	const int ncomponents = parts.ncomponents();
	Ix.resize(nscales, vector3DMat(ncomponents));
	Iy.resize(nscales, vector3DMat(ncomponents));
	Ik.resize(nscales, vector3DMat(ncomponents));
	rootv.resize(nscales, vectorMat(ncomponents));
	rooti.resize(nscales, vectorMat(ncomponents));

	// for each scale, and each component, update the scores through message passing
	#ifdef _OPENMP
	#pragma omp parallel for
	#endif
	for (int nc = 0; nc < nscales*ncomponents; ++nc) {

		// calculate the inner loop variables from the dual variables
		const int n = floor(nc / ncomponents);
		const int c = nc % ncomponents;

		// allocate the inner loop variables
		Ix[n][c].resize(parts.nparts(c));
		Iy[n][c].resize(parts.nparts(c));
		Ik[n][c].resize(parts.nparts(c));
		vectorMat ncscores(scores[n].size());

		for (int p = parts.nparts(c)-1; p > 0; --p) {

			// get the component part (which may have multiple mixtures associated with it)
			ComponentPart cpart = parts.component(c, p);
			int nmixtures       = cpart.nmixtures();
			Ix[n][c][p].resize(nmixtures);
			Iy[n][c][p].resize(nmixtures);
			Ik[n][c][p].resize(nmixtures);

			// intermediate results for mixtures of this part
			vectorMat scoresp;
			vectorMat Ixp;
			vectorMat Iyp;

			for (int m = 0; m < nmixtures; ++m) {

				// raw score outputs
				Mat score_in, score_dt, Ix_dt, Iy_dt;
				if (cpart.score(ncscores, m).empty()) {
					score_in = cpart.score(scores[n], m);
				} else {
					score_in = cpart.score(ncscores, m);
				}

				// get the anchor position
				Point anchor = cpart.anchor(m);

				// compute the distance transform
				distanceTransform(score_in, cpart.defw(m), anchor, score_dt, Ix_dt, Iy_dt);
				scoresp.push_back(score_dt);
				Ixp.push_back(Ix_dt);
				Iyp.push_back(Iy_dt);
				//cout << score_dt(Range(0,10), Range(0,10)) << endl;

				// calculate a valid region of interest for the scores
				/*
				int X = score_in.cols;
				int Y = score_in.rows;
				int xmin = std::max(std::min(anchor.x, X), 0);
				int ymin = std::max(std::min(anchor.y, Y), 0);
				int xmax = std::min(std::max(anchor.x+X, 0), X);
				int ymax = std::min(std::max(anchor.y+Y, 0), Y);
				int xoff = std::max(-anchor.x,    0);
				int yoff = std::max(-anchor.y,    0);

				// shift the score by the Part's offset from its parent
				Mat scorem = -numeric_limits<T>::infinity() * Mat::ones(score_dt.size(), score_dt.type());
				Mat Ixm    = Mat::zeros(Ix_dt.size(), Ix_dt.type());
				Mat Iym    = Mat::zeros(Iy_dt.size(), Iy_dt.type());
				if (xoff < X && yoff < Y && (ymax - ymin) > 0 && (xmax - xmin) > 0) {
					Mat score_dt_range 	= score_dt(Range(ymin, ymax),         Range(xmin, xmax));
					Mat score_range    	= scorem(Range(yoff, yoff+ymax-ymin), Range(xoff, xoff+xmax-xmin));
					Mat Ix_dt_range 	= Ix_dt(Range(ymin, ymax),            Range(xmin, xmax));
					Mat Ixm_range 		= Ixm(Range(yoff, yoff+ymax-ymin),    Range(xoff, xoff+xmax-xmin));
					Mat Iy_dt_range 	= Iy_dt(Range(ymin, ymax),            Range(xmin, xmax));
					Mat Iym_range 		= Iym(Range(yoff, yoff+ymax-ymin),    Range(xoff, xoff+xmax-xmin));
					score_dt_range.copyTo(score_range);
					Ix_dt_range.copyTo(Ixm_range);
					Iy_dt_range.copyTo(Iym_range);
				}

				// push the scores onto the intermediate vectors
				scoresp.push_back(scorem);
				Ixp.push_back(Ixm);
				Iyp.push_back(Iym);
				*/
			}

			nmixtures = cpart.parent().nmixtures();
			for (int m = 0; m < nmixtures; ++m) {
				vectorMat weighted;
				// weight each of the child scores
				// TODO: More elegant way of handling bias
				for (int mm = 0; mm < cpart.nmixtures(); ++mm) {
					weighted.push_back(scoresp[mm] + cpart.bias(mm)[m]);
				}
				// compute the max over the mixtures
				Mat maxv, maxi;
				reduceMax(weighted, maxv, maxi);

				// choose the best indices
				Mat Ixm, Iym;
				reducePickIndex<int>(Ixp, maxi, Ixm);
				reducePickIndex<int>(Iyp, maxi, Iym);
				Ix[n][c][p][m] = Ixm;
				Iy[n][c][p][m] = Iym;
				Ik[n][c][p][m] = maxi;

				// update the parent's score
				ComponentPart parent = cpart.parent();
				if (parent.score(ncscores,m).empty()) parent.score(scores[n],m).copyTo(parent.score(ncscores,m));
				parent.score(ncscores,m) += maxv;
				//cout << parent.score(ncscores,m)(Range(0,10),Range(0,10)) << endl << endl;
				if (parent.self() == 0) {
					ComponentPart root = parts.component(c);
					//cout << root.score(ncscores,m)(Range(0,10),Range(0,10)) << endl << endl;
				}
				//cout <<parent.self() << endl;
			}
		}
		// add bias to the root score and find the best mixture
		ComponentPart root = parts.component(c);
		//cout << root.self() << endl;
		Mat rncscore = root.score(ncscores,0);
		//cout << rncscore(Range(1,10),Range(1,10)) << endl;
		T bias = root.bias(0)[0];
		vectorMat weighted;
		// weight each of the child scores
		for (int m = 0; m < root.nmixtures(); ++m) {
			weighted.push_back(root.score(ncscores,m) + bias);
		}
		reduceMax(weighted, rootv[n][c], rooti[n][c]);
	}
}
Exemple #8
0
bool FileType::
parse(Context *context, plist::Dictionary const *dict, std::unordered_set<std::string> *seen, bool check)
{
    if (!Specification::parse(context, dict, seen, false))
        return false;

    auto unpack = plist::Keys::Unpack("FileType", dict, seen);

    auto MTs   = unpack.cast <plist::Array> ("MIMETypes");
    auto U     = unpack.cast <plist::String> ("UTI");
    auto Es    = unpack.cast <plist::Array> ("Extensions");
    auto TCs   = unpack.cast <plist::Array> ("TypeCodes");
    auto FPs   = unpack.cast <plist::Array> ("FilenamePatterns");
    auto MWs   = unpack.cast <plist::Array> ("MagicWord");
    auto L     = unpack.cast <plist::String> ("Language");
    auto CL    = unpack.cast <plist::String> ("ComputerLanguage");
    auto GDN   = unpack.cast <plist::String> ("GccDialectName");
    auto Ps    = unpack.cast <plist::Array> ("Prefix");
    auto P     = unpack.cast <plist::String> ("Permissions");
    auto BPIWE = unpack.cast <plist::Array> ("BuildPhaseInjectionsWhenEmbedding");
    auto ATBR  = unpack.coerce <plist::Boolean> ("AppliesToBuildRules");
    auto ITF   = unpack.coerce <plist::Boolean> ("IsTextFile");
    auto IBPF  = unpack.coerce <plist::Boolean> ("IsBuildPropertiesFile");
    auto ISC   = unpack.coerce <plist::Boolean> ("IsSourceCode");
    auto ISSC  = unpack.coerce <plist::Boolean> ("IsSwiftSourceCode");
    auto IP    = unpack.coerce <plist::Boolean> ("IsPreprocessed");
    auto IT    = unpack.coerce <plist::Boolean> ("IsTransparent");
    auto ID    = unpack.coerce <plist::Boolean> ("IsDocumentation");
    auto IEM   = unpack.coerce <plist::Boolean> ("IsEmbeddable");
    auto IE    = unpack.coerce <plist::Boolean> ("IsExecutable");
    auto IEWG  = unpack.coerce <plist::Boolean> ("IsExecutableWithGUI");
    auto IA    = unpack.coerce <plist::Boolean> ("IsApplication");
    auto IB    = unpack.coerce <plist::Boolean> ("IsBundle");
    auto IL    = unpack.coerce <plist::Boolean> ("IsLibrary");
    auto IDL   = unpack.coerce <plist::Boolean> ("IsDynamicLibrary");
    auto ISL   = unpack.coerce <plist::Boolean> ("IsStaticLibrary");
    auto IF    = unpack.coerce <plist::Boolean> ("IsFolder");
    auto IWF   = unpack.coerce <plist::Boolean> ("IsWrapperFolder");
    auto ISFI  = unpack.coerce <plist::Boolean> ("IsScannedForIncludes");
    auto IFW   = unpack.coerce <plist::Boolean> ("IsFrameworkWrapper");
    auto ISFW  = unpack.coerce <plist::Boolean> ("IsStaticFrameworkWrapper");
    auto IPW   = unpack.coerce <plist::Boolean> ("IsProjectWrapper");
    auto ITW   = unpack.coerce <plist::Boolean> ("IsTargetWrapper");
    auto EPNs  = unpack.cast <plist::Array> ("ExtraPropertyNames");
    auto CPs   = unpack.cast <plist::Dictionary> ("ComponentParts");
    auto III   = unpack.coerce <plist::Boolean> ("IncludeInIndex");
    auto CSIII = unpack.coerce <plist::Boolean> ("CanSetIncludeInIndex");
    auto RHT   = unpack.coerce <plist::Boolean> ("RequiresHardTabs");
    auto CNC   = unpack.coerce <plist::Boolean> ("ContainsNativeCode");
    auto PDS   = unpack.cast <plist::String> ("PlistStructureDefinition");
    auto CCDGI = unpack.coerce <plist::Boolean> ("ChangesCauseDependencyGraphInvalidation");
    auto FABP  = unpack.cast <plist::String> ("FallbackAutoroutingBuildPhase");
    auto CSOC  = unpack.coerce <plist::Boolean> ("CodeSignOnCopy");
    auto RHOC  = unpack.coerce <plist::Boolean> ("RemoveHeadersOnCopy");
    auto VOC   = unpack.coerce <plist::Boolean> ("ValidateOnCopy");

    if (!unpack.complete(check)) {
        fprintf(stderr, "%s", unpack.errorText().c_str());
    }

    if (U != nullptr) {
        _uti = U->value();
    }

    if (Es != nullptr) {
        _extensions = std::vector<std::string>();
        for (size_t n = 0; n < Es->count(); n++) {
            auto E = Es->value <plist::String> (n);
            if (E != nullptr) {
                _extensions->push_back(E->value());
            }
        }
    }

    if (MTs != nullptr) {
        _mimeTypes = std::vector<std::string>();
        for (size_t n = 0; n < MTs->count(); n++) {
            auto MT = MTs->value <plist::String> (n);
            if (MT != nullptr) {
                _mimeTypes->push_back(MT->value());
            }
        }
    }

    if (TCs != nullptr) {
        _typeCodes = std::vector<std::string>();
        for (size_t n = 0; n < TCs->count(); n++) {
            auto TC = TCs->value <plist::String> (n);
            if (TC != nullptr) {
                _typeCodes->push_back(TC->value());
            }
        }
    }

    if (FPs != nullptr) {
        _filenamePatterns = std::vector<std::string>();
        for (size_t n = 0; n < FPs->count(); n++) {
            auto FP = FPs->value <plist::String> (n);
            if (FP != nullptr) {
                _filenamePatterns->push_back(FP->value());
            }
        }
    }

    if (MWs != nullptr) {
        _magicWords = std::vector<std::vector<uint8_t>>();
        for (size_t n = 0; n < MWs->count(); n++) {
            if (auto MW = MWs->value <plist::String> (n)) {
                std::vector<uint8_t> MWV = std::vector<uint8_t>(MW->value().begin(), MW->value().end());
                _magicWords->push_back(MWV);
            } else if (auto MW = MWs->value <plist::Data> (n)) {
                _magicWords->push_back(MW->value());
            }
        }
    }

    if (L != nullptr) {
        _language = L->value();
    }

    if (CL != nullptr) {
        _computerLanguage = CL->value();
    }

    if (GDN != nullptr) {
        _gccDialectName = GDN->value();
    }

    if (Ps != nullptr) {
        _prefix = std::vector<std::string>();
        for (size_t n = 0; n < Ps->count(); n++) {
            auto P = Ps->value <plist::String> (n);
            if (P != nullptr) {
                _prefix->push_back(P->value());
            }
        }
    }

    if (P != nullptr) {
        _permissions = P->value();
    }

    if (BPIWE != nullptr) {
        _buildPhaseInjectionsWhenEmbedding = std::vector<BuildPhaseInjection>();
        for (size_t n = 0; n < BPIWE->count(); n++) {
            auto BPI = BPIWE->value <plist::Dictionary> (n);
            if (BPI != nullptr) {
                BuildPhaseInjection injection;
                if (injection.parse(BPI)) {
                    _buildPhaseInjectionsWhenEmbedding->push_back(injection);
                }
            }
        }
    }

    if (ATBR != nullptr) {
        _appliesToBuildRules = ATBR->value();
    }

    if (IT != nullptr) {
        _isTransparent = IT->value();
    }

    if (ID != nullptr) {
        _isDocumentation = ID->value();
    }

    if (IBPF != nullptr) {
        _isBuildPropertiesFile = IBPF->value();
    }

    if (ISC != nullptr) {
        _isSourceCode = ISC->value();
    }

    if (ISSC != nullptr) {
        _isSwiftSourceCode = ISSC->value();
    }

    if (IP != nullptr) {
        _isPreprocessed = IP->value();
    }

    if (IT != nullptr) {
        _isTransparent = IT->value();
    }

    if (IEM != nullptr) {
        _isEmbeddable = IEM->value();
    }

    if (IE != nullptr) {
        _isExecutable = IE->value();
    }

    if (IEWG != nullptr) {
        _isExecutableWithGUI = IEWG->value();
    }

    if (IA != nullptr) {
        _isApplication = IA->value();
    }

    if (IB != nullptr) {
        _isBundle = IB->value();
    }

    if (IL != nullptr) {
        _isLibrary = IL->value();
    }

    if (IDL != nullptr) {
        _isDynamicLibrary = IDL->value();
    }

    if (ISL != nullptr) {
        _isStaticLibrary = ISL->value();
    }

    if (IF != nullptr) {
        _isFolder = IF->value();
    }

    if (IWF != nullptr) {
        _isWrappedFolder = IWF->value();
    }

    if (IFW != nullptr) {
        _isFrameworkWrapper = IFW->value();
    }

    if (ISFW != nullptr) {
        _isStaticFrameworkWrapper = ISFW->value();
    }

    if (IPW != nullptr) {
        _isProjectWrapper = IPW->value();
    }

    if (ITW != nullptr) {
        _isTargetWrapper = ITW->value();
    }

    if (EPNs != nullptr) {
        _extraPropertyNames = std::vector<std::string>();
        for (size_t n = 0; n < EPNs->count(); n++) {
            auto EPN = EPNs->value <plist::String> (n);
            if (EPN != nullptr) {
                _extraPropertyNames->push_back(EPN->value());
            }
        }
    }

    if (CPs != nullptr) {
        _componentParts = std::vector<ComponentPart>();
        for (size_t n = 0; n < CPs->count(); n++) {
            auto K  = CPs->key(n);
            auto CP = CPs->value <plist::Array> (n);
            if (CP != nullptr) {
                ComponentPart cp;
                if (cp.parse(K, CP)) {
                    _componentParts->push_back(cp);
                }
            }
        }
    }

    if (ISFI != nullptr) {
        _isScannedForIncludes = ISFI->value();
    }

    if (III != nullptr) {
        _includeInIndex = III->value();
    }

    if (CSIII != nullptr) {
        _canSetIncludeInIndex = CSIII->value();
    }

    if (RHT != nullptr) {
        _requiresHardTabs = RHT->value();
    }

    if (CNC != nullptr) {
        _containsNativeCode = CNC->value();
    }

    if (PDS != nullptr) {
        _plistStructureDefinition = PDS->value();
    }

    if (CCDGI != nullptr) {
        _changesCauseDependencyGraphInvalidation = CCDGI->value();
    }

    if (FABP != nullptr) {
        _fallbackAutoroutingBuildPhase = FABP->value();
    }

    if (CSOC != nullptr) {
        _codeSignOnCopy = CSOC->value();
    }

    if (RHOC != nullptr) {
        _removeHeadersOnCopy = RHOC->value();
    }

    if (VOC != nullptr) {
        _validateOnCopy = VOC->value();
    }

    return true;
}
void DynamicProgram<T>::min(Parts& parts, vector2DMat& scores, vector4DMat& Ix, vector4DMat& Iy, vector4DMat& Ik, vector2DMat& rootv, vector2DMat& rooti) {

	// initialize the outputs, preallocate vectors to make them thread safe
	// TODO: better initialisation of Ix, Iy, Ik
	const unsigned int nscales = scores.size();
	const unsigned int ncomponents = parts.ncomponents();
	Ix.resize(nscales, vector3DMat(ncomponents));
	Iy.resize(nscales, vector3DMat(ncomponents));
	Ik.resize(nscales, vector3DMat(ncomponents));
	rootv.resize(nscales, vectorMat(ncomponents));
	rooti.resize(nscales, vectorMat(ncomponents));

	// for each scale, and each component, update the scores through message passing
	#ifdef _OPENMP
	#pragma omp parallel for
	#endif
	for (unsigned int nc = 0; nc < nscales*ncomponents; ++nc) {

		// calculate the inner loop variables from the dual variables
		const unsigned int n = floor(nc / ncomponents);
		const unsigned int c = nc % ncomponents;

		// allocate the inner loop variables
		Ix[n][c].resize(parts.nparts(c));
		Iy[n][c].resize(parts.nparts(c));
		Ik[n][c].resize(parts.nparts(c));
		vectorMat ncscores(scores[n].size());

		for (int p = parts.nparts(c)-1; p > 0; --p) {

			// get the component part (which may have multiple mixtures associated with it)
			ComponentPart cpart = parts.component(c, p);
			const unsigned int nmixtures  = cpart.nmixtures();
			const unsigned int pnmixtures = cpart.parent().nmixtures();
			Ix[n][c][p].resize(pnmixtures);
			Iy[n][c][p].resize(pnmixtures);
			Ik[n][c][p].resize(pnmixtures);

			// intermediate results for mixtures of this part
			vectorMat scoresp;
			vectorMat Ixp;
			vectorMat Iyp;

			for (unsigned int m = 0; m < nmixtures; ++m) {

				// raw score outputs
				Mat_<T> score_in, score_dt;
				Mat_<int> Ix_dt, Iy_dt;
				if (cpart.score(ncscores, m).empty()) {
					score_in = cpart.score(scores[n], m);
				} else {
					score_in = cpart.score(ncscores, m);
				}

				// get the anchor position
				Point anchor = cpart.anchor(m);

				// compute the distance transform
				vectorf w = cpart.defw(m);
				Quadratic fx(-w[0], -w[1]);
				Quadratic fy(-w[2], -w[3]);
				dt_.compute(score_in, fx, fy, anchor, score_dt, Ix_dt, Iy_dt);
				scoresp.push_back(score_dt);
				Ixp.push_back(Ix_dt);
				Iyp.push_back(Iy_dt);
			}

			for (unsigned int m = 0; m < pnmixtures; ++m) {
				vectorMat weighted;
				// weight each of the child scores
				// TODO: More elegant way of handling bias
				for (unsigned int mm = 0; mm < nmixtures; ++mm) {
					weighted.push_back(scoresp[mm] + cpart.bias(mm)[m]);
				}
				// compute the max over the mixtures
				Mat maxv, maxi;
				Math::reduceMax<T>(weighted, maxv, maxi);

				// choose the best indices
				Mat Ixm, Iym;
				Math::reducePickIndex<int>(Ixp, maxi, Ixm);
				Math::reducePickIndex<int>(Iyp, maxi, Iym);
				Ix[n][c][p][m] = Ixm;
				Iy[n][c][p][m] = Iym;
				Ik[n][c][p][m] = maxi;

				// update the parent's score
				ComponentPart parent = cpart.parent();
				if (parent.score(ncscores,m).empty()) parent.score(scores[n],m).copyTo(parent.score(ncscores,m));
				parent.score(ncscores,m) += maxv;
				if (parent.self() == 0) {
					ComponentPart root = parts.component(c);
				}
			}
		}
		// add bias to the root score and find the best mixture
		ComponentPart root = parts.component(c);
		Mat rncscore = root.score(ncscores,0);
		T bias = root.bias(0)[0];
		vectorMat weighted;
		// weight each of the child scores
		for (unsigned int m = 0; m < root.nmixtures(); ++m) {
			weighted.push_back(root.score(ncscores,m) + bias);
		}
		Math::reduceMax<T>(weighted, rootv[n][c], rooti[n][c]);
	}
}