IT++ Logo
punct_convcode.cpp
Go to the documentation of this file.
1 
30 
31 
32 namespace itpp
33 {
34 
35 // --------------------- Punctured_Conv_Code --------------------------------
36 
37 //------- Protected functions -----------------------
38 int Punctured_Convolutional_Code::weight(int state, int input, int time)
39 {
40  int i, j, temp, out, w = 0, shiftreg = state;
41 
42  shiftreg = shiftreg | (int(input) << m);
43  for (j = 0; j < n; j++) {
44  if (puncture_matrix(j, time) == bin(1)) {
45  out = 0;
46  temp = shiftreg & gen_pol(j);
47  for (i = 0; i < K; i++) {
48  out ^= (temp & 1);
49  temp = temp >> 1;
50  }
51  w += out;
52  }
53  }
54  return w;
55 }
56 
57 int Punctured_Convolutional_Code::weight_reverse(int state, int input, int time)
58 {
59  int i, j, temp, out, w = 0, shiftreg = state;
60 
61  shiftreg = shiftreg | (int(input) << m);
62  for (j = 0; j < n; j++) {
63  if (puncture_matrix(j, Period - 1 - time) == bin(1)) {
64  out = 0;
65  temp = shiftreg & gen_pol_rev(j);
66  for (i = 0; i < K; i++) {
67  out ^= (temp & 1);
68  temp = temp >> 1;
69  }
70  w += out;
71  }
72  }
73  return w;
74 }
75 
76 void Punctured_Convolutional_Code::weight(int state, int &w0, int &w1, int time)
77 {
78  int i, j, temp, out, shiftreg = state;
79  w0 = 0;
80  w1 = 0;
81 
82  shiftreg = shiftreg | (1 << m);
83  for (j = 0; j < n; j++) {
84  if (puncture_matrix(j, time) == bin(1)) {
85  out = 0;
86  temp = shiftreg & gen_pol(j);
87  for (i = 0; i < m; i++) {
88  out ^= (temp & 1);
89  temp = temp >> 1;
90  }
91  w0 += out;
92  w1 += out ^(temp & 1);
93  }
94  }
95 }
96 
97 void Punctured_Convolutional_Code::weight_reverse(int state, int &w0, int &w1, int time)
98 {
99  int i, j, temp, out, shiftreg = state;
100  w0 = 0;
101  w1 = 0;
102 
103  shiftreg = shiftreg | (1 << m);
104  for (j = 0; j < n; j++) {
105  if (puncture_matrix(j, Period - 1 - time) == bin(1)) {
106  out = 0;
107  temp = shiftreg & gen_pol_rev(j);
108  for (i = 0; i < m; i++) {
109  out ^= (temp & 1);
110  temp = temp >> 1;
111  }
112  w0 += out;
113  w1 += out ^(temp & 1);
114  }
115  }
116 }
117 
118 //------- Public functions -----------------------
119 
121 {
122  it_error_if((pmatrix.rows() != n) || (pmatrix.cols() == 0), "Wrong size of puncture matrix");
123  puncture_matrix = pmatrix;
124  Period = puncture_matrix.cols();
125 
126  int p, j;
127  total = 0;
128 
129  for (j = 0; j < n; j++) {
130  for (p = 0; p < Period; p++)
131  total = total + (int)(puncture_matrix(j, p));
132  }
133  rate = (double)Period / total;
134 }
135 
136 void Punctured_Convolutional_Code::encode(const bvec &input, bvec &output)
137 {
138  switch (cc_method) {
139  case Trunc:
140  encode_trunc(input, output);
141  break;
142  case Tail:
143  encode_tail(input, output);
144  break;
145  case Tailbite:
146  encode_tailbite(input, output);
147  break;
148  default:
149  encode_tail(input, output);
150  break;
151  };
152 }
153 
154 void Punctured_Convolutional_Code::encode_trunc(const bvec &input, bvec &output)
155 {
156  Convolutional_Code::encode_trunc(input, output);
157 
158  int nn = 0, i, p = 0, j;
159 
160  for (i = 0; i < int(output.size() / n); i++) {
161  for (j = 0; j < n; j++) {
162  if (puncture_matrix(j, p) == bin(1)) {
163  output(nn) = output(i * n + j);
164  nn++;
165  }
166  }
167  p = (p + 1) % Period;
168  }
169  output.set_size(nn, true);
170 }
171 
172 void Punctured_Convolutional_Code::encode_tail(const bvec &input, bvec &output)
173 {
174  Convolutional_Code::encode_tail(input, output);
175 
176  int nn = 0, i, p = 0, j;
177 
178  for (i = 0; i < int(output.size() / n); i++) {
179  for (j = 0; j < n; j++) {
180  if (puncture_matrix(j, p) == bin(1)) {
181  output(nn) = output(i * n + j);
182  nn++;
183  }
184  }
185  p = (p + 1) % Period;
186  }
187  output.set_size(nn, true);
188 }
189 
190 void Punctured_Convolutional_Code::encode_tailbite(const bvec &input, bvec &output)
191 {
193 
194  int nn = 0, i, p = 0, j;
195 
196  for (i = 0; i < int(output.size() / n); i++) {
197  for (j = 0; j < n; j++) {
198  if (puncture_matrix(j, p) == bin(1)) {
199  output(nn) = output(i * n + j);
200  nn++;
201  }
202  }
203  p = (p + 1) % Period;
204  }
205  output.set_size(nn, true);
206 }
207 
208 
209 // --------------- Hard-decision decoding is not implemented --------------------------------
210 void Punctured_Convolutional_Code::decode(const bvec &, bvec &)
211 {
212  it_error("Punctured_Convolutional_Code::decode(bvec, bvec); hard-decision decoding is not implemented");
213 }
214 
216 {
217  it_error("Punctured_Convolutional_Code::decode(bvec, bvec); hard-decision decoding is not implemented");
218  return bvec();
219 }
220 
221 /*
222  Decode a block of encoded data using specified method
223 */
224 void Punctured_Convolutional_Code::decode(const vec &received_signal, bvec &output)
225 {
226  switch (cc_method) {
227  case Trunc:
228  decode_trunc(received_signal, output);
229  break;
230  case Tail:
231  decode_tail(received_signal, output);
232  break;
233  case Tailbite:
234  decode_tailbite(received_signal, output);
235  break;
236  default:
237  decode_tail(received_signal, output);
238  break;
239  };
240 }
241 
242 
243 // Viterbi decoder using TruncLength (=5*K if not specified)
244 void Punctured_Convolutional_Code::decode_trunc(const vec &received_signal, bvec &output)
245 {
246  int nn = 0, i = 0, p = received_signal.size() / total, j;
247 
248  int temp_size = p * Period * n;
249  // number of punctured bits in a fraction of the puncture matrix
250  // correcponding to the end of the received_signal vector
251  p = received_signal.size() - p * total;
252  // precise calculation of the number of unpunctured bits
253  // (in the above fraction of the puncture matrix)
254  while (p > 0) {
255  for (j = 0; j < n; j++) {
256  if (puncture_matrix(j, nn) == bin(1))
257  p--;
258  }
259  nn++;
260  }
261  temp_size += n * nn;
262  if (p != 0) {
263  it_warning("Punctured_Convolutional_Code::decode(): Improper length of "
264  "the received punctured block, dummy bits have been added");
265  }
266 
267  vec temp(temp_size);
268  nn = 0;
269  j = 0;
270  p = 0;
271 
272  while (nn < temp.size()) {
273  if ((puncture_matrix(j, p) == bin(1)) && (i < received_signal.size())) {
274  temp(nn) = received_signal(i);
275  i++;
276  }
277  else { // insert dummy symbols with the same contribution for 0 and 1
278  temp(nn) = 0;
279  }
280 
281  nn++;
282  j++;
283 
284  if (j == n) {
285  j = 0;
286  p = (p + 1) % Period;
287  }
288  } // while
289 
290  Convolutional_Code::decode_trunc(temp, output);
291 }
292 
293 // Viterbi decoder using TruncLength (=5*K if not specified)
294 void Punctured_Convolutional_Code::decode_tail(const vec &received_signal, bvec &output)
295 {
296  int nn = 0, i = 0, p = received_signal.size() / total, j;
297 
298  int temp_size = p * Period * n;
299  // number of punctured bits in a fraction of the puncture matrix
300  // correcponding to the end of the received_signal vector
301  p = received_signal.size() - p * total;
302  // precise calculation of the number of unpunctured bits
303  // (in the above fraction of the puncture matrix)
304  while (p > 0) {
305  for (j = 0; j < n; j++) {
306  if (puncture_matrix(j, nn) == bin(1))
307  p--;
308  }
309  nn++;
310  }
311  temp_size += n * nn;
312  if (p != 0) {
313  it_warning("Punctured_Convolutional_Code::decode_tail(): Improper length "
314  "of the received punctured block, dummy bits have been added");
315  }
316 
317  vec temp(temp_size);
318 
319  nn = 0;
320  j = 0;
321  p = 0;
322 
323  while (nn < temp.size()) {
324  if ((puncture_matrix(j, p) == bin(1)) && (i < received_signal.size())) {
325  temp(nn) = received_signal(i);
326  i++;
327  }
328  else { // insert dummy symbols with same contribution for 0 and 1
329  temp(nn) = 0;
330  }
331 
332  nn++;
333  j++;
334 
335  if (j == n) {
336  j = 0;
337  p = (p + 1) % Period;
338  }
339  } // while
340 
341  Convolutional_Code::decode_tail(temp, output);
342 }
343 
344 // Decode a block of encoded data where encode_tailbite has been used. Tries all start states.
345 void Punctured_Convolutional_Code::decode_tailbite(const vec &received_signal, bvec &output)
346 {
347  int nn = 0, i = 0, p = received_signal.size() / total, j;
348 
349  int temp_size = p * Period * n;
350  // number of punctured bits in a fraction of the puncture matrix
351  // correcponding to the end of the received_signal vector
352  p = received_signal.size() - p * total;
353  // precise calculation of the number of unpunctured bits
354  // (in the above fraction of the puncture matrix)
355  while (p > 0) {
356  for (j = 0; j < n; j++) {
357  if (puncture_matrix(j, nn) == bin(1))
358  p--;
359  }
360  nn++;
361  }
362  temp_size += n * nn;
363  if (p != 0) {
364  it_warning("Punctured_Convolutional_Code::decode_tailbite(): Improper "
365  "length of the received punctured block, dummy bits have been "
366  "added");
367  }
368 
369  vec temp(temp_size);
370 
371  nn = 0;
372  j = 0;
373  p = 0;
374 
375  while (nn < temp.size()) {
376  if ((puncture_matrix(j, p) == bin(1)) && (i < received_signal.size())) {
377  temp(nn) = received_signal(i);
378  i++;
379  }
380  else { // insert dummy symbols with same contribution for 0 and 1
381  temp(nn) = 0;
382  }
383 
384  nn++;
385  j++;
386 
387  if (j == n) {
388  j = 0;
389  p = (p + 1) % Period;
390  }
391  } // while
392 
394 }
395 
396 
397 /*
398  Calculate the inverse sequence
399 
400  Assumes that encode_tail is used in the encoding process. Returns false if there is an
401  error in the coded sequence (not a valid codeword). Does not check that the tail forces
402  the encoder into the zeroth state.
403 */
404 bool Punctured_Convolutional_Code::inverse_tail(const bvec coded_sequence, bvec &input)
405 {
406  int state = 0, zero_state, one_state, zero_temp, one_temp, i, j, p = 0, prev_pos = 0, no_symbols;
407  int block_length = 0;
408  bvec zero_output(n), one_output(n), temp_output(n);
409 
410  block_length = coded_sequence.size() * Period / total - m;
411 
412  it_error_if(block_length <= 0, "The input sequence is to short");
413  input.set_length(block_length, false); // not include the tail in the output
414 
415  p = 0;
416 
417  for (i = 0; i < block_length; i++) {
418  zero_state = state;
419  one_state = state | (1 << m);
420  no_symbols = 0;
421  for (j = 0; j < n; j++) {
422  if (puncture_matrix(j, p) == bin(1)) {
423  zero_temp = zero_state & gen_pol(j);
424  one_temp = one_state & gen_pol(j);
425  zero_output(no_symbols) = xor_int_table(zero_temp);
426  one_output(no_symbols) = xor_int_table(one_temp);
427  no_symbols++;
428  }
429  }
430  if (coded_sequence.mid(prev_pos, no_symbols) == zero_output.left(no_symbols)) {
431  input(i) = bin(0);
432  state = zero_state >> 1;
433  }
434  else if (coded_sequence.mid(prev_pos, no_symbols) == one_output.left(no_symbols)) {
435  input(i) = bin(1);
436  state = one_state >> 1;
437  }
438  else
439  return false;
440 
441  prev_pos += no_symbols;
442  p = (p + 1) % Period;
443  }
444 
445  return true;
446 }
447 
448 
449 
450 
451 /*
452  It is possible to do this more efficiently by registrating all (inputs,states,Periods)
453  that has zero metric (just and with the generators). After that build paths from a input=1 state.
454 */
456 {
457  int max_stack_size = 50000;
458  ivec S_stack(max_stack_size), t_stack(max_stack_size);
459  int start, S, W0, W1, S0, S1, pos, t = 0;
460  int stack_pos = -1;
461 
462  for (pos = 0; pos < Period; pos++) { // test all start positions
463  for (start = 0; start < (1 << m); start++) {
464  stack_pos = -1;
465  S = start;
466  t = 0;
467 
468  node1:
469  if (t > (1 << m) * Period) { return true; }
470  S0 = next_state(S, 0);
471  S1 = next_state(S, 1);
472  weight(S, W0, W1, (pos + t) % Period);
473  if (W1 > 0) { goto node0; }
474  if ((W0 == 0) && (S0 == start) && (((pos + t + 1) % Period) == pos)) { return true; }
475  if ((W0 == 0) && (S0 == 0) && (S != 0)) { return true; }
476  if ((S0 != 0) && (W0 == 0)) {
477  stack_pos++;
478  if (stack_pos >= max_stack_size) {
479  max_stack_size = 2 * max_stack_size;
480  S_stack.set_size(max_stack_size, true);
481  t_stack.set_size(max_stack_size, true);
482  }
483  S_stack(stack_pos) = S0;
484  t_stack(stack_pos) = t + 1;
485  }
486  if ((W1 == 0) && (S1 == start) && (((pos + t + 1) % Period) == pos)) { return true; }
487  S = S1;
488  t++;
489  goto node1;
490 
491  node0:
492  if (W0 > 0) goto stack;
493  if ((W0 == 0) && (S0 == start) && (((pos + t + 1) % Period) == pos)) { return true; }
494  if ((W0 == 0) && (S0 == 0) && (S != 0)) { return true; }
495  if (S0 != 0) {
496  S = S0;
497  t++;
498  goto node1;
499  }
500  else {
501  goto stack;
502  }
503 
504  stack:
505  if (stack_pos >= 0) {
506  S = S_stack(stack_pos);
507  t = t_stack(stack_pos);
508  stack_pos--;
509  goto node1;
510  }
511  }
512  }
513  return false;
514 }
515 
516 void Punctured_Convolutional_Code::distance_profile(ivec &dist_prof, int start_time, int dmax, bool reverse)
517 {
518  int max_stack_size = 50000;
519  ivec S_stack(max_stack_size), W_stack(max_stack_size), t_stack(max_stack_size);
520 
521  int stack_pos = -1, t, S, W, W0, w0, w1;
522 
523 
524  dist_prof.zeros();
525  dist_prof += dmax; // just select a big number!
526  if (reverse)
527  W = weight_reverse(0, 1, start_time);
528  else
529  W = weight(0, 1, start_time);
530 
531  S = next_state(0, 1); // start from zero state and a one input
532  t = 0;
533  dist_prof(0) = W;
534 
535 node1:
536  if (reverse)
537  weight_reverse(S, w0, w1, (start_time + t + 1) % Period);
538  else
539  weight(S, w0, w1, (start_time + t + 1) % Period);
540 
541  if (t < m) {
542  W0 = W + w0;
543  if (W0 < dist_prof(m)) { // store node0 (S, W0, and t+1)
544  stack_pos++;
545  if (stack_pos >= max_stack_size) {
546  max_stack_size = 2 * max_stack_size;
547  S_stack.set_size(max_stack_size, true);
548  W_stack.set_size(max_stack_size, true);
549  t_stack.set_size(max_stack_size, true);
550  }
551  S_stack(stack_pos) = next_state(S, 0);
552  W_stack(stack_pos) = W0;
553  t_stack(stack_pos) = t + 1;
554  }
555  }
556  else goto stack;
557 
558  W += w1;
559  if (W > dist_prof(m))
560  goto stack;
561 
562  t++;
563  S = next_state(S, 1);
564 
565  if (W < dist_prof(t))
566  dist_prof(t) = W;
567 
568  if (t == m) goto stack;
569  goto node1;
570 
571 
572 stack:
573  if (stack_pos >= 0) {
574  // get root node from stack
575  S = S_stack(stack_pos);
576  W = W_stack(stack_pos);
577  t = t_stack(stack_pos);
578  stack_pos--;
579 
580  if (W < dist_prof(t))
581  dist_prof(t) = W;
582 
583  if (t == m) goto stack;
584 
585  goto node1;
586  }
587 }
588 
589 int Punctured_Convolutional_Code::fast(Array<ivec> &spectrum, int start_time, int dfree, int no_terms,
590  int d_best_so_far, bool test_catastrophic)
591 {
592  int cat_treshold = (1 << m) * Period;
593  int i, j, t = 0;
594  ivec dist_prof(K), dist_prof_rev(K), dist_prof_temp(K);
595 
596  //calculate distance profile
597  distance_profile(dist_prof, start_time, dfree);
598  distance_profile(dist_prof_rev, 0, dfree, true); // for the reverse code
599 
600  int dist_prof_rev0 = dist_prof_rev(0);
601 
602  bool reverse = true; // true = use reverse dist_prof
603 
604  // choose the lowest dist_prof over all periods
605  for (i = 1; i < Period; i++) {
606  distance_profile(dist_prof_temp, i, dfree, true);
607  // switch if new is lower
608  for (j = 0; j < K; j++) {
609  if (dist_prof_temp(j) < dist_prof_rev(j)) {
610  dist_prof_rev(j) = dist_prof_temp(j);
611  }
612  }
613  }
614 
615  dist_prof_rev0 = dist_prof(0);
616  dist_prof = dist_prof_rev;
617 
618  int d = dfree + no_terms - 1;
619  int max_stack_size = 50000;
620  ivec S_stack(max_stack_size), W_stack(max_stack_size), b_stack(max_stack_size);
621  ivec c_stack(max_stack_size), t_stack(max_stack_size);
622  int stack_pos = -1;
623 
624  // F1.
625  int mf = 1, b = 1;
626  spectrum.set_size(2);
627  spectrum(0).set_size(dfree + no_terms, 0); // ad
628  spectrum(1).set_size(dfree + no_terms, 0); // cd
629  spectrum(0).zeros();
630  spectrum(1).zeros();
631  int S, S0, S1, W0, W1, w0, w1, c = 0;
632  S = next_state(0, 1); // start in zero state and one input
633  int W = d - dist_prof_rev0;
634  t = 1;
635 
636 F2:
637  S0 = next_state(S, 0);
638  S1 = next_state(S, 1);
639 
640  if (reverse) {
641  weight(S, w0, w1, (start_time + t) % Period);
642  }
643  else {
644  weight_reverse(S, w0, w1, (start_time + t) % Period);
645  }
646  W0 = W - w0;
647  W1 = W - w1;
648 
649  if (mf < m) goto F6;
650 
651  //F3:
652  if (W0 >= 0) {
653  spectrum(0)(d - W0)++;
654  spectrum(1)(d - W0) += b;
655  }
656  //Test on d_best_so_far
657  if ((d - W0) < d_best_so_far) { return -1; }
658 
659 F4:
660  if ((W1 < dist_prof(m - 1)) || (W < dist_prof(m))) goto F5;
661  // select node 1
662  if (test_catastrophic && (W == W1)) {
663  c++;
664  if (c > cat_treshold)
665  return 0;
666  }
667  else {
668  c = 0;
669  }
670 
671  W = W1;
672  S = S1;
673  t++;
674  mf = 1;
675  b++;
676  goto F2;
677 
678 F5:
679  if (stack_pos == -1) goto end;
680  // get node from stack
681  S = S_stack(stack_pos);
682  W = W_stack(stack_pos);
683  b = b_stack(stack_pos);
684  c = c_stack(stack_pos);
685  t = t_stack(stack_pos);
686  stack_pos--;
687  mf = 1;
688  goto F2;
689 
690 F6:
691  if (W0 < dist_prof(m - mf - 1)) goto F4;
692 
693  //F7:
694  if ((W1 >= dist_prof(m - 1)) && (W >= dist_prof(m))) {
695  // save node 1
696  if (test_catastrophic && (stack_pos > 40000))
697  return 0;
698 
699  stack_pos++;
700  if (stack_pos >= max_stack_size) {
701  max_stack_size = 2 * max_stack_size;
702  S_stack.set_size(max_stack_size, true);
703  W_stack.set_size(max_stack_size, true);
704  b_stack.set_size(max_stack_size, true);
705  c_stack.set_size(max_stack_size, true);
706  t_stack.set_size(max_stack_size, true);
707  }
708  S_stack(stack_pos) = S1;
709  W_stack(stack_pos) = W1;
710  b_stack(stack_pos) = b + 1; // because gone to node 1
711  c_stack(stack_pos) = c;
712  t_stack(stack_pos) = t + 1;
713  }
714  // select node 0
715  S = S0;
716  t++;
717  if (test_catastrophic && (W == W0)) {
718  c++;
719  if (c > cat_treshold)
720  return false;
721  }
722  else {
723  c = 0;
724  }
725 
726  W = W0;
727  mf++;
728  goto F2;
729 
730 end:
731  return 1;
732 }
733 
735 {
736  Array<ivec> temp_spectra(2);
737  spectrum.set_size(2);
738  spectrum(0).set_size(dmax + no_terms, false);
739  spectrum(1).set_size(dmax + no_terms, false);
740  spectrum(0).zeros();
741  spectrum(1).zeros();
742 
743  for (int pos = 0; pos < Period; pos++) {
744  calculate_spectrum(temp_spectra, pos, dmax, no_terms);
745  spectrum(0) += temp_spectra(0);
746  spectrum(1) += temp_spectra(1);
747  }
748 }
749 
750 void Punctured_Convolutional_Code::calculate_spectrum(Array<ivec> &spectrum, int time, int dmax, int no_terms, int block_length)
751 {
752  imat Ad_states(1 << (K - 1), dmax + no_terms), Cd_states(1 << m, dmax + no_terms);
753  imat Ad_temp(1 << (K - 1), dmax + no_terms), Cd_temp(1 << m, dmax + no_terms);
754  ivec mindist(1 << (K - 1)), mindist_temp(1 << m);
755 
756  spectrum.set_size(2);
757  spectrum(0).set_size(dmax + no_terms, false);
758  spectrum(1).set_size(dmax + no_terms, false);
759  spectrum(0).zeros();
760  spectrum(1).zeros();
761  Ad_states.zeros();
762  Cd_states.zeros();
763  mindist.zeros();
764  int wmax = dmax + no_terms;
765  ivec visited_states(1 << m), visited_states_temp(1 << m);
766  bool proceede, expand_s1;
767  int t, d, w0, w1, s, s0, s1 = 0, s_start;
768 
769  // initial phase. Evolv trellis up to time K.
770  visited_states.zeros(); // 0 = false
771 
772  s1 = next_state(0, 1); // Start in state 0 and 1 input
773  visited_states(s1) = 1; // 1 = true.
774  w1 = weight(0, 1, time);
775  Ad_states(s1, w1) = 1;
776  Cd_states(s1, w1) = 1;
777  mindist(s1) = w1;
778 
779  if (block_length > 0) {
780  s0 = next_state(0, 0);
781  visited_states(s0) = 1; // 1 = true. Expand also the zero-path
782  w0 = weight(0, 0, time);
783  Ad_states(s0, w0) = 1;
784  Cd_states(s0, w0) = 0;
785  mindist(s0) = w0;
786  s_start = 0;
787  }
788  else {
789  s_start = 1;
790  }
791 
792  t = 1;
793  proceede = true;
794  while (proceede) {
795  proceede = false;
796  Ad_temp.zeros();
797  Cd_temp.zeros();
798  mindist_temp.zeros();
799  visited_states_temp.zeros(); //false
800 
801  for (s = s_start; s < (1 << m); s++) {
802 
803  if (visited_states(s) == 1) {
804  if ((mindist(s) >= 0) && (mindist(s) < wmax)) {
805  proceede = true;
806  weight(s, w0, w1, (time + t) % Period);
807 
808  s0 = next_state(s, 0);
809  for (d = mindist(s); d < (wmax - w0); d++) {
810  Ad_temp(s0, d + w0) += Ad_states(s, d);
811  Cd_temp(s0, d + w0) += Cd_states(s, d);
812  }
813  if (visited_states_temp(s0) == 0) { mindist_temp(s0) = mindist(s) + w0; }
814  else { mindist_temp(s0) = ((mindist(s) + w0) < mindist_temp(s0)) ? mindist(s) + w0 : mindist_temp(s0); }
815  visited_states_temp(s0) = 1; //true
816 
817  expand_s1 = false;
818  if ((block_length == 0) || (t < (block_length - (K - 1)))) {
819  expand_s1 = true;
820  }
821 
822  if (expand_s1) {
823  s1 = next_state(s, 1);
824  for (d = mindist(s); d < (wmax - w1); d++) {
825  Ad_temp(s1, d + w1) += Ad_states(s, d);
826  Cd_temp(s1, d + w1) += Cd_states(s, d) + Ad_states(s, d);
827  }
828  if (visited_states_temp(s1) == 0) { mindist_temp(s1) = mindist(s) + w1; }
829  else { mindist_temp(s1) = ((mindist(s) + w1) < mindist_temp(s1)) ? mindist(s) + w1 : mindist_temp(s1); }
830  visited_states_temp(s1) = 1; //true
831  }
832  }
833  }
834  }
835 
836  Ad_states = Ad_temp;
837  Cd_states = Cd_temp;
838  if (block_length == 0) {
839  spectrum(0) += Ad_temp.get_row(0);
840  spectrum(1) += Cd_temp.get_row(0);
841  }
842  visited_states = visited_states_temp;
843  mindist = elem_mult(mindist_temp, visited_states);
844  t++;
845  if ((t > block_length) && (block_length > 0)) { proceede = false; }
846  }
847 
848  if (block_length > 0) {
849  spectrum(0) = Ad_states.get_row(0);
850  spectrum(1) = Cd_states.get_row(0);
851  }
852 
853 }
854 
855 } // namespace itpp
SourceForge Logo

Generated on Sat May 25 2013 16:32:21 for IT++ by Doxygen 1.8.2