GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
generate_pds.hpp
1 #include <iostream>
2 #include <vector>
3 namespace graphlab {
4  class pds {
5  public:
6  pds() {}
7  std::vector<size_t> get_pds(size_t p) {
8  std::vector<size_t> result = find_pds(p);
9  // verify pdsness
10  size_t pdslength = p *p + p + 1;
11  std::vector<size_t> count(pdslength, 0);
12  for (size_t i = 0;i < result.size(); ++i) {
13  for (size_t j = 0;j < result.size(); ++j) {
14  if (i == j) continue;
15  count[(result[i] - result[j] + pdslength) % pdslength]++;
16  }
17  }
18  bool ispds = true;
19  for (size_t i = 1;i < count.size(); ++i) {
20  if (count[i] != 1) ispds = false;
21  }
22 
23  // If success, return the result, else, return empty vector.
24  if (ispds) {
25  return result;
26  } else {
27  logstream(LOG_ERROR) << "Fail to generate pds for p = " << p << std::endl;
28  return std::vector<size_t>();
29  }
30  }
31 
32  private:
33  bool test_seq(size_t a, size_t b, size_t c, size_t p, std::vector<size_t>& result) {
34  std::vector<size_t> seq;
35  size_t pdslength = p*p + p + 1;
36  seq.resize(pdslength + 3);
37  seq[0] = 0; seq[1] = 0; seq[2] = 1;
38  size_t ctr = 2;
39  for (size_t i = 3; i < seq.size(); ++i) {
40  seq[i] = a * seq[i - 1] + b * seq[i - 2] + c * seq[i - 3];
41  seq[i] = seq[i] % p;
42  ctr += (seq[i] == 0);
43  // PDS must be of length p + 1
44  // and are the 0's of seq.
45  if (i < pdslength && ctr > p + 1) return false;
46  }
47  if (seq[pdslength] == 0 && seq[pdslength + 1] == 0){
48  // we are good to go
49  // now find the 0s
50  for (size_t i = 0; i < pdslength; ++i) {
51  if (seq[i] == 0) {
52  result.push_back(i);
53  }
54  }
55  // probably not necessary. but verify that the result has length p + 1
56  if (result.size() != p + 1) {
57  result.clear();
58  return false;
59  }
60  return true;
61  }
62  else {
63  return false;
64  }
65  }
66 
67 
68  std::vector<size_t> find_pds(size_t p) {
69  std::vector<size_t> result;
70  for (size_t a = 0; a < p; ++a) {
71  for (size_t b = 0; b < p; ++b) {
72  if (b == 0 && a == 0) continue;
73  for (size_t c = 1; c < p; ++c) {
74  if (test_seq(a,b,c,p,result)) {
75  return result;
76  }
77  }
78  }
79  }
80  return result;
81  }
82  }; // end of pds class
83 } // end of graphlab namespace