NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bidir_inl.h
Go to the documentation of this file.
1 /*
2  * nvbio
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 
30 namespace nvbio {
31 
32 // \relates fm_index
33 // forward extension using a bidirectional FM-index, extending the range
34 // of a pattern P to the pattern Pc
35 //
36 // \param f_fmi forward FM-index
37 // \param r_fmi reverse FM-index
38 // \param f_range current forward range
39 // \param r_range current reverse range
40 // \param c query character
41 //
42 template <
43  typename TRankDictionary1,
44  typename TSuffixArray1,
45  typename TRankDictionary2,
46  typename TSuffixArray2>
53  uint8 c)
54 {
55  typedef typename fm_index<TRankDictionary1,TSuffixArray1>::range_type f_range_type;
56  typedef typename fm_index<TRankDictionary2,TSuffixArray2>::range_type r_range_type;
57 
58  // find the number of suffixes in T that start with Pd, for d < c
59  uint32 x = 0;
60  for (uint32 d = 0; d < c; ++d)
61  {
62  // search for (Pd)^R = dP^R in r_fmi
63  const r_range_type d_rank = rank(
64  r_fmi,
65  make_vector( r_range.x-1, r_range.y ),
66  d );
67 
68  // add the number of occurrences to x
69  x += d_rank.y - d_rank.x;
70  }
71 
72  // search for (Pc)^R = cP^R in r_fmi
73  {
74  const r_range_type c_rank = rank(
75  r_fmi,
76  make_vector( r_range.x-1, r_range.y ),
77  c );
78 
79  r_range.x = r_fmi.L2(c) + c_rank.x + 1;
80  r_range.y = r_fmi.L2(c) + c_rank.y;
81  }
82  const uint32 y = 1u + r_range.y - r_range.x;
83 
84  // and now compute the new forward range of Pc
85  f_range.y = f_range.x + x + y - 1u;
86  f_range.x = f_range.x + x;
87 }
88 
89 // \relates fm_index
90 // backwards extension using a bidirectional FM-index, extending the range
91 // of a pattern P to the pattern cP
92 //
93 // \param f_fmi forward FM-index
94 // \param r_fmi reverse FM-index
95 // \param f_range current forward range
96 // \param r_range current reverse range
97 // \param c query character
98 //
99 template <
100  typename TRankDictionary1,
101  typename TSuffixArray1,
102  typename TRankDictionary2,
103  typename TSuffixArray2>
110  uint8 c)
111 {
112  typedef typename fm_index<TRankDictionary1,TSuffixArray1>::range_type f_range_type;
113  typedef typename fm_index<TRankDictionary2,TSuffixArray2>::range_type r_range_type;
114 
115  // find the number of suffixes in T that start with dP, for d < c
116  uint32 x = 0;
117  for (uint32 d = 0; d < c; ++d)
118  {
119  // search for dP in f_fmi
120  const f_range_type d_rank = rank(
121  f_fmi,
122  make_vector( f_range.x-1, f_range.y ),
123  d );
124 
125  // add the number of occurrences to x
126  x += d_rank.y - d_rank.x;
127  }
128 
129  // search for cP in f_fmi
130  {
131  const f_range_type c_rank = rank(
132  f_fmi,
133  make_vector( f_range.x-1, f_range.y ),
134  c );
135 
136  f_range.x = f_fmi.L2(c) + c_rank.x + 1;
137  f_range.y = f_fmi.L2(c) + c_rank.y;
138  }
139  const uint32 y = 1u + f_range.y - f_range.x;
140 
141  // and now compute the new reverse range of cP
142  r_range.y = r_range.x + x + y - 1u;
143  r_range.x = r_range.x + x;
144 }
145 
146 } // namespace nvbio