dither 0.2.2 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ package com.github.jesg.dither;
2
+
3
+ /*
4
+ * #%L
5
+ * dither
6
+ * %%
7
+ * Copyright (C) 2015 Jason Gowan
8
+ * %%
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ * #L%
21
+ */
22
+
23
+ class Pair {
24
+ final int i;
25
+ final int j;
26
+
27
+ Pair(final int i, final int j) {
28
+ this.i = i;
29
+ this.j = j;
30
+ }
31
+
32
+
33
+ @Override
34
+ public int hashCode() {
35
+ final int prime = 31;
36
+ int result = 1;
37
+ result = prime * result + i;
38
+ result = prime * result + j;
39
+ return result;
40
+ }
41
+
42
+ @Override
43
+ public boolean equals(Object obj) {
44
+ if (this == obj)
45
+ return true;
46
+ if (obj == null)
47
+ return false;
48
+ if (getClass() != obj.getClass())
49
+ return false;
50
+ Pair other = (Pair) obj;
51
+ if (j != other.j)
52
+ return false;
53
+ if (i != other.i)
54
+ return false;
55
+ return true;
56
+ }
57
+
58
+ public String toString() {
59
+ return "Pair i: " + i + " j: " + j;
60
+ }
61
+ }
@@ -20,7 +20,10 @@ namespace dither {
20
20
  BaseConstraintHandler(){};
21
21
  virtual ~BaseConstraintHandler(){};
22
22
  virtual bool violate_constraints(const dtest_case &test_case) { return false; }
23
- virtual bool violate_constraints(const std::vector<param> &test_case) {
23
+ virtual bool violate_constraints(const std::vector<param*> &test_case) {
24
+ return false;
25
+ }
26
+ virtual bool violate_constraints(param** test_case, const std::size_t length) {
24
27
  return false;
25
28
  }
26
29
  virtual bool ground(dtest_case &test_case) {
@@ -12,6 +12,8 @@
12
12
 
13
13
  #include <vector>
14
14
  #include <forward_list>
15
+ #include <algorithm>
16
+ #include <memory>
15
17
  #include "dither_types.h"
16
18
 
17
19
  namespace dither {
@@ -157,33 +159,40 @@ inline void product3(
157
159
  }
158
160
  }
159
161
 
160
- inline void product4(
161
- std::forward_list<std::vector<param>>& results,
162
- std::vector<std::vector<param>>& param_matrix) {
162
+ inline std::size_t product4(
163
+ std::forward_list<param**>& results,
164
+ param** param_cache,
165
+ std::vector<std::vector<param>*>& param_matrix) {
163
166
  std::vector<int> ranges;
164
- std::vector<param> scratch;
165
- for(auto params : param_matrix) {
166
- ranges.push_back(params.size() - 1);
167
- scratch.push_back(params[0]);
167
+ std::unique_ptr<param*[]> scratch_ptr(new param*[param_matrix.size()]);
168
+ auto scratch = scratch_ptr.get();
169
+ for(std::size_t j = 0; j < param_matrix.size(); j++) {
170
+ ranges.push_back(param_matrix[j]->size() - 1);
171
+ scratch[j] = &(*param_matrix[j])[0];
168
172
  }
169
- std::vector<int> indexes(scratch.size(), 0);
173
+ std::vector<int> indexes(ranges.size(), 0);
170
174
 
171
175
  const std::size_t max = ranges.size() - 1;
176
+ const std::size_t length = ranges.size();
177
+ std::size_t j = 0;
172
178
  for(std::size_t i = max;;) {
173
179
 
174
180
  if(i == max) {
175
181
  for(std::size_t val = 0; val <= ranges[i]; val++) {
176
- scratch[i] = param_matrix[i][indexes[i]];
177
- results.push_front(scratch);
182
+ scratch[i] = &(*param_matrix[i])[indexes[i]];
183
+ std::copy(scratch, scratch+length, param_cache);
184
+ results.push_front(param_cache);
185
+ param_cache += length;
178
186
  indexes[i]++;
187
+ j++;
179
188
  }
180
189
  indexes[i] = 0;
181
190
  i--;
182
191
  } else if(i == 0 && indexes[i] >= ranges[i]) {
183
- return;
192
+ return j;
184
193
  } else if(indexes[i] < ranges[i]) {
185
194
  indexes[i]++;
186
- scratch[i] = param_matrix[i][indexes[i]];
195
+ scratch[i] = &(*param_matrix[i])[indexes[i]];
187
196
  i++;
188
197
  } else {
189
198
  indexes[i] = -1;
@@ -14,6 +14,7 @@
14
14
  #include <tuple>
15
15
  #include <limits.h>
16
16
  #include <cstddef>
17
+ #include <memory>
17
18
 
18
19
  namespace dither {
19
20
 
@@ -27,9 +28,7 @@ Ipog::Ipog() {
27
28
  t_ = 2;
28
29
  }
29
30
 
30
- Ipog::Ipog(const unsigned int t) {
31
- t_ = t;
32
- }
31
+ Ipog::Ipog(const unsigned int t) : t_(t) {}
33
32
 
34
33
  void Ipog::init_bound() {
35
34
  using dither::product3;
@@ -56,7 +55,7 @@ void Ipog::init_bound() {
56
55
  }
57
56
  }
58
57
 
59
- std::forward_list<std::vector<param>> Ipog::cover(const int k) {
58
+ inline param** Ipog::cover(const int k, std::forward_list<param**> &coverage) {
60
59
  std::vector<int> input(k);
61
60
  for (std::size_t i = 0; i < k; i++) {
62
61
  input[i] = i;
@@ -64,30 +63,35 @@ std::forward_list<std::vector<param>> Ipog::cover(const int k) {
64
63
 
65
64
  std::forward_list<std::vector<int>> output;
66
65
  combinations(t_ - 1, input, output);
67
- std::forward_list<std::vector<std::vector<param>>> product_input;
68
- const std::vector<param> k_param = param_cache_[k];
66
+ std::forward_list<std::vector<std::vector<param>*>> product_input;
67
+ int count = 0;
69
68
  for (auto it = output.begin(); it != output.end(); ++it) {
70
- std::vector<std::vector<param>> param_tuple;
69
+ std::vector<std::vector<param>*> param_tuple;
71
70
  (*it).push_back(k);
71
+ int inner_count = 1;
72
72
  for (auto iit = (*it).begin(); iit != (*it).end(); ++iit) {
73
- auto vals = param_cache_[*iit];
74
- param_tuple.push_back(vals);
73
+ param_tuple.push_back(&param_cache_[*iit]);
74
+ inner_count *= param_cache_[*iit].size();
75
75
  }
76
+ count += inner_count;
76
77
  product_input.push_front(param_tuple);
77
78
  }
78
79
 
79
- std::forward_list<std::vector<param>> coverage;
80
+ param **local_param_cache = new param*[count*t_];
81
+ std::size_t j = 0;
80
82
  for (auto it = product_input.begin(); it != product_input.end(); ++it) {
81
- product4(coverage, *it);
83
+ j += t_*product4(coverage, local_param_cache+j, *it);
82
84
  }
83
- coverage.remove_if([this](std::vector<param>& a) { return has_previously_tested(a); });
84
- return coverage;
85
+ coverage.remove_if([this](param **a) { return has_previously_tested(a); });
86
+ return local_param_cache;
85
87
  }
86
88
 
87
89
  void Ipog::run() {
88
90
  init_bound();
89
91
  for (auto k = t_; k < input_params_.size(); k++) {
90
- std::forward_list<std::vector<param>> pi = cover(k);
92
+ std::forward_list<param**> pi;
93
+ param **params = cover(k, pi);
94
+ std::unique_ptr<param*[]> params_ptr(params);
91
95
 
92
96
  {
93
97
  auto prev = bound_.cbefore_begin();
@@ -105,8 +109,8 @@ void Ipog::run() {
105
109
 
106
110
  /* vertical extension */
107
111
  for (auto pairs = pi.cbegin(); pairs != pi.cend(); ++pairs) {
108
- const std::vector<param> &test_case = *pairs;
109
- bool case_covered = constraint_handler->violate_constraints(test_case);
112
+ param **test_case = *pairs;
113
+ bool case_covered = constraint_handler->violate_constraints(test_case, t_);
110
114
 
111
115
  if(!case_covered) {
112
116
  for (auto it = unbound_.cbegin(); it != unbound_.cend(); ++it) {
@@ -125,8 +129,9 @@ void Ipog::run() {
125
129
 
126
130
  if (merge_result > 0) {
127
131
  dtest_case tmp = *next;
128
- for (auto it = test_case.cbegin(); it != test_case.cend(); ++it) {
129
- tmp[(*it).first] = (*it).second;
132
+ for(std::size_t i = 0; i < t_; i++) {
133
+ const param *it = test_case[i];
134
+ tmp[it->first] = it->second;
130
135
  }
131
136
  is_merged = true;
132
137
  break;
@@ -135,8 +140,9 @@ void Ipog::run() {
135
140
 
136
141
  if (!is_merged) {
137
142
  dtest_case unbound_test_case(param_cache_.size(), -1);
138
- for (auto it = test_case.cbegin(); it != test_case.cend(); ++it) {
139
- unbound_test_case[(*it).first] = (*it).second;
143
+ for(std::size_t i = 0; i < t_; i++) {
144
+ const param *it = test_case[i];
145
+ unbound_test_case[it->first] = it->second;
140
146
  }
141
147
  if (!constraint_handler->violate_constraints(unbound_test_case)) {
142
148
  unbound_.push_front(unbound_test_case);
@@ -150,18 +156,20 @@ void Ipog::run() {
150
156
 
151
157
  /* -1 no merge, 0 perfect merge (no unbound), 1 partial merge */
152
158
  inline const int Ipog::merge(const int k, dtest_case &test_case,
153
- const std::vector<param> &pairs) {
154
- for (auto it = pairs.cbegin(); it != pairs.cend(); ++it) {
155
- auto value = test_case[(*it).first];
156
- if (!(value == -1 || value == (*it).second)) {
159
+ param** pairs) {
160
+ for(std::size_t i = 0; i < t_; i++) {
161
+ const param *it = pairs[i];
162
+ auto value = test_case[it->first];
163
+ if (!(value == -1 || value == it->second)) {
157
164
  return -1;
158
165
  }
159
166
  }
160
167
 
161
168
  std::copy(test_case.cbegin(), test_case.cend(), merge_scratch_.begin());
162
169
 
163
- for (auto it = pairs.cbegin(); it != pairs.cend(); ++it) {
164
- merge_scratch_[(*it).first] = (*it).second;
170
+ for(std::size_t i = 0; i < t_; i++) {
171
+ const param *it = pairs[i];
172
+ merge_scratch_[it->first] = it->second;
165
173
  }
166
174
 
167
175
  if (constraint_handler->violate_constraints(merge_scratch_)) {
@@ -178,24 +186,34 @@ inline const int Ipog::merge(const int k, dtest_case &test_case,
178
186
  }
179
187
 
180
188
  inline bool Ipog::is_covered(const dtest_case &test_case,
181
- const std::vector<param> &params) {
189
+ param** params) {
190
+ for(std::size_t i = 0; i < t_; i++) {
191
+ const param *my_param = params[i];
192
+ if (test_case[my_param->first] != my_param->second) {
193
+ return false;
194
+ }
195
+ }
196
+ return true;
197
+ }
198
+ inline bool Ipog::is_covered(const dtest_case &test_case,
199
+ const std::vector<param*> &params) {
182
200
  for (auto param = params.cbegin(); param != params.cend(); ++param) {
183
- if (test_case[(*param).first] != (*param).second) {
201
+ if (test_case[(*param)->first] != (*param)->second) {
184
202
  return false;
185
203
  }
186
204
  }
187
205
  return true;
188
206
  }
189
207
 
190
- const int Ipog::maximize_coverage(const int k, dtest_case &test_case,
191
- std::forward_list<std::vector<param>> &pi) {
208
+ inline const int Ipog::maximize_coverage(const int k, dtest_case &test_case,
209
+ std::forward_list<param**> &pi) {
192
210
  const std::vector<param> &param_range = param_cache_[k];
193
211
  int current_max = -1;
194
212
  param max_param = param_range[0];
195
- std::forward_list<std::forward_list<std::vector<param>>::iterator> covered;
213
+ std::forward_list<std::forward_list<param**>::iterator> covered;
196
214
 
197
215
  for (auto it = param_range.cbegin(); it != param_range.cend(); ++it) {
198
- std::forward_list<std::forward_list<std::vector<param>>::iterator>
216
+ std::forward_list<std::forward_list<param**>::iterator>
199
217
  tmp_covered;
200
218
  const param current_param = *it;
201
219
 
@@ -203,12 +221,11 @@ const int Ipog::maximize_coverage(const int k, dtest_case &test_case,
203
221
  if (!constraint_handler->violate_constraints(test_case)) {
204
222
  int count = 0;
205
223
  auto prev = pi.before_begin();
206
- for (auto params = pi.cbegin(); params != pi.cend(); ++params) {
224
+ for (auto params = pi.begin(); params != pi.end(); ++params, ++prev) {
207
225
  if (is_covered(test_case, *params)) {
208
226
  tmp_covered.push_front(prev);
209
227
  count++;
210
228
  }
211
- ++prev;
212
229
  }
213
230
 
214
231
  if (count > current_max) {
@@ -367,7 +384,7 @@ std::string *Ipog::header() {
367
384
  constraints.push_back(tmp);
368
385
  }
369
386
 
370
- void Ipog::ground_solutions() {
387
+ inline void Ipog::ground_solutions() {
371
388
  std::size_t solution_count = 0;
372
389
  std::vector<dval> transform_scratch(param_cache_.size(), 0);
373
390
 
@@ -414,11 +431,28 @@ void Ipog::add_previously_tested(const int values[], const std::size_t length) {
414
431
  original_previously_tested_.push_back(tmp);
415
432
  }
416
433
 
417
- inline bool Ipog::has_previously_tested(std::vector<param>& test_case) {
434
+ inline bool Ipog::has_previously_tested(std::vector<param*>& test_case) {
418
435
  for(auto it = previously_tested_.cbegin(); it != previously_tested_.cend(); ++it) {
419
436
  bool flag = true;
420
437
  for(auto iit = test_case.cbegin(); iit != test_case.cend(); ++iit) {
421
- if((*it)[(*iit).first] != (*iit).second) {
438
+ if((*it)[(*iit)->first] != (*iit)->second) {
439
+ flag = false;
440
+ break;
441
+ }
442
+ }
443
+ if(flag) {
444
+ return true;
445
+ }
446
+ }
447
+ return false;
448
+ }
449
+
450
+ inline bool Ipog::has_previously_tested(param **params) {
451
+ for(auto it = previously_tested_.cbegin(); it != previously_tested_.cend(); ++it) {
452
+ bool flag = true;
453
+ for(std::size_t i = 0; i < t_; i++) {
454
+ const param *iit = params[i];
455
+ if((*it)[iit->first] != iit->second) {
422
456
  flag = false;
423
457
  break;
424
458
  }
@@ -16,6 +16,7 @@
16
16
  #include <algorithm>
17
17
  #include <string>
18
18
  #include <unordered_map>
19
+ #include <memory>
19
20
  #include "combinations.h"
20
21
  #include "dither_types.h"
21
22
  #include "base_constraint_handler.h"
@@ -52,9 +53,10 @@ class Ipog {
52
53
  std::copy(scratch.cbegin(), scratch.cend(), test_case.begin());
53
54
  }
54
55
 
55
- inline bool has_previously_tested(std::vector<param>& test_case);
56
+ inline bool has_previously_tested(std::vector<param*>& test_case);
56
57
  inline bool has_previously_tested(dtest_case& test_case);
57
58
  inline bool has_previously_tested(const int, dtest_case& test_case);
59
+ inline bool has_previously_tested(param **params);
58
60
 
59
61
  public:
60
62
  Ipog();
@@ -69,17 +71,20 @@ class Ipog {
69
71
  void run();
70
72
  int size();
71
73
  std::string *header();
72
- void ground_solutions();
74
+ inline void ground_solutions();
73
75
  inline bool is_valid() { return t_ <= param_cache_.size(); }
74
- std::forward_list<std::vector<param>> cover(int);
75
- const int maximize_coverage(const int, dtest_case &,
76
- std::forward_list<std::vector<param>> &);
76
+ inline param** cover(int,std::forward_list<param**>&);
77
+ inline const int maximize_coverage(const int, dtest_case &,
78
+ std::forward_list<param**> &);
77
79
  void add_constraint(const int[], const unsigned int);
78
80
  void add_previously_tested(const int[], const std::size_t);
79
81
  inline bool is_covered(const dtest_case &test_case,
80
- const std::vector<param> &params);
82
+ param** params);
83
+ inline bool is_covered(const param** params);
84
+ inline bool is_covered(const dtest_case &test_case,
85
+ const std::vector<param*> &params);
81
86
  inline bool is_covered(const std::vector<param> &params);
82
- inline const int merge(const int, dtest_case &, const std::vector<param> &);
87
+ inline const int merge(const int, dtest_case &, param**);
83
88
  void display_raw_solution();
84
89
  void fill(int[]);
85
90
  inline void display_header() {
@@ -53,10 +53,22 @@ namespace dither {
53
53
  return true;
54
54
  }
55
55
 
56
- bool SimpleConstraintHandler::violate_constraints(const std::vector<param> &test_case) {
56
+ bool SimpleConstraintHandler::violate_constraints(param** test_case, const std::size_t length) {
57
+ std::fill(scratch.begin(), scratch.end(), -1);
58
+ for(std::size_t i = 0; i < length; i++) {
59
+ const param *p = test_case[i];
60
+ scratch[p->first] = p->second;
61
+ }
62
+ if(violate_constraints_(scratch)) {
63
+ return true;
64
+ }
65
+ return !ground(scratch);
66
+ }
67
+
68
+ bool SimpleConstraintHandler::violate_constraints(const std::vector<param*> &test_case) {
57
69
  std::fill(scratch.begin(), scratch.end(), -1);
58
70
  for(auto p : test_case) {
59
- scratch[p.first] = p.second;
71
+ scratch[p->first] = p->second;
60
72
  }
61
73
  if(violate_constraints_(scratch)) {
62
74
  return true;
@@ -30,7 +30,8 @@ namespace dither {
30
30
  public:
31
31
  SimpleConstraintHandler(std::vector<dval>& ranges, std::vector<std::vector<dval>>& pconstraints);
32
32
  bool violate_constraints(const dtest_case &test_case);
33
- bool violate_constraints(const std::vector<param> &test_case);
33
+ bool violate_constraints(const std::vector<param*> &test_case);
34
+ bool violate_constraints(param** test_case, const std::size_t length);
34
35
  bool ground(dtest_case &test_case);
35
36
  };
36
37
  }
@@ -96,8 +96,7 @@ require 'dither/graph'
96
96
 
97
97
  if RUBY_PLATFORM =~ /java/
98
98
  require 'java'
99
- require 'choco-solver-3.3.1-with-dependencies.jar'
100
- require 'dither-0.1.5.jar'
99
+ require 'dither.jar'
101
100
 
102
101
  require 'dither/java_ext/dither'
103
102
  else