An alternative way for if-else in the following piece of code

I have the following piece of code which is a part of my project
if the number of syndromes will increase in each part of my project and with increasing the number of syndromes, then writing if- else statement is difficult, now I would like to know how I can write a code which supports all codes when number of syndrome increase in them?


Last edited on
Are you sure your code is right? Some values of syndrome are the complement of the index of the decodedBits, but some values are the index itself:
Syndrome complement    index
111	   000		  0  
110	   001		  1
101	   010		  2
011	   100		  3
100	   011		  4
010	   101		  5
001	   110		  6


Assuming that what you really want is the complement, the way to do this is to compute the index into decodedBits. Store it in a variable and then use it to set the bit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void func2()
{
    char syndrome[3];
    int val=0;
    
    for (int a = 0; a < 3; a++) {
	char result = 0;
	for (int b = 0; b < 7; b++) {
	    result += (checkMatrix[a][b] * decodedBits[b]);
	}
	syndrome[a] = result % 2;
	val = (val << 1) | (1 ^ syndrome[a]) ;
    }
    if (val < 7) decodedBits[val] ^= 1;
}

Last edited on
.
Last edited on
I think the basic approach I showed you will still work: convert the syndrome bits to a number, map the number to an index for decodedBits and then set the appropriate decoded bit based on the index.
you can do several things to clean it up if you wanted.

a lookup table.. this is very close, I think it is correct (?) but you may want to double check me.

char tbl[] = {0,1,2,4,3,5,6,6}; //this is intentional because of your weird bit pattern. 6s map 6 and 7 to 6.

char dx = 0;
if(synd[0] == 0) dx |= 4;
if(synd[1] == 0) dx |= 2;
if(synd[] == 0) dx |=1;
//if(dx >=6) dx = 6; //not necessary here, but if you had like 20+ combos this is worth a look
dcb[tbl[dx]] ^=1;

what I did was:
define synd[0] = bit 3, synd[1] = bit 2, and synd [2] = bit 1
map binary numbers from combinations of synd into the lookup table
cook up the correct index, and its done.

3 bits of synd can represent up to 111 which is 7. So you could actually just extend the table so that 6 and 7 both map to 6 and skip the dx correction logic. either way works.

Hopefully this is right, did it off the cuff, but if not, it should be close and give you an idea.

This is the same idea, different approach, to what dhayden said.

you can also do nested combined conditions, but that gets old.
if(synd[0] && synd[1])
{
if(synd[2])
//do this
else
//do that
}
else...

and finally, there may be some sort of way to just cook up an answer...
it may be possible that
dcb[0] = *bitwise statement*
dcb[1] = *different bitwise*
etc
6 of those statements back to back and its done.
maybe

dcb[0] ^= synd[0]&&synd[1]&&synd[2] ; //1 if all 3 are set, else ^0 (false) which does nothing. This one is easy, but I don't know if all of them can be so casually cooked.

My 'gut' feeling is that these can all be worded as direct assignment statements (of varying complexity) and no if/else at all!


there's a happy medium somewhere too. If this is performance critical stuff, using an array or vector for synd is poor, it should just be an integer and access bits as bits. If its performance critical, then it is worth looking at each assignment and minimizing the work done for each one. The result is going to be a nightmare to read, debug, and deal with though. If its not high speed stuff, find some readable compromise that keeps it simple. The lookup table approach is solid there.
Last edited on
the structure which Mr dhayden answered after my first question is not correct and compatible with the strategy of my project, please just guide me how I can use an alternative way instead of if-else when I have increasing elements in condition part in if statement?
Lookup table, like jonnin said.

It seems that each element of syndrome has value of 0 or 1. Therefore:
key = syndrome[0] + 2 * syndrome[1] + 4 * syndrome[2];

std::map makes a perfect table. The key is of course the value and the map_value is the index that you need.

1
2
3
4
5
6
7
8
9
std::map<size_t,size_t> foo;
// fill table

size_t key = syndrome[0] + 2 * syndrome[1] + 4 * syndrome[2];
auto it = foo.find( key );
if ( it != foo.end() )
{
  decodedBits[ it->second ] ^= 1;
}

See http://www.cplusplus.com/reference/map/map/find/

