Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "mbl_mask.h"
00009 #include <vcl_set.h>
00010 #include <vcl_map.h>
00011 #include <vcl_fstream.h>
00012 #include <vcl_string.h>
00013 #include <mbl/mbl_exception.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022 void mbl_masks_from_index_set(const vcl_vector<unsigned> & indices,
00023 vcl_vector<mbl_mask> & masks)
00024 {
00025 masks.clear();
00026 unsigned n = indices.size(), n_masks = 0;
00027 vcl_set<unsigned> used_indices;
00028 vcl_map<unsigned, unsigned> ordering;
00029
00030 for (unsigned i = 0 ; i < n ; ++i)
00031 used_indices.insert(indices[i]);
00032
00033 for (vcl_set<unsigned>::const_iterator it = used_indices.begin(),
00034 end = used_indices.end();
00035 it != end; ++it)
00036 {
00037 ordering[*it] = n_masks++;
00038 masks.push_back(mbl_mask(n));
00039 }
00040
00041 for (unsigned i = 0 ; i < n ; ++i)
00042 masks[ordering[indices[i]]][i] = true;
00043 }
00044
00045
00046
00047 void mbl_mask_on_mask(const mbl_mask & A, mbl_mask & B)
00048 {
00049 unsigned nA = A.size();
00050 unsigned nB = 0;
00051 for (unsigned i = 0 ; i < B.size() ; ++i) nB += B[i];
00052 if (nA != nB)
00053 throw vcl_runtime_error("Length of A mismatch with number of true elements of B");
00054
00055 for (unsigned i = 0, j = 0 ; i < B.size() ; ++i)
00056 if (B[i]) B[i] = A[j++];
00057 }
00058
00059
00060
00061 void mbl_mask_logic_and(const mbl_mask & A, mbl_mask & B)
00062 {
00063 mbl_mask_logic(A, B, "0001");
00064 }
00065
00066
00067 void mbl_mask_logic_or(const mbl_mask & A, mbl_mask & B)
00068 {
00069 mbl_mask_logic(A, B, "0111");
00070 }
00071
00072
00073 void mbl_mask_logic_xor(const mbl_mask & A, mbl_mask & B)
00074 {
00075 mbl_mask_logic(A, B, "0110");
00076 }
00077
00078
00079 void mbl_mask_logic_nor(const mbl_mask & A, mbl_mask & B)
00080 {
00081 mbl_mask_logic(A, B, "1000");
00082 }
00083
00084
00085 void mbl_mask_logic_xnor(const mbl_mask & A, mbl_mask & B)
00086 {
00087 mbl_mask_logic(A, B, "1001");
00088 }
00089
00090
00091 void mbl_mask_logic_nand(const mbl_mask & A, mbl_mask & B)
00092 {
00093 mbl_mask_logic(A, B, "1110");
00094 }
00095
00096
00097
00098 void mbl_mask_logic(const mbl_mask & A, mbl_mask & B, const vcl_string & operation)
00099 {
00100 if (A.size() != B.size())
00101 throw vcl_runtime_error("Mask lengths differ");
00102
00103
00104
00105 if (operation.length() != 4)
00106 throw vcl_runtime_error("Operation must be of length 4");
00107 vcl_vector<bool> op_rule(4);
00108 for (unsigned i = 0 ; i < 4 ; ++i)
00109 {
00110 if (operation[i] == '0') op_rule[i] = false;
00111 else if (operation[i] == '1') op_rule[i] = true;
00112 else throw vcl_runtime_error("Invalid character in operation string - must contain only '0' or '1'");
00113 }
00114
00115
00116 for (unsigned i = 0 ; i < A.size() ; ++i)
00117 B[i] = op_rule[2*A[i] + B[i]];
00118 }
00119
00120
00121
00122 void mbl_save_mask(const mbl_mask & mask, vcl_ostream & stream)
00123 {
00124 vcl_vector<bool>::const_iterator it = mask.begin();
00125 const vcl_vector<bool>::const_iterator & end = mask.end();
00126 for (; it != end; ++it)
00127 stream << *it << vcl_endl;
00128 }
00129
00130
00131 void mbl_save_mask(const mbl_mask & mask, const char * filename)
00132 {
00133 vcl_ofstream stream(filename);
00134 if (!stream)
00135 mbl_exception_throw_os_error(filename);
00136 mbl_save_mask(mask, stream);
00137 }
00138
00139
00140 void mbl_save_mask(const mbl_mask & mask, const vcl_string &filename)
00141 {
00142 vcl_ofstream stream(filename.c_str());
00143 if (!stream)
00144 mbl_exception_throw_os_error(filename);
00145 mbl_save_mask(mask, stream);
00146 }
00147
00148
00149 void mbl_load_mask(mbl_mask & mask, vcl_istream & stream)
00150 {
00151 mask.clear();
00152 vcl_string line;
00153 while (stream.good())
00154 {
00155 vcl_getline(stream, line);
00156 if (line.length() == 0) continue;
00157 if (line == "0") mask.push_back(false);
00158 else if (line == "1") mask.push_back(true);
00159 else
00160 {
00161 mask.clear();
00162 throw mbl_exception_parse_file_error("Unable to parse mask value " + line, "");
00163 }
00164 }
00165 }
00166
00167
00168 void mbl_load_mask(mbl_mask & mask, const char * filename)
00169 {
00170 vcl_ifstream stream(filename);
00171 if (!stream)
00172 mbl_exception_throw_os_error(filename);
00173 try
00174 {
00175 mbl_load_mask(mask, stream);
00176 }
00177 catch (mbl_exception_parse_file_error & e)
00178 {
00179 throw mbl_exception_parse_file_error(e.what(), filename);
00180 }
00181 }