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)
52 return (max - min) * ((double)rand() / (double)RAND_MAX) + min;
55 vpColVector generateRandomVector(
unsigned int rows,
double min=-100,
double max=100)
59 for (
unsigned int i = 0; i < v.getRows(); i++) {
60 v[i] = getRandomValues(min, max);
66 double stddev(
const std::vector<double>& vec)
68 double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
69 double mean = sum / vec.size();
71 std::vector<double> diff(vec.size());
72 std::transform(vec.begin(), vec.end(), diff.begin(), [mean](
double x) {
return x - mean; });
73 double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
74 return std::sqrt(sq_sum / vec.size());
81 for (
unsigned int i = 0; i < v.
getRows(); i++) {
88 double computeRegularSumSquare(
const vpColVector &v)
90 double sum_square = 0.0;
92 for (
unsigned int i = 0; i < v.
getRows(); i++) {
93 sum_square += v[i] * v[i];
101 double mean_value = computeRegularSum(v) / v.
getRows();
102 double sum_squared_diff = 0.0;
104 for (
unsigned int i = 0; i < v.
size(); i++) {
105 sum_squared_diff += (v[i] - mean_value) * (v[i] - mean_value);
108 double divisor = (double)v.
size();
110 return std::sqrt(sum_squared_diff / divisor);
113 std::vector<double> computeHadamard(
const std::vector<double>& v1,
const std::vector<double>& v2)
115 std::vector<double> result;
116 std::transform(v1.begin(), v1.end(), v2.begin(),
117 std::back_inserter(result), std::multiplies<double>());
127 for (
unsigned int i = 0; i < v1.
getRows(); i++) {
137 TEST_CASE(
"Benchmark vpColVector::sum()",
"[benchmark]") {
140 const double val = 11;
142 CHECK(v.
sum() == Approx(val).epsilon(std::numeric_limits<double>::epsilon()));
145 const unsigned int size = 11;
146 std::vector<double> vec(size);
148 for (
size_t i = 0; i < 11; i++) {
150 v[
static_cast<unsigned int>(i)] = vec[i];
152 CHECK(v.
sum() == Approx(std::accumulate(vec.begin(), vec.end(), 0.0)).epsilon(std::numeric_limits<double>::epsilon()));
155 if (g_runBenchmark) {
156 for (
auto size : g_sizes) {
160 std::ostringstream oss;
161 oss <<
"Benchmark vpColVector::sum() with size: " << size <<
" (ViSP)";
163 BENCHMARK(oss.str().c_str()) {
169 oss <<
"Benchmark std::accumulate() with size: " << size <<
" (C++)";
171 BENCHMARK(oss.str().c_str()) {
172 std_sum = std::accumulate(vec.begin(), vec.end(), 0.0);
175 CHECK(vp_sum == Approx(std_sum));
178 oss <<
"Benchmark naive sum() with size: " << size;
179 double naive_sum = 0;
180 BENCHMARK(oss.str().c_str()) {
181 naive_sum = computeRegularSum(v);
184 CHECK(naive_sum == Approx(std_sum));
189 TEST_CASE(
"Benchmark vpColVector::sumSquare()",
"[benchmark]") {
192 const double val = 11;
194 CHECK(v.
sumSquare() == Approx(val*val).epsilon(std::numeric_limits<double>::epsilon()));
197 const unsigned int size = 11;
198 std::vector<double> vec(size);
200 for (
size_t i = 0; i < 11; i++) {
202 v[
static_cast<unsigned int>(i)] = vec[i];
204 CHECK(v.
sumSquare() == Approx(std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0)).epsilon(std::numeric_limits<double>::epsilon()));
207 if (g_runBenchmark) {
208 for (
auto size : g_sizes) {
212 std::ostringstream oss;
213 oss <<
"Benchmark vpColVector::sumSquare() with size: " << size <<
" (ViSP)";
214 double vp_sq_sum = 0;
215 BENCHMARK(oss.str().c_str()) {
221 oss <<
"Benchmark std::inner_product with size: " << size <<
" (C++)";
222 double std_sq_sum = 0;
223 BENCHMARK(oss.str().c_str()) {
224 std_sq_sum = std::inner_product(vec.begin(), vec.end(), vec.begin(), 0.0);
227 CHECK(vp_sq_sum == Approx(std_sq_sum));
230 oss <<
"Benchmark naive sumSquare() with size: " << size;
231 double naive_sq_sum = 0;
232 BENCHMARK(oss.str().c_str()) {
233 naive_sq_sum = computeRegularSumSquare(v);
236 CHECK(naive_sq_sum == Approx(std_sq_sum));
241 TEST_CASE(
"Benchmark vpColVector::stdev()",
"[benchmark]") {
248 CHECK(
vpColVector::stdev(v) == Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
251 const unsigned int size = 11;
252 std::vector<double> vec(size);
254 for (
size_t i = 0; i < 11; i++) {
256 v[
static_cast<unsigned int>(i)] = vec[i];
258 CHECK(
vpColVector::stdev(v) == Approx(stddev(vec)).epsilon(std::numeric_limits<double>::epsilon()));
261 if (g_runBenchmark) {
262 for (
auto size : g_sizes) {
266 std::ostringstream oss;
267 oss <<
"Benchmark vpColVector::stdev() with size: " << size <<
" (ViSP)";
268 double vp_stddev = 0;
269 BENCHMARK(oss.str().c_str()) {
275 oss <<
"Benchmark C++ stddev impl with size: " << size <<
" (C++)";
276 double std_stddev = 0;
277 BENCHMARK(oss.str().c_str()) {
278 std_stddev = stddev(vec);
281 CHECK(vp_stddev == Approx(std_stddev));
284 oss <<
"Benchmark naive stdev() with size: " << size;
285 double naive_stddev = 0;
286 BENCHMARK(oss.str().c_str()) {
287 naive_stddev = computeRegularStdev(v);
290 CHECK(naive_stddev == Approx(std_stddev));
295 TEST_CASE(
"Benchmark vpColVector::hadamard()",
"[benchmark]") {
305 CHECK(almostEqual(res1, res2));
308 const unsigned int size = 11;
309 std::vector<double> vec1(size), vec2(size);
310 for (
size_t i = 0; i < 11; i++) {
317 CHECK(almostEqual(res1, res2));
320 if (g_runBenchmark) {
321 for (
auto size : g_sizes) {
327 std::ostringstream oss;
328 oss <<
"Benchmark vpColVector::hadamard() with size: " << size <<
" (ViSP)";
330 BENCHMARK(oss.str().c_str()) {
336 oss <<
"Benchmark C++ element wise multiplication with size: " << size <<
" (C++)";
337 std::vector<double> std_res;
338 BENCHMARK(oss.str().c_str()) {
339 std_res = computeHadamard(vec1, vec2);
347 int main(
int argc,
char *argv[])
354 Catch::Session session;
357 using namespace Catch::clara;
358 auto cli = session.cli()
359 | Opt(g_runBenchmark)
367 session.applyCommandLine(argc, argv);
369 int numFailed = session.run();
static bool equal(double x, double y, double s=0.001)
unsigned int size() const
Return the number of elements of the 2D array.
vpColVector hadamard(const vpColVector &v) const
unsigned int getRows() const
std::vector< double > toStdVector()
Implementation of column vector and the associated operations.
static double stdev(const vpColVector &v, bool useBesselCorrection=false)