38#include <visp3/core/vpConfig.h>
40#if defined(VISP_HAVE_CATCH2)
43#include <catch_amalgamated.hpp>
45#include <visp3/core/vpColVector.h>
47#ifdef ENABLE_VISP_NAMESPACE
53static bool g_runBenchmark =
false;
54VP_ATTRIBUTE_NO_DESTROY
static const std::vector<unsigned int> g_sizes = { 23, 127, 233, 419, 1153, 2749 };
56double getRandomValues(
double min,
double max) {
return (max - min) * (
static_cast<double>(rand()) /
static_cast<double>(RAND_MAX)) + min; }
58vpColVector generateRandomVector(
unsigned int rows,
double min = -100,
double max = 100)
62 for (
unsigned int i = 0;
i <
v.getRows();
i++) {
63 v[
i] = getRandomValues(min, max);
69double stddev(
const std::vector<double> &vec)
71 double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
72 double mean = sum / vec.size();
74 std::vector<double> diff(vec.size());
75 std::transform(vec.begin(), vec.end(), diff.begin(), [mean](
double x) {
77 double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
78 return std::sqrt(sq_sum / vec.size());
85 for (
unsigned int i = 0;
i <
v.getRows();
i++) {
94 double sum_square = 0.0;
96 for (
unsigned int i = 0;
i <
v.getRows();
i++) {
97 sum_square +=
v[
i] *
v[
i];
105 double mean_value = computeRegularSum(v) /
v.getRows();
106 double sum_squared_diff = 0.0;
108 for (
unsigned int i = 0;
i <
v.size();
i++) {
109 sum_squared_diff += (
v[
i] - mean_value) * (v[i] - mean_value);
112 double divisor =
static_cast<double>(
v.size());
114 return std::sqrt(sum_squared_diff / divisor);
117std::vector<double> computeHadamard(
const std::vector<double> &v1,
const std::vector<double> &v2)
119 std::vector<double> result;
120 std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(result), std::multiplies<double>());
130 for (
unsigned int i = 0;
i < v1.
getRows();
i++) {
140TEST_CASE(
"Benchmark vpColVector::sum()",
"[benchmark]")
144 const double val = 11;
146 CHECK(
v.sum() == Catch::Approx(val).epsilon(std::numeric_limits<double>::epsilon()));
149 const unsigned int size = 11;
150 std::vector<double> vec(size);
152 for (
size_t i = 0;
i < 11;
i++) {
154 v[
static_cast<unsigned int>(
i)] = vec[i];
156 CHECK(
v.sum() == Catch::Approx(std::accumulate(vec.begin(), vec.end(), 0.0)).epsilon(std::numeric_limits<double>::epsilon()));
159 if (g_runBenchmark) {
160 for (
auto size : g_sizes) {
162 std::vector<double> vec =
v.toStdVector();
164 std::ostringstream oss;
165 oss <<
"Benchmark vpColVector::sum() with size: " << size <<
" (ViSP)";
167 BENCHMARK(oss.str().c_str())
174 oss <<
"Benchmark std::accumulate() with size: " << size <<
" (C++)";
176 BENCHMARK(oss.str().c_str())
178 std_sum = std::accumulate(vec.begin(), vec.end(), 0.0);
181 CHECK(vp_sum == Catch::Approx(std_sum));
184 oss <<
"Benchmark naive sum() with size: " << size;
185 double naive_sum = 0;
186 BENCHMARK(oss.str().c_str())
188 naive_sum = computeRegularSum(v);
191 CHECK(naive_sum == Catch::Approx(std_sum));
196TEST_CASE(
"Benchmark vpColVector::sumSquare()",
"[benchmark]")
200 const double val = 11;
202 CHECK(
v.sumSquare() == Catch::Approx(val * val).epsilon(std::numeric_limits<double>::epsilon()));
205 const unsigned int size = 11;
206 std::vector<double> vec(size);
208 for (
size_t i = 0;
i < 11;
i++) {
210 v[
static_cast<unsigned int>(
i)] = vec[i];
212 CHECK(
v.sumSquare() == Catch::Approx(std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0))
213 .epsilon(std::numeric_limits<double>::epsilon()));
216 if (g_runBenchmark) {
217 for (
auto size : g_sizes) {
219 std::vector<double> vec =
v.toStdVector();
221 std::ostringstream oss;
222 oss <<
"Benchmark vpColVector::sumSquare() with size: " << size <<
" (ViSP)";
223 double vp_sq_sum = 0;
224 BENCHMARK(oss.str().c_str())
226 vp_sq_sum =
v.sumSquare();
231 oss <<
"Benchmark std::inner_product with size: " << size <<
" (C++)";
232 double std_sq_sum = 0;
233 BENCHMARK(oss.str().c_str())
235 std_sq_sum = std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0);
238 CHECK(vp_sq_sum == Catch::Approx(std_sq_sum));
241 oss <<
"Benchmark naive sumSquare() with size: " << size;
242 double naive_sq_sum = 0;
243 BENCHMARK(oss.str().c_str())
245 naive_sq_sum = computeRegularSumSquare(v);
248 CHECK(naive_sq_sum == Catch::Approx(std_sq_sum));
253TEST_CASE(
"Benchmark vpColVector::stdev()",
"[benchmark]")
260 std::vector<double> vec =
v.toStdVector();
261 CHECK(
vpColVector::stdev(v) == Catch::Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
264 const unsigned int size = 11;
265 std::vector<double> vec(size);
267 for (
size_t i = 0;
i < 11;
i++) {
269 v[
static_cast<unsigned int>(
i)] = vec[i];
271 CHECK(
vpColVector::stdev(v) == Catch::Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
274 if (g_runBenchmark) {
275 for (
auto size : g_sizes) {
277 std::vector<double> vec =
v.toStdVector();
279 std::ostringstream oss;
280 oss <<
"Benchmark vpColVector::stdev() with size: " << size <<
" (ViSP)";
281 double vp_stddev = 0;
282 BENCHMARK(oss.str().c_str())
289 oss <<
"Benchmark C++ stddev impl with size: " << size <<
" (C++)";
290 double std_stddev = 0;
291 BENCHMARK(oss.str().c_str())
293 std_stddev = stddev(vec);
296 CHECK(vp_stddev == Catch::Approx(std_stddev));
299 oss <<
"Benchmark naive stdev() with size: " << size;
300 double naive_stddev = 0;
301 BENCHMARK(oss.str().c_str())
303 naive_stddev = computeRegularStdev(v);
306 CHECK(naive_stddev == Catch::Approx(std_stddev));
311TEST_CASE(
"Benchmark vpColVector::hadamard()",
"[benchmark]")
322 CHECK(almostEqual(res1, res2));
325 const unsigned int size = 11;
326 std::vector<double> vec1(size), vec2(size);
327 for (
size_t i = 0;
i < 11;
i++) {
329 vec2[
i] = 3. *
i + 5.;
334 CHECK(almostEqual(res1, res2));
337 if (g_runBenchmark) {
338 for (
auto size : g_sizes) {
344 std::ostringstream oss;
345 oss <<
"Benchmark vpColVector::hadamard() with size: " << size <<
" (ViSP)";
347 BENCHMARK(oss.str().c_str())
354 oss <<
"Benchmark C++ element wise multiplication with size: " << size <<
" (C++)";
355 std::vector<double> std_res;
356 BENCHMARK(oss.str().c_str())
358 std_res = computeHadamard(vec1, vec2);
366int main(
int argc,
char *argv[])
373 Catch::Session session;
374 auto cli = session.cli()
375 | Catch::Clara::Opt(g_runBenchmark)[
"--benchmark"](
"run benchmark?");
378 session.applyCommandLine(argc, argv);
380 int numFailed = session.run();
386int main() {
return EXIT_SUCCESS; }
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)