multimap<double, int> SOINN::getSortedDistancesNodeNumbers(const Node &input_node, vector<Node> &compared_nodes) { // 距離でソートされたノード番号のセット multimap<double, int> node_distances; vector<Node>::iterator it = compared_nodes.begin(); while(it != compared_nodes.end()) { double d = getNodeDistance((*it), input_node); node_distances.insert(pair<double, int>(d, it->id)); ++it; } return node_distances; }
double SOINN::getSimularThreshold(const Node &target_node) { // target_nodeの類似度閾値を計算 // 連結ノードがある場合は if(soinn.getEdgeCount(target_node.id) != 0) { // 連結ノード集合 vector<Node> related_nodes = soinn.getRealtedNodes(target_node.id); // 連結ノード集合のうち最も遠いノードまでの距離を返す if(related_nodes.size() == 1) { return getNodeDistance(related_nodes.at(0), target_node); } else { multimap<double, int> node_distances = getSortedDistancesNodeNumbers(target_node, related_nodes); return (*node_distances.end()).first; } } // 連結ノードがない場合は else { // target_node以外のノードの集合 vector<Node> nodes = soinn.getAllNodes(); vector<Node> except_nodes; for(int i = 0; i < (int)nodes.size(); ++i) { Node n = nodes.at(i); if(n.id != target_node.id) { except_nodes.push_back(n); } } // target_node以外のノードのうち最も近いノードまでの距離を返す multimap<double, int> node_distances = getSortedDistancesNodeNumbers(target_node, except_nodes); return (*node_distances.begin()).first; } }
void way ( osmium::Way& way ) { const char* highway = way.tags() ["highway"]; if ( !highway ) return; // http://wiki.openstreetmap.org/wiki/Key:highway if ( !strcmp ( highway, "footway" ) || !strcmp ( highway, "cycleway" ) || !strcmp ( highway, "bridleway" ) || !strcmp ( highway, "steps" ) || !strcmp ( highway, "pedestrian") || !strcmp ( highway, "construction" ) ) return; double dist = getNodeDistance(way); //inicializáljuk a sebességét az utaknak, amit egy külön függvényben // std::cout<<speed; //írtunk meg,hogy melyik úthoz milyen sebesség tartozik. onewayf = false; const char* oneway = way.tags() ["oneway"]; if ( oneway ) { onewayf = true; ++onewayc; //oneway counter } ++nOSM_ways; double way_length = osmium::geom::haversine::distance ( way.nodes() ); sum_highhway_length += way_length; int node_counter {0}; int unique_node_counter {0}; osmium::Location from_loc; osmium::unsigned_object_id_type vertex_old; for ( const osmium::NodeRef& nr : way.nodes() ) { osmium::unsigned_object_id_type vertex = nr.positive_ref(); //Get absolute value of the reference ID of this NodeRef. way2nodes[way.id()].push_back ( vertex ); //Get ID of this object with way.id() and push the actual vertex to their vector try { vert.get ( vertex ); //Retrieve value by id. Does not check for overflow or empty fields. } catch ( std::exception& e ) { vert.set ( vertex, 1 ); //Set the field with id to value. ++unique_node_counter; //waynode_locations.set ( vertex, nr.location() ); waynode_locations[vertex] = nr.location(); //Get location of this NodeRef. } if ( node_counter > 0 ) { if ( !edge ( vertex_old, vertex ) ) { alist[vertex_old].push_back ( vertex ); double edge_length = distance ( vertex_old, vertex ); palist[vertex_old].push_back ( edge_length / dist ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; if ( !onewayf ) { if ( !edge ( vertex, vertex_old ) ) { alist[vertex].push_back ( vertex_old ); // double edge_length = distance ( vertex_old, vertex ); palist[vertex].push_back ( edge_length / dist ); if ( edge_length>max_edge_length ) max_edge_length = edge_length; mean_edge_length += edge_length; ++m_estimator; ++cedges; } else ++edge_multiplicity; } } vertex_old = vertex; ++node_counter; } sum_highhway_nodes += node_counter; sum_unique_highhway_nodes += unique_node_counter; }
void SOINN::learn(vector<Node> inputs) { input_nodes = inputs; initialize(); // 入力パターンを学習 for(int i = 0; i < (int)input_nodes.size(); ++i) { Node input = input_nodes.at(i); // 勝者ノードを探す vector<Node> winner_nodes = getWinnerNodes(input); Node first_winner = winner_nodes.at(0); // 勝者ノード Node second_winner = winner_nodes.at(1); // 第二勝者ノード double first_simular = getSimularThreshold(first_winner); double second_simular = getSimularThreshold(second_winner); double input_first_dist = getNodeDistance(input, first_winner); double input_second_dist = getNodeDistance(input, second_winner); // 勝者ノードもしくは第二勝者ノードの類似度閾値の外側なら if(input_first_dist > first_simular || input_second_dist > second_simular) { // 新規ノードとして追加 soinn.addNode(input.position); } // 勝者・第二勝者ノードいずれかの類似度閾値の内側の場合 if(input_first_dist <= first_simular && input_second_dist <= second_simular) { // 勝者ノードと第二勝者ノードの間にエッジが無いなら if(!soinn.hasEdge(first_winner.id, second_winner.id)) { // エッジを追加 soinn.addEdge(first_winner.id, second_winner.id); } // エッジの年齢を0にリセット setEdgeAge(first_winner.id, second_winner.id, 0); // 勝者ノードにつながる全エッジの年齢をインクリメント incAllEdgeAge(first_winner.id); // 位置ベクトルの更新 updatePosition(first_winner, input, 1.0, first_winner.win_times); // 勝者ノードの関連ノードの位置ベクトルの更新 updatePositionRelated(first_winner, input, 1.0 / 100.0); // 年老いたエッジを削除 eraseOldEdges(); // 消されたエッジでつながれていたノードを調べる for(int j = 0; j < (int)erased_edges.size(); ++j) { Edge e = erased_edges.at(j); // 関連ノードがなければ削除 eraseIndependentNode(e.node_ids.first); eraseIndependentNode(e.node_ids.second); } } // 入力パターン数がnode_erase_ageの倍数 if((i + 1) % node_erase_age == 0 || (i + 1) == (int)input_nodes.size()) { eraseNoizyNode(); } } drawGraph(); }
void computePlacementBias(tree *tr, analdef *adef) { int windowSize = adef->slidingWindowSize, k, i, tips, numTraversalBranches = (2 * (tr->mxtips - 1)) - 3; /* compute number of branches into which we need to insert once we have removed a taxon */ char fileName[1024]; FILE *outFile; /* data for each sliding window starting position */ positionData *pd = (positionData *)malloc(sizeof(positionData) * (tr->cdta->endsite - windowSize)); double *nodeDistances = (double*)calloc(tr->cdta->endsite, sizeof(double)), /* array to store node distnces ND for every sliding window position */ *distances = (double*)calloc(tr->cdta->endsite, sizeof(double)); /* array to store avg distances for every site */ strcpy(fileName, workdir); strcat(fileName, "RAxML_SiteSpecificPlacementBias."); strcat(fileName, run_id); outFile = myfopen(fileName, "w"); printBothOpen("Likelihood of comprehensive tree %f\n\n", tr->likelihood); if(windowSize > tr->cdta->endsite) { printBothOpen("The size of your sliding window is %d while the number of sites in the alignment is %d\n\n", windowSize, tr->cdta->endsite); exit(-1); } if(windowSize >= (int)(0.9 * tr->cdta->endsite)) printBothOpen("WARNING: your sliding window of size %d is only slightly smaller than you alignment that has %d sites\n\n", windowSize, tr->cdta->endsite); printBothOpen("Sliding window size: %d\n\n", windowSize); /* prune and re-insert on tip at a time into all branches of the remaining tree */ for(tips = 1; tips <= tr->mxtips; tips++) { nodeptr myStart, p = tr->nodep[tips]->back, /* this is the node at which we are prunung */ p1 = p->next->back, p2 = p->next->next->back; double pz[NUM_BRANCHES], p1z[NUM_BRANCHES], p2z[NUM_BRANCHES]; int branchCounter = 0; /* reset array values for this tip */ for(i = 0; i < tr->cdta->endsite; i++) { pd[i].lh = unlikely; pd[i].p = (nodeptr)NULL; } /* store the three branch lengths adjacent to the position at which we prune */ for(i = 0; i < tr->numBranches; i++) { p1z[i] = p1->z[i]; p2z[i] = p2->z[i]; pz[i] = p->z[i]; } /* prune the taxon, optimizing the branch between p1 and p2 */ removeNodeBIG(tr, p, tr->numBranches); printBothOpen("Pruning taxon Number %d [%s]\n", tips, tr->nameList[tips]); /* find any tip to start traversing the tree */ myStart = findAnyTip(p1, tr->mxtips); /* insert taxon, compute likelihood and remove taxon again from all branches */ traverseBias(p, myStart->back, tr, &branchCounter, pd, windowSize); assert(branchCounter == numTraversalBranches); /* for every sliding window position calc ND to the true/correct position at p */ for(i = 0; i < tr->cdta->endsite - windowSize; i++) nodeDistances[i] = getNodeDistance(p1, pd[i].p, tr->mxtips); /* now analyze */ for(i = 0; i < tr->cdta->endsite; i++) { double d = 0.0; int s = 0; /* check site position, i.e., doe we have windowSize data points available or fewer because we are at the start or the end of the alignment */ /* for each site just accumulate the node distances we have for all sliding windows that passed over this site */ if(i < windowSize) { for(k = 0; k < i + 1; k++, s++) d += nodeDistances[k]; } else { if(i < tr->cdta->endsite - windowSize) { for(k = i - windowSize + 1; k <= i; k++, s++) d += nodeDistances[k]; } else { for(k = i - windowSize; k < (tr->cdta->endsite - windowSize); k++, s++) d += nodeDistances[k + 1]; } } /* now just divide the accumultaed ND distance by the number of distances we have for this position and then add it to the acc distances over all taxa. I just realized that the version on which I did the tests I sent to Simon I used distances[i] = d / ((double)s); instead of distances[i] += d / ((double)s); gamo tin poutana mou */ distances[i] += (d / ((double)s)); } /* re-connect taxon to its original position */ hookup(p->next, p1, p1z, tr->numBranches); hookup(p->next->next, p2, p2z, tr->numBranches); hookup(p, p->back, pz, tr->numBranches); /* fix likelihood vectors */ newviewGeneric(tr, p); } /* now just compute the average ND over all taxa */ for(i = 0; i < tr->cdta->endsite; i++) { double avg = distances[i] / ((double)tr->mxtips); fprintf(outFile, "%d %f\n", i, avg); } printBothOpen("\nTime for EPA-based site-specific placement bias calculation: %f\n", gettime() - masterTime); printBothOpen("Site-specific placement bias statistics written to file %s\n", fileName); fclose(outFile); exit(0); }