-
Notifications
You must be signed in to change notification settings - Fork 0
/
Variable_Node.cpp
118 lines (90 loc) · 3.16 KB
/
Variable_Node.cpp
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
/*
* Variable_Node.cpp
*
* Created on: 23 Dec, 2014
\* Author: Mehrdad Tahernia
*/
#include "Message.h"
#include "Channel.h"
#include "PNC_Channel.h"
#include "Edge.h"
#include "Check_Node.h"
#include "Variable_Node.h"
/*************************************************************************
*
* Variable node
*
*************************************************************************/
node &variable_node::AdjacentNode(int index) {
return GetEdge(index).RightNode();
}
message &variable_node::CalcRightboundMessage(int rightbound_index)
// rightbound_index is -1 if calculation is meant for final estimate
{
static message Aux;
Aux = InitialMessage;
for (int i = 0; i < GetDegree(); i++) {
// ignore intrinsic information
if (i == rightbound_index)
continue;
Aux *= GetEdge(i).LeftBoundMessage;
}
Aux.Normalize();
return Aux;
}
void variable_node::CalcFinalMessage() {
FinalEstimate = CalcRightboundMessage( /* NO rightbound index */-1);
DecSymbol = FinalEstimate.Decision();
}
void variable_node::CalcAllRightboundMessages() {
for (int i = 0; i < GetDegree(); i++)
GetEdge(i).RightBoundMessage = CalcRightboundMessage(/* rightbound index */i);
CalcFinalMessage();
}
// Generates channel message
message &GenerateChannelMessage(GFq v, channel &TransmitChannel, mapping &MapInUse, double ChannelOut) {
static message InitialMessage;
int q = MapInUse.GetQ();
double CandidateIn;
// double ChannelIn;
// ChannelIn = MapInUse.map(v); // mapping of (0 + v) % q; FIXME: This is not used
// Generate InitialMessage
InitialMessage.Set_q(q);
for (GFq i(0); i.val < q; i.val++) {
CandidateIn = MapInUse.map(i + v);
InitialMessage[i.val] = TransmitChannel.CalcProbForInput(ChannelOut, CandidateIn);
}
InitialMessage.Normalize(); // Make valid probability vector
return InitialMessage;
}
message &GenerateChannelMessage_PNC(channel &TransmitChannel, mapping &MapInUse, double ChannelOut) {
static message InitialMessage;
int q = MapInUse.GetQ();
double CandidateIn;
GFq N;
// Generate InitialMessage
InitialMessage.Set_q(q);
InitialMessage.Clear();
for (GFq A(0); A.val < q; A.val++)
for (GFq B(0); B.val < q; B.val++) {
N = (dynamic_cast<PNC_Channel&>(TransmitChannel)).alpha * A + (dynamic_cast<PNC_Channel&>(TransmitChannel)).beta * B;
CandidateIn = MapInUse.map(A)*(dynamic_cast<PNC_Channel&>(TransmitChannel)).h_A + MapInUse.map(B)*(dynamic_cast<PNC_Channel&>(TransmitChannel)).h_B;
InitialMessage[N.val] = InitialMessage[N.val] + TransmitChannel.CalcProbForInput(ChannelOut, CandidateIn);
}
InitialMessage.Normalize(); // Make valid probability vector
return InitialMessage;
}
void variable_node::Initialize(channel &TransmitChannel, double ChannelOut) {
// InitialMessage = GenerateChannelMessage(v, TransmitChannel, *MapInUse,ChannelOut);
InitialMessage = GenerateChannelMessage_PNC(TransmitChannel, *MapInUse,ChannelOut);
FinalEstimate = InitialMessage;
// Generate Rightbound messages
for (int j = 0; j < degree; j++)
GetEdge(j).RightBoundMessage = InitialMessage;
}
bool variable_node::IsRightConnectedTo(node *n) {
for (int i = 0; i < degree; i++)
if (&edges[i]->RightNode() == n)
return true;
return false;
}