コード例 #1
0
ファイル: graph_kmerify.cpp プロジェクト: gyper/gyper
void
checkKmers(DnaString const & kmer,
           TVertexDescriptor const & starting_vertex,
           TVertexDescriptor const & source_vertex,
           TGraph const & graph,
           std::vector<VertexLabels> & vertex_vector,
           boost::unordered_set<TVertexDescriptor> const & free_nodes,
           boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
           boost::dynamic_bitset<> const & id_bits,
           TKmerMap & kmer_map,
           std::size_t const & kmer_size
          )
{
  if (id_bits.none())
    return;

  if (length(kmer) == kmer_size)
  {
    KmerLabels new_kmer_label =
    {
      starting_vertex,
      source_vertex,
      id_bits
    };

    if (kmer_map.count(kmer) == 0)
    {
      std::vector<KmerLabels> new_vector(1, new_kmer_label);
      kmer_map[kmer] = new_vector;
    }
    else
    {
      kmer_map[kmer].push_back(new_kmer_label);
    }

    return;
  }

  for (Iterator<TGraph, OutEdgeIterator>::Type out_edge_iterator (graph, source_vertex) ; !atEnd(out_edge_iterator) ; ++out_edge_iterator)
  {
    DnaString new_kmer(kmer);
    TVertexDescriptor const & target_vertex = targetVertex(out_edge_iterator);
    boost::dynamic_bitset<> new_id_bits(id_bits);

    if (free_nodes.count(target_vertex) == 0)
    {
      seqan::appendValue(new_kmer, vertex_vector[target_vertex].dna);
      std::pair<TVertexDescriptor, TVertexDescriptor> edge_pair(source_vertex, target_vertex);
      
      if (edge_ids.count(edge_pair) == 1)
      {
        new_id_bits = id_bits & edge_ids[edge_pair];
      }
    }

    checkKmers(new_kmer, starting_vertex, target_vertex, graph, vertex_vector, free_nodes, edge_ids, new_id_bits, kmer_map, kmer_size);
  }
}
コード例 #2
0
ファイル: graph_kmerify.cpp プロジェクト: gyper/gyper
void
check_kmers_simple(DnaString const & kmer,
                   TGraph const & graph,
                   TVertexDescriptor const & source_vertex,
                   std::vector<VertexLabels> & vertex_vector,
                   boost::unordered_set<TVertexDescriptor> const & free_nodes,
                   boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
                   boost::dynamic_bitset<> const & id_bits,
                   TKmerMapSimple & kmer_map,
                   std::size_t const & kmer_size
                  )
{
  if (id_bits.none())
    return;

  if (length(kmer) == kmer_size)
  {
    if (id_bits.all())
      return;

    if (kmer_map.count(kmer) == 0)
    {
      kmer_map[kmer] = id_bits;
    }
    else
    {
      kmer_map[kmer] |= id_bits;
    }

    return;
  }

  for (Iterator<TGraph, OutEdgeIterator>::Type out_edge_iterator (graph, source_vertex) ; !atEnd(out_edge_iterator) ; ++out_edge_iterator)
  {
    DnaString new_kmer(kmer);
    TVertexDescriptor const & target_vertex = targetVertex(out_edge_iterator);

    // std::cout << source_vertex << " -> " << target_vertex << std::endl;

    boost::dynamic_bitset<> new_id_bits(id_bits);

    if (free_nodes.count(target_vertex) == 0)
    {
      seqan::appendValue(new_kmer, vertex_vector[target_vertex].dna);
      std::pair<TVertexDescriptor, TVertexDescriptor> edge_pair(source_vertex, target_vertex);
      
      if (edge_ids.count(edge_pair) == 1)
      {
        new_id_bits = id_bits & edge_ids[edge_pair];
      }
    }

    check_kmers_simple(new_kmer, graph, target_vertex, vertex_vector, free_nodes, edge_ids, new_id_bits, kmer_map, kmer_size);
  }
}
コード例 #3
0
ファイル: divide_and_conquer.cpp プロジェクト: axiao/delaunay
edge_pair delaunay_dc2(vertex v[], size_t n, bool div_by_x, vertex_buffer p) {
    edge_pair ldo_ldi, rdi_rdo;
    edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp;
    vertex *v_l, *v_r;
    size_t median, v_l_n, v_r_n;
    bool lcand_valid, rcand_valid;

    if (n == 2) { 
        // for two vertices, return the two directed edges between them
        if (point_lte(p.val(v[0]), p.val(v[1]), div_by_x)) {
            a = make_edge(v[0], v[1]);
        } else {
            a = make_edge(v[1], v[0]);
        }
        return edge_pair(a, a.sym());

    } else if (n == 3) {
        // for three vertices
        a = make_edge();
        b = make_edge();
        splice(a.sym(), b);

        // order the vertices on the right axis
        bool zero_lte_one = point_lte(p.val(v[0]), p.val(v[1]), div_by_x);
        bool one_lte_two = point_lte(p.val(v[1]), p.val(v[2]), div_by_x);
        bool two_lte_zero = point_lte(p.val(v[2]), p.val(v[0]), div_by_x);
        vertex first, second, third;
        if (zero_lte_one) {
            if (one_lte_two) {
                first = v[0]; 
                second = v[1]; 
                third = v[2];
            } else {
                if (two_lte_zero) {
                    first = v[2];
                    second = v[0];
                    third = v[1];
                } else {
                    first = v[0];
                    second = v[2];
                    third = v[1];
                }
            }
        } else {
            if (one_lte_two) {
                if (two_lte_zero) {
                    first = v[1];
                    second = v[2];
                    third = v[0];
                } else {
                    first = v[1];
                    second = v[0];
                    third = v[2];
                }
            } else {
                first = v[2];
                second = v[1];
                third = v[0];
            }
        }
        a.set_org(first);
        a.set_dst(second);
        b.set_org(second);
        b.set_dst(third);
        if (p.orient2d(first, second, third) > 0) {
            c = connect(b, a);
            return edge_pair(a, b.sym());
        } else if (p.orient2d(first, third, second) > 0) {
            c = connect(b, a);
            return edge_pair(c.sym(), c);
        } else { // the points are collinear
            return edge_pair(a, b.sym());
        }

    } else { // n >= 4
        // div_by_x tells whether this recursive case is splitting by x
        // divide v into left half v_l, right half v_r
        median = lexico_partition(v, n, div_by_x, p);
        v_l = v;
        v_l_n = median + 1; // +1 ensures that the lower partition has >=2
        v_r = (v + v_l_n);
        v_r_n = (n - v_l_n);


        // recursive calls split in opposite axis; *do and *di are flipped!
        // must merge on the current axis, however
        ldo_ldi = delaunay_dc2(v_l, v_l_n, !div_by_x, p);
        ldo = ldo_ldi[0]; // ccw, so right face is open
        ldi = ldo_ldi[1]; // cw, so left face is open
        rdi_rdo = delaunay_dc2(v_r, v_r_n, !div_by_x, p);
        rdi = rdi_rdo[0]; // ccw, so right face is open
        rdo = rdi_rdo[1]; // cw, so left face is open

        // move *di, *do into the correct "leftmost", "rightmost" for level
        if (div_by_x) {
            while (point_lte(p.val(ldo.rprev().org()), p.val(ldo.org()), 
                    div_by_x)) {
                ldo = ldo.rprev();
            }
            while (point_lte(p.val(ldi.org()), p.val(ldi.lnext().org()), 
                    div_by_x)) {
                ldi = ldi.lnext();
            }
            while (point_lte(p.val(rdi.rprev().org()), p.val(rdi.org()), 
                    div_by_x)) {
                rdi = rdi.rprev();
            }
            while (point_lte(p.val(rdo.org()), p.val(rdo.lnext().org()), 
                    div_by_x)) {
                rdo = rdo.lnext();
            }
        } else {
            while (point_lte(p.val(ldo.rnext().org()), p.val(ldo.org()), 
                    div_by_x)) {
                ldo = ldo.rnext();
            }
            while (point_lte(p.val(ldi.org()), p.val(ldi.lprev().org()), 
                    div_by_x)) {
                ldi = ldi.lprev();
            }
            while (point_lte(p.val(rdi.rnext().org()), p.val(rdi.org()), 
                    div_by_x)) {
                rdi = rdi.rnext();
            }
            while (point_lte(p.val(rdo.org()), p.val(rdo.lprev().org()), 
                    div_by_x)) {
                rdo = rdo.lprev();
            }
        }

        // loop to compute lower common tangent of l and r
        while (true) {
            if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) {
                ldi = ldi.lnext();
            } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) {
                //rdi = rdi.rprev(); // Guibas and Stolfi wrong here?
                rdi = rdi.rnext();
            } else {
                break;
            }
        }

        // create the first cross edge basel from rdi.org to ldi.org
        basel = connect(rdi.sym(), ldi);
        if (ldi.org() == ldo.org()) {
            ldo = basel.sym();
        }
        if (rdi.org() == rdo.org()) {
            rdo = basel;
        }

        // merge loop
        while (true) {
            // is lcand valid?
            lcand = basel.sym().onext();
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            if (lcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) {
                    temp = lcand.onext();
                    delete_edge(lcand);
                    lcand = temp;
                }
            }
            // is rcand valid?
            rcand = basel.oprev();
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            if (rcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) {
                    temp = rcand.oprev();
                    delete_edge(rcand);
                    rcand = temp;
                }
            }
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            // if both lcand and rcand are invalid, 
            // then basel is the upper common tangent
            // ... break out of merge loop
            if ((not lcand_valid) and (not rcand_valid)) {
                break;
            }

            // the next cross edge is to be connected to either 
            // lcand.dst() or rcand.dst() 
            // if both valid, choose the appropriate one using incircle test
            if ((not lcand_valid) or ((rcand_valid and 
                (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) {
                // add cross edge basel from rcand.dst() to basel.dst()
                basel = connect(rcand, basel.sym());
            } else {
                // add cross edge basel from basel.org() to lcand.dst()
                basel = connect(basel.sym(), lcand.sym());
            }
        }

        return edge_pair(ldo, rdo);
    }
}
コード例 #4
0
ファイル: divide_and_conquer.cpp プロジェクト: axiao/delaunay
// outputs the edge_pair (le, re)
// le: counterclockwise convex hull edge out of the leftmost vertex
// re: clockwise convex hull edge out of the rightmost vertex
edge_pair delaunay_dc(vertex v[], size_t n, vertex_buffer p) {
    // assumes that v is sorted in lexicographic order
    edge_pair ldo_ldi, rdi_rdo;
    edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp;
    vertex *v_l, *v_r;
    size_t v_l_n, v_r_n;
    bool lcand_valid, rcand_valid;

    if (n == 2) { 
        // for two vertices, return the two directed edges between them
        a = make_edge(v[0], v[1]);
        return edge_pair(a, a.sym());

    } else if (n == 3) {
        // for three vertices
        a = make_edge();
        b = make_edge();
        splice(a.sym(), b);
        a.set_org(v[0]);
        a.set_dst(v[1]);
        b.set_org(v[1]);
        b.set_dst(v[2]);
        if (p.orient2d(v[0], v[1], v[2]) > 0) {
            c = connect(b, a);
            return edge_pair(a, b.sym());
        } else if (p.orient2d(v[0], v[2], v[1]) > 0) {
            c = connect(b, a);
            return edge_pair(c.sym(), c);
        } else { // the points are collinear
            return edge_pair(a, b.sym());
        }

    } else { // n >= 4
        // divide v into left half v_l, right half v_r
        v_l = v;
        v_l_n = n/2;
        v_r = (v + v_l_n);
        v_r_n = (n - v_l_n);

        ldo_ldi = delaunay_dc(v_l, v_l_n, p);
        ldo = ldo_ldi[0];
        ldi = ldo_ldi[1];
        rdi_rdo = delaunay_dc(v_r, v_r_n, p);
        rdi = rdi_rdo[0];
        rdo = rdi_rdo[1];

        // loop to compute lower common tangent of l and r
        while (true) {
            if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) {
                ldi = ldi.lnext();
            } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) {
                //rdi = rdi.rprev(); // Guibas and Stolfi wrong here?
                rdi = rdi.rnext();
            } else {
                break;
            }
        }

        // create the first cross edge basel from rdi.org to ldi.org
        basel = connect(rdi.sym(), ldi);
        if (ldi.org() == ldo.org()) {
            ldo = basel.sym();
        }
        if (rdi.org() == rdo.org()) {
            rdo = basel;
        }

        // merge loop
        while (true) {
            // is lcand valid?
            lcand = basel.sym().onext();
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            if (lcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) {
                    temp = lcand.onext();
                    delete_edge(lcand);
                    lcand = temp;
                }
            }
            // is rcand valid?
            rcand = basel.oprev();
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            if (rcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) {
                    temp = rcand.oprev();
                    delete_edge(rcand);
                    rcand = temp;
                }
            }

            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            // if both lcand and rcand are invalid, 
            // then basel is the upper common tangent
            // ... break out of merge loop
            if ((not lcand_valid) and (not rcand_valid)) {
                break;
            }

            // the next cross edge is to be connected to either 
            // lcand.dst() or rcand.dst() 
            // if both valid, choose the appropriate one using incircle test
            if ((not lcand_valid) or ((rcand_valid and 
                (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) {
                // add cross edge basel from rcand.dst() to basel.dst()
                basel = connect(rcand, basel.sym());
            } else {
                // add cross edge basel from basel.org() to lcand.dst()
                basel = connect(basel.sym(), lcand.sym());
            }
        }

        return edge_pair(ldo, rdo);
    }
}