36 #include <visp3/core/vpConfig.h>
38 #ifdef VISP_HAVE_CATCH2
39 #define CATCH_CONFIG_ENABLE_BENCHMARKING
40 #define CATCH_CONFIG_RUNNER
43 #include <visp3/core/vpColVector.h>
47 static bool g_runBenchmark =
false;
48 static const std::vector<unsigned int> g_sizes = { 23, 127, 233, 419, 1153, 2749 };
50 double getRandomValues(
double min,
double max) {
return (max - min) * ((double)rand() / (double)RAND_MAX) + min; }
52 vpColVector generateRandomVector(
unsigned int rows,
double min = -100,
double max = 100)
56 for (
unsigned int i = 0; i < v.getRows(); i++) {
57 v[i] = getRandomValues(min, max);
63 double stddev(
const std::vector<double> &vec)
65 double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
66 double mean = sum / vec.size();
68 std::vector<double> diff(vec.size());
69 std::transform(vec.begin(), vec.end(), diff.begin(), [mean](
double x) {
71 double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
72 return std::sqrt(sq_sum / vec.size());
79 for (
unsigned int i = 0; i < v.
getRows(); i++) {
86 double computeRegularSumSquare(
const vpColVector &v)
88 double sum_square = 0.0;
90 for (
unsigned int i = 0; i < v.
getRows(); i++) {
91 sum_square += v[i] * v[i];
99 double mean_value = computeRegularSum(v) / v.
getRows();
100 double sum_squared_diff = 0.0;
102 for (
unsigned int i = 0; i < v.
size(); i++) {
103 sum_squared_diff += (v[i] - mean_value) * (v[i] - mean_value);
106 double divisor = (double)v.
size();
108 return std::sqrt(sum_squared_diff / divisor);
111 std::vector<double> computeHadamard(
const std::vector<double> &v1,
const std::vector<double> &v2)
113 std::vector<double> result;
114 std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(result), std::multiplies<double>());
124 for (
unsigned int i = 0; i < v1.
getRows(); i++) {
134 TEST_CASE(
"Benchmark vpColVector::sum()",
"[benchmark]")
138 const double val = 11;
140 CHECK(v.
sum() == Approx(val).epsilon(std::numeric_limits<double>::epsilon()));
143 const unsigned int size = 11;
144 std::vector<double> vec(size);
146 for (
size_t i = 0; i < 11; i++) {
148 v[
static_cast<unsigned int>(i)] = vec[i];
151 Approx(std::accumulate(vec.begin(), vec.end(), 0.0)).epsilon(std::numeric_limits<double>::epsilon()));
154 if (g_runBenchmark) {
155 for (
auto size : g_sizes) {
159 std::ostringstream oss;
160 oss <<
"Benchmark vpColVector::sum() with size: " << size <<
" (ViSP)";
162 BENCHMARK(oss.str().c_str())
169 oss <<
"Benchmark std::accumulate() with size: " << size <<
" (C++)";
171 BENCHMARK(oss.str().c_str())
173 std_sum = std::accumulate(vec.begin(), vec.end(), 0.0);
176 CHECK(vp_sum == Approx(std_sum));
179 oss <<
"Benchmark naive sum() with size: " << size;
180 double naive_sum = 0;
181 BENCHMARK(oss.str().c_str())
183 naive_sum = computeRegularSum(v);
186 CHECK(naive_sum == Approx(std_sum));
191 TEST_CASE(
"Benchmark vpColVector::sumSquare()",
"[benchmark]")
195 const double val = 11;
197 CHECK(v.
sumSquare() == Approx(val * val).epsilon(std::numeric_limits<double>::epsilon()));
200 const unsigned int size = 11;
201 std::vector<double> vec(size);
203 for (
size_t i = 0; i < 11; i++) {
205 v[
static_cast<unsigned int>(i)] = vec[i];
207 CHECK(v.
sumSquare() == Approx(std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0))
208 .epsilon(std::numeric_limits<double>::epsilon()));
211 if (g_runBenchmark) {
212 for (
auto size : g_sizes) {
216 std::ostringstream oss;
217 oss <<
"Benchmark vpColVector::sumSquare() with size: " << size <<
" (ViSP)";
218 double vp_sq_sum = 0;
219 BENCHMARK(oss.str().c_str())
226 oss <<
"Benchmark std::inner_product with size: " << size <<
" (C++)";
227 double std_sq_sum = 0;
228 BENCHMARK(oss.str().c_str())
230 std_sq_sum = std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0);
233 CHECK(vp_sq_sum == Approx(std_sq_sum));
236 oss <<
"Benchmark naive sumSquare() with size: " << size;
237 double naive_sq_sum = 0;
238 BENCHMARK(oss.str().c_str())
240 naive_sq_sum = computeRegularSumSquare(v);
243 CHECK(naive_sq_sum == Approx(std_sq_sum));
248 TEST_CASE(
"Benchmark vpColVector::stdev()",
"[benchmark]")
256 CHECK(
vpColVector::stdev(v) == Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
259 const unsigned int size = 11;
260 std::vector<double> vec(size);
262 for (
size_t i = 0; i < 11; i++) {
264 v[
static_cast<unsigned int>(i)] = vec[i];
266 CHECK(
vpColVector::stdev(v) == Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
269 if (g_runBenchmark) {
270 for (
auto size : g_sizes) {
274 std::ostringstream oss;
275 oss <<
"Benchmark vpColVector::stdev() with size: " << size <<
" (ViSP)";
276 double vp_stddev = 0;
277 BENCHMARK(oss.str().c_str())
284 oss <<
"Benchmark C++ stddev impl with size: " << size <<
" (C++)";
285 double std_stddev = 0;
286 BENCHMARK(oss.str().c_str())
288 std_stddev = stddev(vec);
291 CHECK(vp_stddev == Approx(std_stddev));
294 oss <<
"Benchmark naive stdev() with size: " << size;
295 double naive_stddev = 0;
296 BENCHMARK(oss.str().c_str())
298 naive_stddev = computeRegularStdev(v);
301 CHECK(naive_stddev == Approx(std_stddev));
306 TEST_CASE(
"Benchmark vpColVector::hadamard()",
"[benchmark]")
317 CHECK(almostEqual(res1, res2));
320 const unsigned int size = 11;
321 std::vector<double> vec1(size), vec2(size);
322 for (
size_t i = 0; i < 11; i++) {
324 vec2[i] = 3. * i + 5.;
329 CHECK(almostEqual(res1, res2));
332 if (g_runBenchmark) {
333 for (
auto size : g_sizes) {
339 std::ostringstream oss;
340 oss <<
"Benchmark vpColVector::hadamard() with size: " << size <<
" (ViSP)";
342 BENCHMARK(oss.str().c_str())
349 oss <<
"Benchmark C++ element wise multiplication with size: " << size <<
" (C++)";
350 std::vector<double> std_res;
351 BENCHMARK(oss.str().c_str())
353 std_res = computeHadamard(vec1, vec2);
361 int main(
int argc,
char *argv[])
368 Catch::Session session;
371 using namespace Catch::clara;
372 auto cli = session.cli()
373 | Opt(g_runBenchmark)
381 session.applyCommandLine(argc, argv);
383 int numFailed = session.run();
393 int main() {
return EXIT_SUCCESS; }
unsigned int size() const
Return the number of elements of the 2D array.
unsigned int getRows() const
Implementation of column vector and the associated operations.
vpColVector hadamard(const vpColVector &v) const
std::vector< double > toStdVector() const
static double stdev(const vpColVector &v, bool useBesselCorrection=false)
static bool equal(double x, double y, double threshold=0.001)