-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathviterbi_serial.cc
124 lines (94 loc) · 2.89 KB
/
viterbi_serial.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// viterbi.cc
// Viterbi
//
// Created by Shubham Chaudhary on 19/03/17.
// Copyright © 2017 Shubham Chaudhary. All rights resized.
//
#include <iostream>
#include <limits>
#include <vector>
#include <chrono>
#include "viterbi.hh"
viterbi::viterbi(std::string &arg1, std::string& arg2) {
std::ifstream file;
// Load info of the decoder
file.open("data/viterbi_" + arg1 + "_" + arg2, std::ios::in | std::ios::binary);
file.read((char*) &seq_len, sizeof(seq_len));
file.read((char*) &num_hidden, sizeof(num_hidden));
// Allocate memory for data
ltdp_matrix.resize(seq_len);
for (auto& a : ltdp_matrix) {
a.resize(num_hidden);
for (auto& b: a) {
b.resize(num_hidden);
}
}
// Load LTDP matrix
for (auto& row : ltdp_matrix)
for (auto& col : row)
for (auto& e : col)
file.read((char*) &e, sizeof(e));
file.close();
// Allocate memory for sequence
predicted_sequence.resize(seq_len);
#ifdef DEBUG
std::cout << "Finished loading data from disk." << std::endl;
#endif
}
void viterbi::decode() {
// Setup dynamic programming tables
std::vector<std::vector<double>> dp1;
std::vector<std::vector<unsigned int>> dp2;
// Allocate memory for the dp tables
dp1.resize(seq_len);
dp2.resize(seq_len);
for (auto& a : dp1)
a.resize(num_hidden);
for (auto& a : dp2)
a.resize(num_hidden);
#ifdef DEBUG
std::cout << "Running algorithm for " << num_hidden
<< " hidden states, and a sequence of length "
<< seq_len << std::endl;
#endif
auto wcts = std::chrono::system_clock::now();
// Algorithm
std::vector<double> s(num_hidden, 0.0);
for (int i = 0; i < seq_len; i++) {
for (int j = 0; j < num_hidden; j++) {
double max = -std::numeric_limits<double>::max();
size_t argmax = std::numeric_limits<size_t>::max();
double entry;
for (size_t k = 0; k < num_hidden; k++) {
entry = s[k] + ltdp_matrix[i][j][k];
if (entry > max) {
max = entry;
argmax = k;
}
}
dp1[i][j] = max;
dp2[i][j] = argmax;
}
s = dp1[i];
}
unsigned int x = 0;
for (int i = seq_len - 1; i >= 0; i--) {
predicted_sequence[i] = dp2[i][x];
x = predicted_sequence[i];
}
std::chrono::duration<double> wctduration = (std::chrono::system_clock::now() - wcts);
std::cout << "Elapsed time: "
<< wctduration.count()
<< " seconds."
<< std::endl;
}
void viterbi::show_predicted() {
std::ofstream file(
"output_serial",
std::ios::out | std::ios::trunc);
for (auto& a : predicted_sequence)
file << a << " ";
file << std::endl;
file.close();
}