PandA-2024.02
digitrec_sw.c
Go to the documentation of this file.
1 /*===============================================================*/
2 /* */
3 /* digitrec_sw.cpp */
4 /* */
5 /* Software version for digit recognition */
6 /* */
7 /*===============================================================*/
8 
9 #include "digitrec_sw.h"
10 
11 // types and constants used in the functions below
12 const unsigned long long m1 = 0x5555555555555555; //binary: 0101...
13 const unsigned long long m2 = 0x3333333333333333; //binary: 00110011..
14 const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
15 
16 // popcount function
17 // source: wikipedia (https://en.wikipedia.org/wiki/Hamming_weight)
19 {
20  x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
21  x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
22  x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
23  x += x >> 8; //put count of each 16 bits into their lowest 8 bits
24  x += x >> 16; //put count of each 32 bits into their lowest 8 bits
25  x += x >> 32; //put count of each 64 bits into their lowest 8 bits
26  return x & 0x7f;
27 }
28 
29 void update_knn( const DigitType* train_inst, const DigitType* test_inst, int dists[K_CONST], int labels[K_CONST], int label )
30 {
31  int dist = 0;
32 
33  for (int i = 0; i < DIGIT_WIDTH; i ++ )
34  {
35  DigitType diff = test_inst[i] ^ train_inst[i];
36  dist += popcount(diff);
37  }
38 
39  int max_dist = 0;
40  int max_dist_id = K_CONST+1;
41 
42  // Find the max distance
43  FIND_MAX_DIST: for ( int k = 0; k < K_CONST; ++k )
44  {
45  if ( dists[k] > max_dist )
46  {
47  max_dist = dists[k];
48  max_dist_id = k;
49  }
50  }
51 
52  // Replace the entry with the max distance
53  if ( dist < max_dist )
54  {
55  dists[max_dist_id] = dist;
56  labels[max_dist_id] = label;
57  }
58 
59  return;
60 }
61 
62 LabelType knn_vote(int labels[K_CONST])
63 {
64  int max_vote = 0;
65  LabelType max_label = 0;
66 
67  int votes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
68 
69  for (int i = 0; i < K_CONST; i ++ )
70  votes[labels[i]] ++;
71 
72  for (int i = 0; i < 10; i ++ )
73  {
74  if (votes[i] > max_vote)
75  {
76  max_vote = votes[i];
77  max_label = i;
78  }
79  }
80 
81  return max_label;
82 
83 }
84 
85 #ifndef NTESTS
86 #define NTESTS 4
87 #endif
88 
89 // sw top function
90 void DigitRec_sw(const DigitType global_training_set[NUM_TRAINING * DIGIT_WIDTH],
91  const DigitType global_test_set[NUM_TEST * DIGIT_WIDTH],
92  LabelType global_results[NUM_TEST])
93 {
94 
95  // nearest neighbor set
96  int dists[K_CONST];
97  int labels[K_CONST];
98 
99  // loop through test set
100  TEST_LOOP: for (int t = 0; t < NTESTS /*NUM_TESTS*/; ++t)
101  {
102  // Initialize the neighbor set
103  SET_KNN_SET: for ( int i = 0; i < K_CONST; ++i )
104  {
105  // Note that the max distance is 256
106  dists[i] = 256;
107  labels[i] = 0;
108  }
109 
110  // for each training instance, compare it with the test instance, and update the nearest neighbor set
111  TRAINING_LOOP : for ( int i = 0; i < NUM_TRAINING; ++i )
112  update_knn(&global_training_set[i * DIGIT_WIDTH], &global_test_set[t * DIGIT_WIDTH], dists, labels, i / CLASS_SIZE);
113 
114  // Compute the final output
115  LabelType max_vote = knn_vote(labels);
116  global_results[t] = max_vote;
117 
118  }
119 
120 }
121 
#define NUM_TEST
Definition: typedefs.h:15
void update_knn(const DigitType *train_inst, const DigitType *test_inst, int dists[K_CONST], int labels[K_CONST], int label)
Definition: digitrec_sw.c:29
#define K_CONST
Definition: typedefs.h:36
#define NTESTS
Definition: digitrec_sw.c:86
int popcount(DigitType x)
Definition: digitrec_sw.c:18
unsigned char LabelType
Definition: typedefs.h:20
#define NUM_TRAINING
Definition: typedefs.h:13
LabelType knn_vote(int labels[K_CONST])
Definition: digitrec_sw.c:62
const unsigned long long m4
Definition: digitrec_sw.c:14
static const uint32_t k[]
Definition: sha-256.c:22
const unsigned long long m2
Definition: digitrec_sw.c:13
void DigitRec_sw(const DigitType global_training_set[NUM_TRAINING *DIGIT_WIDTH], const DigitType global_test_set[NUM_TEST *DIGIT_WIDTH], LabelType global_results[NUM_TEST])
Definition: digitrec_sw.c:90
const unsigned long long m1
Definition: digitrec_sw.c:12
#define CLASS_SIZE
Definition: typedefs.h:14
x
Return the smallest n such that 2^n >= _x.
#define DIGIT_WIDTH
Definition: typedefs.h:16
unsigned long long DigitType
Definition: typedefs.h:19

Generated on Mon Feb 12 2024 13:02:50 for PandA-2024.02 by doxygen 1.8.13