Merged anastas/wip changes r3156:3218 into trunk.
[debian/gnuradio] / gr-trellis / src / lib / fsm.cc
1 /* -*- c++ -*- */\r
2 /*\r
3  * Copyright 2002 Free Software Foundation, Inc.\r
4  *\r
5  * This file is part of GNU Radio\r
6  *\r
7  * GNU Radio is free software; you can redistribute it and/or modify\r
8  * it under the terms of the GNU General Public License as published by\r
9  * the Free Software Foundation; either version 2, or (at your option)\r
10  * any later version.\r
11  *\r
12  * GNU Radio is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  * GNU General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU General Public License\r
18  * along with GNU Radio; see the file COPYING.  If not, write to\r
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
20  * Boston, MA 02111-1307, USA.\r
21  */\r
22 \r
23 #include <cstdio>\r
24 #include <stdexcept>\r
25 #include <cmath>\r
26 #include "fsm.h"\r
27 \r
28 fsm::fsm()\r
29 {\r
30   d_I=0;\r
31   d_S=0;\r
32   d_O=0;\r
33   d_NS.resize(0);\r
34   d_OS.resize(0);\r
35   d_PS.resize(0);\r
36   d_PI.resize(0);\r
37 }\r
38 \r
39 fsm::fsm(const fsm &FSM)\r
40 {\r
41   d_I=FSM.I();\r
42   d_S=FSM.S();\r
43   d_O=FSM.O();\r
44   d_NS=FSM.NS();\r
45   d_OS=FSM.OS();\r
46   d_PS=FSM.PS();\r
47   d_PI=FSM.PI();\r
48 }\r
49 \r
50 fsm::fsm(const int I, const int S, const int O, const std::vector<int> &NS, const std::vector<int> &OS)\r
51 {\r
52   d_I=I;\r
53   d_S=S;\r
54   d_O=O;\r
55   d_NS=NS;\r
56   d_OS=OS;\r
57   d_PS.resize(d_I*d_S);\r
58   d_PI.resize(d_I*d_S);\r
59   \r
60   // generate the PS, PI tables for later use\r
61   for(int i=0;i<d_S;i++) {\r
62     int j=0;\r
63     for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
64       if(d_NS[ii*d_I+jj]!=i) continue;\r
65       d_PS[i*d_I+j]=ii;\r
66       d_PI[i*d_I+j]=jj;\r
67       j++;\r
68     }\r
69   }\r
70 }\r
71 \r
72 //######################################################################\r
73 //# Read an FSM specification from a file.\r
74 //# Format (hopefully will become more flexible in the future...):\r
75 //# I S O (in the first line)\r
76 //# blank line\r
77 //# Next state matrix (S lines, each with I integers separated by spaces)\r
78 //# blank line\r
79 //# output symbol matrix (S lines, each with I integers separated by spaces)\r
80 //# optional comments\r
81 //######################################################################\r
82 fsm::fsm(const char *name) \r
83 {\r
84   FILE *fsmfile;\r
85 \r
86   if((fsmfile=fopen(name,"r"))==NULL) \r
87     throw std::runtime_error ("file open error in fsm()");\r
88     //printf("file open error in fsm()\n");\r
89   \r
90   fscanf(fsmfile,"%d %d %d\n",&d_I,&d_S,&d_O);\r
91   d_NS.resize(d_I*d_S);\r
92   d_OS.resize(d_I*d_S);\r
93   d_PS.resize(d_I*d_S);\r
94   d_PI.resize(d_I*d_S);\r
95 \r
96   for(int i=0;i<d_S;i++) {\r
97     for(int j=0;j<d_I;j++) fscanf(fsmfile,"%d",&(d_NS[i*d_I+j]));\r
98   }\r
99   for(int i=0;i<d_S;i++) {\r
100     for(int j=0;j<d_I;j++) fscanf(fsmfile,"%d",&(d_OS[i*d_I+j]));\r
101   }\r
102   \r
103   // generate the PS, PI tables for later use\r
104   for(int i=0;i<d_S;i++) {\r
105     int j=0;\r
106     for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
107       if(d_NS[ii*d_I+jj]!=i) continue;\r
108       d_PS[i*d_I+j]=ii;\r
109       d_PI[i*d_I+j]=jj;\r
110       j++;\r
111     }\r
112   }\r
113 }\r
114 \r
115 //######################################################################\r
116 //# Automatically generate an FSM specification describing the \r
117 //# ISI for a channel\r
118 //# of length ch_length and a modulation of size mod_size\r
119 //######################################################################\r
120 fsm::fsm(const int mod_size, const int ch_length)\r
121 {\r
122   d_I=mod_size;\r
123   d_S=(int) (pow(1.0*d_I,1.0*ch_length-1)+0.5);\r
124   d_O=d_S*d_I;\r
125 \r
126   d_NS.resize(d_I*d_S);\r
127   d_OS.resize(d_I*d_S);\r
128   d_PS.resize(d_I*d_S);\r
129   d_PI.resize(d_I*d_S);\r
130 \r
131   for(int s=0;s<d_S;s++) {\r
132     for(int i=0;i<d_I;i++) { \r
133       int t=i*d_S+s;\r
134       d_NS[s*d_I+i] = t/d_I;\r
135       d_OS[s*d_I+i] = t;\r
136     }\r
137   }\r
138   \r
139   // generate the PS, PI tables for later use\r
140   for(int i=0;i<d_S;i++) {\r
141     int j=0;\r
142     for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
143       if(d_NS[ii*d_I+jj]!=i) continue;\r
144       d_PS[i*d_I+j]=ii;\r
145       d_PI[i*d_I+j]=jj;\r
146       j++;\r
147     }\r
148   }\r
149 }\r