diff --git a/alib2algo/src/stringology/simulations/GeneralizedLevenshteinBitParalelism.h b/alib2algo/src/stringology/simulations/GeneralizedLevenshteinBitParalelism.h new file mode 100644 index 0000000000000000000000000000000000000000..e56d0aeb7b5adb14830b72b112cbf917b54a631c --- /dev/null +++ b/alib2algo/src/stringology/simulations/GeneralizedLevenshteinBitParalelism.h @@ -0,0 +1,94 @@ +/* + * GeneralizedLevenshteinBitParalelism.h + * + * Created on: 29.4.2018 + * Author: Tomas Capek + */ + +#ifndef _GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_H__ +#define _GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_H__ + +#include <exception> +#include <string/LinearString.h> + +#include "BitParalelism.h" + +namespace stringology { + +namespace simulations { + +class GeneralizedLevenshteinBitParalelism { +public: + template <class SymbolType> + static ext::vector<unsigned int> search(const string::LinearString<SymbolType> & text, const string::LinearString<SymbolType> & pattern, unsigned int errors); +}; + +template <class SymbolType> +ext::vector<unsigned int> GeneralizedLevenshteinBitParalelism::search(const string::LinearString<SymbolType> & text, const string::LinearString<SymbolType> & pattern, unsigned int errors) { + // preparation stage + ext::set<SymbolType> common_alphabet = text.getAlphabet(); + common_alphabet.insert(pattern.getAlphabet().begin(), pattern.getAlphabet().end()); + + ext::map<SymbolType, ext::vector<bool> > D_vectors = BitParalelism::constructDVectors(common_alphabet, pattern); + + auto V_vector = ext::vector<bool>(pattern.getContent().size(), 0); + V_vector[pattern.getContent().size() - 1] = 1; + + // computation part + ext::vector<unsigned int> result; + + ext::vector<ext::vector<bool> > B_vectors; + for(unsigned int i=0; i<=errors; i++) { + B_vectors.push_back(ext::vector<bool>(pattern.getContent().size(), 0)); + } + + for(unsigned int l = 0; l <= errors; l++) { + for(unsigned int j = l; j <= pattern.getContent().size(); j++) { + B_vectors[l][j] = 1; + } + } + + ext::vector<ext::vector<bool> > S_vectors; + for(unsigned int i=0; i<=errors; i++) { + S_vectors.push_back(ext::vector<bool>(pattern.getContent().size(), 1)); + } + + for(unsigned int i=0; i<text.getContent().size(); i++) { + ext::vector< ext::vector<bool> > previous_B_vectors = B_vectors; + ext::vector< ext::vector<bool> > previous_S_vectors = S_vectors; + + auto D_vector = D_vectors[text.getContent()[i]]; + + B_vectors[0] = (previous_B_vectors[0] << 1) | D_vector; + S_vectors[0] = (previous_B_vectors[0] << 1) | (D_vector >> 1); + + for(unsigned int j=1; j<=errors; j++) { + B_vectors[j] = ((previous_B_vectors[j] << 1) | D_vector) & + ((previous_B_vectors[j-1] & B_vectors[j-1] & (previous_S_vectors[j-1] | D_vector)) << 1) & + (previous_B_vectors[j-1] | V_vector); + + S_vectors[j] = (previous_B_vectors[j] << 1) | (D_vector >> 1); + } + + for (const auto & data : B_vectors) { + if(data[pattern.getContent().size()-1] == false) { + if (i < pattern.getContent().size()) { + if (result.size() == 0) { + result.push_back(0); + } + } else { + result.push_back(i - pattern.getContent().size() + 1); + } + break; + } + } + } + + return result; +} + +} // namespace simulations + +} // namespace stringology + +#endif /* _GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_H__ */ diff --git a/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.cpp b/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf5155a2f3d4f8a5f2a034c979451c6c27bac173 --- /dev/null +++ b/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.cpp @@ -0,0 +1,20 @@ +#include "GeneralizedLevenshteinBitParalelismTest.h" + +#include <string/LinearString.h> +#include <stringology/simulations/GeneralizedLevenshteinBitParalelism.h> + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( GeneralizedLevenshteinBitParalelismTest, "bit paralelism" ); +CPPUNIT_TEST_SUITE_REGISTRATION ( GeneralizedLevenshteinBitParalelismTest ); + +void GeneralizedLevenshteinBitParalelismTest::testSimple() { + auto text = string::LinearString<>("adbcbaabadbbca"); + auto pattern = string::LinearString<>("adbbca"); + + ext::vector<unsigned int> expected_result = {0, 1, 3, 5, 6, 7, 8}; + auto result = stringology::simulations::GeneralizedLevenshteinBitParalelism::search(text, pattern, 3); + CPPUNIT_ASSERT(expected_result == result); +} + +void GeneralizedLevenshteinBitParalelismTest::setUp() { } + +void GeneralizedLevenshteinBitParalelismTest::tearDown() { } diff --git a/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.h b/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.h new file mode 100644 index 0000000000000000000000000000000000000000..3bcfe69d2dce8e213b7c5e0dfeb009ce6d97efd3 --- /dev/null +++ b/alib2algo/test-src/stringology/simulations/GeneralizedLevenshteinBitParalelismTest.h @@ -0,0 +1,17 @@ +#ifndef GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_TEST_H_ +#define GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class GeneralizedLevenshteinBitParalelismTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(GeneralizedLevenshteinBitParalelismTest); + CPPUNIT_TEST(testSimple); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp ( ); + void tearDown ( ); + + void testSimple(); +}; +#endif // GENERALIZED_LEVENSHTEIN_BIT_PARALELISM_TEST_H_