How you compute the key and what you put into the table is up to you.
Last edited on
.
Last edited on
the structure which Mr dhayden answered after my first question is not correct and compatible with the strategy of my project
Can you explain why it's incorrect / incompatible? It seems to me that the idea is fine, with the possible exception that you may need a lookup table to map the value from the syndromes (val in my sample code) to the actual index. That's what keskiverto and jonnin did.

please just guide me how I can use an alternative way instead of if-else when I have increasing elements in condition part in if statement?
All three of us have provided answers that would seem to solve your problem. It's straightforward to extend the solutions to more syndromes.

Please describe why our solutions won't solve your problem. Otherwise, I, for one, am at a loss regarding how to help you.
well I offered 2 viable solutions... mapping the syndrome values as bits (which we all did in slightly different ways) and direct assignment (no conditions or lookup tables at all) via getting down an dirty with the bit logic stuff. Both will work. I mean, it does not get any more direct than 7 assignment statements!

At this point either you did not understand what we tried to explain (which is fine, say so and ask for clarification) or you have some requirement you did not tell us (provide it). If you need to re-use it, you can build a little class or maybe just a stand alone function or something where all you have to do is provide the lookup table and the array that will be modified. There isnt any way to re-use the direct assignment, but since you have to figure out that mapping and logic anyway, it does not cost anything to write it for each one individually -- maybe an extra 30 sec each.

Last edited on
Call
map<int,int> M = setMap( parityBits );
to set up a mapping for the requisite number of parity bits (as suggested by @Jonnin and @dhayden).

For each syndrome array v (I've used a vector<int> below) call
getSyndromeNumber( v )
as suggested by @Keskiverto.

You can do what you like with decodedBits[] once you have the index from M[number].


The code below is set up for 3 parity bits, but apart from changing the test arrays it should work for other numbers.

The first four bits are data bits; the last three are parity bits (corresponding to powers of 2). This is why the mapping comes out looking slightly odd.


Outcome of mapping: syndrome and index:
001 6
010 5
011 3
100 4
101 2
110 1
111 0


Tests:
1 1 1  ---> decodedBit number 0
1 1 0  ---> decodedBit number 1
1 0 1  ---> decodedBit number 2
0 1 1  ---> decodedBit number 3
1 0 0  ---> decodedBit number 4
0 1 0  ---> decodedBit number 5
0 0 1  ---> decodedBit number 6



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
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;


//=====================================================================


string toBinary( int n, int p )
{
   string result;
   for ( ; p; p--, n /= 2 ) result = (char)( '0' + n % 2 ) + result;
   return result;
}


//=====================================================================


// Define a mapping from syndomeNumber to the decodedBit index for pBits parity bits
// 
// Ordering in decodedBit[] is:   D(s-1) D(s-2) ... D(0) P(p-1) P(p-2) ... P(0)
//    where D is a data bit, P is a parity bit
//
map<int,int> setMap( int pBits )
{
   int N = ( 1 << pBits ) - 1;                   // Maximum number representable (2^p-1)

   map<int,int> M;

   // Set up mapping of parity bits (2^i)
   int n = 1;
   for ( int i = 0; i < pBits; i++ ) 
   {
      M[n] = N - 1 - i;
      n *= 2;
   }

   // Remaining data bits
   int next = 0;
   for ( int i = N; i >= 1; i-- )
   {
      if ( M.count( i ) == 0 )                   // If NOT a parity bit
      {
         M[i] = next;
         next++;
      }
   }

   // Check if required
   cout << "Outcome of mapping: syndrome and index:\n";
   for ( auto e : M ) cout << toBinary( e.first, pBits ) << " " << e.second << '\n';

   return M;
}


//=====================================================================


int getSyndromeNumber( vector<int> syndrome )
{
   int result = 0;
   for ( int i = 0; i < syndrome.size(); i++ ) result = 2 * result + syndrome[i];
   return result;
}


//=====================================================================


int main()
{
   const int parityBits = 3;

   map<int,int> M = setMap( parityBits );
   cout << "\n\n";


   vector< vector<int> > tests = { { 1, 1, 1 }, { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 },
                                   { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }               };
   cout << "Tests:\n";
   for ( auto v : tests )
   {
      for ( int i : v ) cout << i << ' ';
      cout << " ---> decodedBit number " << M[ getSyndromeNumber( v ) ] << '\n';
   }
}




Last edited on
Topic archived. No new replies allowed.