A toolkit for working with phylogenetic data.
v0.20.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
utils/math/bitvector/operators.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
33 #include <iostream>
34 #include <string>
35 
36 namespace genesis {
37 namespace utils {
38 
39 // =================================================================================================
40 // Bitvector Operators
41 // =================================================================================================
42 
43 Bitvector operator & (Bitvector const& lhs, Bitvector const& rhs)
44 {
45  // make a copy.
46  Bitvector result = Bitvector(lhs);
47 
48  // check for self-and.
49  if (&lhs == &rhs) {
50  return result;
51  }
52 
53  // if not, return and with right hand side.
54  result &= rhs;
55  return result;
56 }
57 
58 Bitvector operator | (Bitvector const& lhs, Bitvector const& rhs)
59 {
60  // make a copy.
61  Bitvector result = Bitvector(lhs);
62 
63  // check for self-or.
64  if (&lhs == &rhs) {
65  return result;
66  }
67 
68  // if not, return or with right hand side.
69  result |= rhs;
70  return result;
71 }
72 
73 Bitvector operator ^ (Bitvector const& lhs, Bitvector const& rhs)
74 {
75  // check for self-xor. if so, return zero vector of same size.
76  if (&lhs == &rhs) {
77  return Bitvector(lhs.size(), false);
78  }
79 
80  // otherwise, make a copy and xor it.
81  Bitvector result = Bitvector(lhs);
82  result ^= rhs;
83  return result;
84 }
85 
86 Bitvector bitwise_and (Bitvector const& lhs, Bitvector const& rhs)
87 {
88  if( lhs.size() < rhs.size() ) {
89  auto result = Bitvector( rhs, lhs.size() );
90  result &= lhs;
91  return result;
92  } else {
93  auto result = Bitvector( lhs, rhs.size() );
94  result &= rhs;
95  return result;
96  }
97 }
98 
99 Bitvector bitwise_or (Bitvector const& lhs, Bitvector const& rhs)
100 {
101  if( lhs.size() < rhs.size() ) {
102  auto result = Bitvector( rhs, lhs.size() );
103  result |= lhs;
104  return result;
105  } else {
106  auto result = Bitvector( lhs, rhs.size() );
107  result |= rhs;
108  return result;
109  }
110 }
111 
112 Bitvector bitwise_xor (Bitvector const& lhs, Bitvector const& rhs)
113 {
114  if( lhs.size() < rhs.size() ) {
115  auto result = Bitvector( rhs, lhs.size() );
116  result ^= lhs;
117  return result;
118  } else {
119  auto result = Bitvector( lhs, rhs.size() );
120  result ^= rhs;
121  return result;
122  }
123 }
124 
125 Bitvector set_minus (Bitvector const& lhs, Bitvector const& rhs)
126 {
127  return lhs & (~rhs);
128 }
129 
131 {
132  return (lhs | rhs) & ~(lhs & rhs);
133 }
134 
135 bool is_strict_subset( Bitvector const& sub, Bitvector const& super )
136 {
137  return ((sub & super) == sub) && (sub.count() < super.count());
138 }
139 
140 bool is_strict_superset( Bitvector const& super, Bitvector const& sub )
141 {
142  return is_strict_subset( sub, super );
143 }
144 
145 bool is_subset( Bitvector const& sub, Bitvector const& super )
146 {
147  return (sub == super) || is_strict_subset(sub, super);
148 }
149 
150 bool is_superset( Bitvector const& super, Bitvector const& sub )
151 {
152  return (super == sub) || is_strict_superset(super, sub);
153 }
154 
155 std::ostream& operator << (std::ostream& s, Bitvector const& bv)
156 {
157  for(size_t i = 0; i < bv.size() ; ++i) {
158  s << (bv.get(i) ? "1" : "0");
159  }
160  return s;
161 }
162 
163 std::istream& operator >> ( std::istream& in, Bitvector& bv )
164 {
165  // We need two steps, as we have to construct the bitvector with a known size.
166  // First, bring the bits into string form...
167  std::string str;
168  auto c = in.peek();
169  while( c == '0' || c == '1' ) {
170  str += c;
171  (void) in.get();
172  c = in.peek();
173  }
174 
175  // ... then, create the bitvector.
176  bv = Bitvector( str.size() );
177  for( size_t i = 0; i < str.size(); ++i ) {
178  if( str[i] == '1' ) {
179  bv.set(i);
180  }
181  }
182  return in;
183 }
184 
185 } // namespace utils
186 } // namespace genesis
size_t size() const
Return the size (number of bits) of this Bitvector.
Definition: bitvector.hpp:200
size_t count() const
Count the number of set bits in the Bitvector, that is, its Hamming weight.
Definition: bitvector.cpp:174
Bitvector bitwise_or(Bitvector const &lhs, Bitvector const &rhs)
Take the bitwise or of two Bitvectors of potentially different size.
bool is_superset(Bitvector const &super, Bitvector const &sub)
Superset or equal.
std::istream & operator>>(std::istream &in, Bitvector &bv)
Extraction operator that inputs a Bitvector from a string of '0's and '1's, and stops at the first ch...
bool is_strict_superset(Bitvector const &super, Bitvector const &sub)
Strict superset.
bool operator&(SkipWhitespace lhs, SkipWhitespace rhs)
And-operator to check whether a SkipWhitespace is set.
Definition: scanner.hpp:95
Bitvector operator|(Bitvector const &lhs, Bitvector const &rhs)
void set(size_t index)
Set the value of a single bit to true, with boundary check.
Definition: bitvector.hpp:139
Bitvector symmetric_difference(Bitvector const &lhs, Bitvector const &rhs)
Bitvector operator^(Bitvector const &lhs, Bitvector const &rhs)
Bitvector bitwise_and(Bitvector const &lhs, Bitvector const &rhs)
Take the bitwise and of two Bitvectors of potentially different size.
std::ostream & operator<<(std::ostream &os, const Matrix< T > &matrix)
Print the elements of a Matrix to a stream, using operator << for each element.
bool is_strict_subset(Bitvector const &sub, Bitvector const &super)
Strict subset.
bool get(size_t index) const
Return the value of a single bit, with boundary check.
Definition: bitvector.hpp:128
bool is_subset(Bitvector const &sub, Bitvector const &super)
Subset or equal.
Bitvector set_minus(Bitvector const &lhs, Bitvector const &rhs)
Bitvector bitwise_xor(Bitvector const &lhs, Bitvector const &rhs)
Take the bitwise xor of two Bitvectors of potentially different size.