]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // Copyright (c) 2000-2002 | |
3 | // Joerg Walter, Mathias Koch | |
4 | // | |
5 | // Distributed under the Boost Software License, Version 1.0. (See | |
6 | // accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | // | |
9 | // The authors gratefully acknowledge the support of | |
10 | // GeNeSys mbH & Co. KG in producing this work. | |
11 | // | |
12 | ||
13 | #include "bench1.hpp" | |
14 | ||
15 | template<class T, int N> | |
16 | struct bench_c_outer_prod { | |
17 | typedef T value_type; | |
18 | ||
19 | void operator () (int runs) const { | |
20 | try { | |
21 | static typename c_matrix_traits<T, N, N>::type m; | |
22 | static typename c_vector_traits<T, N>::type v1, v2; | |
23 | initialize_c_vector<T, N> () (v1); | |
24 | initialize_c_vector<T, N> () (v2); | |
25 | boost::timer t; | |
26 | for (int i = 0; i < runs; ++ i) { | |
27 | for (int j = 0; j < N; ++ j) { | |
28 | for (int k = 0; k < N; ++ k) { | |
29 | m [j] [k] = - v1 [j] * v2 [k]; | |
30 | } | |
31 | } | |
32 | // sink_c_matrix<T, N, N> () (m); | |
33 | } | |
34 | BOOST_UBLAS_NOT_USED(m); | |
35 | ||
36 | footer<value_type> () (N * N, N * N, runs, t.elapsed ()); | |
37 | } | |
38 | catch (std::exception &e) { | |
39 | std::cout << e.what () << std::endl; | |
40 | } | |
41 | } | |
42 | }; | |
43 | template<class M, class V, int N> | |
44 | struct bench_my_outer_prod { | |
45 | typedef typename M::value_type value_type; | |
46 | ||
47 | void operator () (int runs, safe_tag) const { | |
48 | try { | |
49 | static M m (N, N); | |
50 | static V v1 (N), v2 (N); | |
51 | initialize_vector (v1); | |
52 | initialize_vector (v2); | |
53 | boost::timer t; | |
54 | for (int i = 0; i < runs; ++ i) { | |
55 | m = - ublas::outer_prod (v1, v2); | |
56 | // sink_matrix (m); | |
57 | } | |
58 | footer<value_type> () (N * N, N * N, runs, t.elapsed ()); | |
59 | } | |
60 | catch (std::exception &e) { | |
61 | std::cout << e.what () << std::endl; | |
62 | } | |
63 | } | |
64 | void operator () (int runs, fast_tag) const { | |
65 | try { | |
66 | static M m (N, N); | |
67 | static V v1 (N), v2 (N); | |
68 | initialize_vector (v1); | |
69 | initialize_vector (v2); | |
70 | boost::timer t; | |
71 | for (int i = 0; i < runs; ++ i) { | |
72 | m.assign (- ublas::outer_prod (v1, v2)); | |
73 | // sink_matrix (m); | |
74 | } | |
75 | footer<value_type> () (N * N, N * N, runs, t.elapsed ()); | |
76 | } | |
77 | catch (std::exception &e) { | |
78 | std::cout << e.what () << std::endl; | |
79 | } | |
80 | } | |
81 | }; | |
82 | template<class M, class V, int N> | |
83 | struct bench_cpp_outer_prod { | |
84 | typedef typename M::value_type value_type; | |
85 | ||
86 | void operator () (int runs) const { | |
87 | try { | |
88 | static M m (N * N); | |
89 | static V v1 (N), v2 (N); | |
90 | initialize_vector (v1); | |
91 | initialize_vector (v2); | |
92 | boost::timer t; | |
93 | for (int i = 0; i < runs; ++ i) { | |
94 | for (int j = 0; j < N; ++ j) { | |
95 | for (int k = 0; k < N; ++ k) { | |
96 | m [N * j + k] = - v1 [j] * v2 [k]; | |
97 | } | |
98 | } | |
99 | // sink_vector (m); | |
100 | } | |
101 | footer<value_type> () (N * N, N * N, runs, t.elapsed ()); | |
102 | } | |
103 | catch (std::exception &e) { | |
104 | std::cout << e.what () << std::endl; | |
105 | } | |
106 | } | |
107 | }; | |
108 | ||
109 | template<class T, int N> | |
110 | struct bench_c_matrix_vector_prod { | |
111 | typedef T value_type; | |
112 | ||
113 | void operator () (int runs) const { | |
114 | try { | |
115 | static typename c_matrix_traits<T, N, N>::type m; | |
116 | static typename c_vector_traits<T, N>::type v1, v2; | |
117 | initialize_c_matrix<T, N, N> () (m); | |
118 | initialize_c_vector<T, N> () (v1); | |
119 | boost::timer t; | |
120 | for (int i = 0; i < runs; ++ i) { | |
121 | for (int j = 0; j < N; ++ j) { | |
122 | v2 [j] = 0; | |
123 | for (int k = 0; k < N; ++ k) { | |
124 | v2 [j] += m [j] [k] * v1 [k]; | |
125 | } | |
126 | } | |
127 | // sink_c_vector<T, N> () (v2); | |
128 | } | |
129 | footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ()); | |
130 | } | |
131 | catch (std::exception &e) { | |
132 | std::cout << e.what () << std::endl; | |
133 | } | |
134 | } | |
135 | }; | |
136 | template<class M, class V, int N> | |
137 | struct bench_my_matrix_vector_prod { | |
138 | typedef typename M::value_type value_type; | |
139 | ||
140 | void operator () (int runs, safe_tag) const { | |
141 | try { | |
142 | static M m (N, N); | |
143 | static V v1 (N), v2 (N); | |
144 | initialize_matrix (m); | |
145 | initialize_vector (v1); | |
146 | boost::timer t; | |
147 | for (int i = 0; i < runs; ++ i) { | |
148 | v2 = ublas::prod (m, v1); | |
149 | // sink_vector (v2); | |
150 | } | |
151 | footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ()); | |
152 | } | |
153 | catch (std::exception &e) { | |
154 | std::cout << e.what () << std::endl; | |
155 | } | |
156 | } | |
157 | void operator () (int runs, fast_tag) const { | |
158 | try { | |
159 | static M m (N, N); | |
160 | static V v1 (N), v2 (N); | |
161 | initialize_matrix (m); | |
162 | initialize_vector (v1); | |
163 | boost::timer t; | |
164 | for (int i = 0; i < runs; ++ i) { | |
165 | v2.assign (ublas::prod (m, v1)); | |
166 | // sink_vector (v2); | |
167 | } | |
168 | footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ()); | |
169 | } | |
170 | catch (std::exception &e) { | |
171 | std::cout << e.what () << std::endl; | |
172 | } | |
173 | } | |
174 | }; | |
175 | template<class M, class V, int N> | |
176 | struct bench_cpp_matrix_vector_prod { | |
177 | typedef typename M::value_type value_type; | |
178 | ||
179 | void operator () (int runs) const { | |
180 | try { | |
181 | static M m (N * N); | |
182 | static V v1 (N), v2 (N); | |
183 | initialize_vector (m); | |
184 | initialize_vector (v1); | |
185 | boost::timer t; | |
186 | for (int i = 0; i < runs; ++ i) { | |
187 | for (int j = 0; j < N; ++ j) { | |
188 | std::valarray<value_type> row (m [std::slice (N * j, N, 1)]); | |
189 | v2 [j] = (row * v1).sum (); | |
190 | } | |
191 | // sink_vector (v2); | |
192 | } | |
193 | footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ()); | |
194 | } | |
195 | catch (std::exception &e) { | |
196 | std::cout << e.what () << std::endl; | |
197 | } | |
198 | } | |
199 | }; | |
200 | ||
201 | template<class T, int N> | |
202 | struct bench_c_matrix_add { | |
203 | typedef T value_type; | |
204 | ||
205 | void operator () (int runs) const { | |
206 | try { | |
207 | static typename c_matrix_traits<T, N, N>::type m1, m2, m3; | |
208 | initialize_c_matrix<T, N, N> () (m1); | |
209 | initialize_c_matrix<T, N, N> () (m2); | |
210 | boost::timer t; | |
211 | for (int i = 0; i < runs; ++ i) { | |
212 | for (int j = 0; j < N; ++ j) { | |
213 | for (int k = 0; k < N; ++ k) { | |
214 | m3 [j] [k] = - (m1 [j] [k] + m2 [j] [k]); | |
215 | } | |
216 | } | |
217 | // sink_c_matrix<T, N, N> () (m3); | |
218 | } | |
219 | BOOST_UBLAS_NOT_USED(m3); | |
220 | ||
221 | footer<value_type> () (0, 2 * N * N, runs, t.elapsed ()); | |
222 | } | |
223 | catch (std::exception &e) { | |
224 | std::cout << e.what () << std::endl; | |
225 | } | |
226 | } | |
227 | }; | |
228 | template<class M, int N> | |
229 | struct bench_my_matrix_add { | |
230 | typedef typename M::value_type value_type; | |
231 | ||
232 | void operator () (int runs, safe_tag) const { | |
233 | try { | |
234 | static M m1 (N, N), m2 (N, N), m3 (N, N); | |
235 | initialize_matrix (m1); | |
236 | initialize_matrix (m2); | |
237 | boost::timer t; | |
238 | for (int i = 0; i < runs; ++ i) { | |
239 | m3 = - (m1 + m2); | |
240 | // sink_matrix (m3); | |
241 | } | |
242 | footer<value_type> () (0, 2 * N * N, runs, t.elapsed ()); | |
243 | } | |
244 | catch (std::exception &e) { | |
245 | std::cout << e.what () << std::endl; | |
246 | } | |
247 | } | |
248 | void operator () (int runs, fast_tag) const { | |
249 | try { | |
250 | static M m1 (N, N), m2 (N, N), m3 (N, N); | |
251 | initialize_matrix (m1); | |
252 | initialize_matrix (m2); | |
253 | boost::timer t; | |
254 | for (int i = 0; i < runs; ++ i) { | |
255 | m3.assign (- (m1 + m2)); | |
256 | // sink_matrix (m3); | |
257 | } | |
258 | footer<value_type> () (0, 2 * N * N, runs, t.elapsed ()); | |
259 | } | |
260 | catch (std::exception &e) { | |
261 | std::cout << e.what () << std::endl; | |
262 | } | |
263 | } | |
264 | }; | |
265 | template<class M, int N> | |
266 | struct bench_cpp_matrix_add { | |
267 | typedef typename M::value_type value_type; | |
268 | ||
269 | void operator () (int runs) const { | |
270 | try { | |
271 | static M m1 (N * N), m2 (N * N), m3 (N * N); | |
272 | initialize_vector (m1); | |
273 | initialize_vector (m2); | |
274 | boost::timer t; | |
275 | for (int i = 0; i < runs; ++ i) { | |
276 | m3 = - (m1 + m2); | |
277 | // sink_vector (m3); | |
278 | } | |
279 | footer<value_type> () (0, 2 * N * N, runs, t.elapsed ()); | |
280 | } | |
281 | catch (std::exception &e) { | |
282 | std::cout << e.what () << std::endl; | |
283 | } | |
284 | } | |
285 | }; | |
286 | ||
287 | // Benchmark O (n ^ 2) | |
288 | template<class T, int N> | |
289 | void bench_2<T, N>::operator () (int runs) { | |
290 | header ("bench_2"); | |
291 | ||
292 | header ("outer_prod"); | |
293 | ||
294 | header ("C array"); | |
295 | bench_c_outer_prod<T, N> () (runs); | |
296 | ||
297 | #ifdef USE_C_ARRAY | |
298 | header ("c_matrix, c_vector safe"); | |
299 | bench_my_outer_prod<ublas::c_matrix<T, N, N>, | |
300 | ublas::c_vector<T, N>, N> () (runs, safe_tag ()); | |
301 | ||
302 | header ("c_matrix, c_vector fast"); | |
303 | bench_my_outer_prod<ublas::c_matrix<T, N, N>, | |
304 | ublas::c_vector<T, N>, N> () (runs, fast_tag ()); | |
305 | #endif | |
306 | ||
307 | #ifdef USE_BOUNDED_ARRAY | |
308 | header ("matrix<bounded_array>, vector<bounded_array> safe"); | |
309 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, | |
310 | ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ()); | |
311 | ||
312 | header ("matrix<bounded_array>, vector<bounded_array> fast"); | |
313 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, | |
314 | ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ()); | |
315 | #endif | |
316 | ||
317 | #ifdef USE_UNBOUNDED_ARRAY | |
318 | header ("matrix<unbounded_array>, vector<unbounded_array> safe"); | |
319 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, | |
320 | ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ()); | |
321 | ||
322 | header ("matrix<unbounded_array>, vector<unbounded_array> fast"); | |
323 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, | |
324 | ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ()); | |
325 | #endif | |
326 | ||
327 | #ifdef USE_STD_VALARRAY | |
328 | header ("matrix<std::valarray>, vector<std::valarray> safe"); | |
329 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, | |
330 | ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ()); | |
331 | ||
332 | header ("matrix<std::valarray>, vector<std::valarray> fast"); | |
333 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, | |
334 | ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ()); | |
335 | #endif | |
336 | ||
337 | #ifdef USE_STD_VECTOR | |
338 | header ("matrix<std::vector>, vector<std::vector> safe"); | |
339 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, | |
340 | ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ()); | |
341 | ||
342 | header ("matrix<std::vector>, vector<std::vector> fast"); | |
343 | bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, | |
344 | ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ()); | |
345 | #endif | |
346 | ||
347 | #ifdef USE_STD_VALARRAY | |
348 | header ("std::valarray"); | |
349 | bench_cpp_outer_prod<std::valarray<T>, std::valarray<T>, N> () (runs); | |
350 | #endif | |
351 | ||
352 | header ("prod (matrix, vector)"); | |
353 | ||
354 | header ("C array"); | |
355 | bench_c_matrix_vector_prod<T, N> () (runs); | |
356 | ||
357 | #ifdef USE_C_ARRAY | |
358 | header ("c_matrix, c_vector safe"); | |
359 | bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>, | |
360 | ublas::c_vector<T, N>, N> () (runs, safe_tag ()); | |
361 | ||
362 | header ("c_matrix, c_vector fast"); | |
363 | bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>, | |
364 | ublas::c_vector<T, N>, N> () (runs, fast_tag ()); | |
365 | #endif | |
366 | ||
367 | #ifdef USE_BOUNDED_ARRAY | |
368 | header ("matrix<bounded_array>, vector<bounded_array> safe"); | |
369 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, | |
370 | ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ()); | |
371 | ||
372 | header ("matrix<bounded_array>, vector<bounded_array> fast"); | |
373 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, | |
374 | ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ()); | |
375 | #endif | |
376 | ||
377 | #ifdef USE_UNBOUNDED_ARRAY | |
378 | header ("matrix<unbounded_array>, vector<unbounded_array> safe"); | |
379 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, | |
380 | ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ()); | |
381 | ||
382 | header ("matrix<unbounded_array>, vector<unbounded_array> fast"); | |
383 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, | |
384 | ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ()); | |
385 | #endif | |
386 | ||
387 | #ifdef USE_STD_VALARRAY | |
388 | header ("matrix<std::valarray>, vector<std::valarray> safe"); | |
389 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, | |
390 | ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ()); | |
391 | ||
392 | header ("matrix<std::valarray>, vector<std::valarray> fast"); | |
393 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, | |
394 | ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ()); | |
395 | #endif | |
396 | ||
397 | #ifdef USE_STD_VECTOR | |
398 | header ("matrix<std::vector>, vector<std::vector> safe"); | |
399 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, | |
400 | ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ()); | |
401 | ||
402 | header ("matrix<std::vector>, vector<std::vector> fast"); | |
403 | bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, | |
404 | ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ()); | |
405 | #endif | |
406 | ||
407 | #ifdef USE_STD_VALARRAY | |
408 | header ("std::valarray"); | |
409 | bench_cpp_matrix_vector_prod<std::valarray<T>, std::valarray<T>, N> () (runs); | |
410 | #endif | |
411 | ||
412 | header ("matrix + matrix"); | |
413 | ||
414 | header ("C array"); | |
415 | bench_c_matrix_add<T, N> () (runs); | |
416 | ||
417 | #ifdef USE_C_ARRAY | |
418 | header ("c_matrix safe"); | |
419 | bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, safe_tag ()); | |
420 | ||
421 | header ("c_matrix fast"); | |
422 | bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, fast_tag ()); | |
423 | #endif | |
424 | ||
425 | #ifdef USE_BOUNDED_ARRAY | |
426 | header ("matrix<bounded_array> safe"); | |
427 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, safe_tag ()); | |
428 | ||
429 | header ("matrix<bounded_array> fast"); | |
430 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, fast_tag ()); | |
431 | #endif | |
432 | ||
433 | #ifdef USE_UNBOUNDED_ARRAY | |
434 | header ("matrix<unbounded_array> safe"); | |
435 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, safe_tag ()); | |
436 | ||
437 | header ("matrix<unbounded_array> fast"); | |
438 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, fast_tag ()); | |
439 | #endif | |
440 | ||
441 | #ifdef USE_STD_VALARRAY | |
442 | header ("matrix<std::valarray> safe"); | |
443 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, safe_tag ()); | |
444 | ||
445 | header ("matrix<std::valarray> fast"); | |
446 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, fast_tag ()); | |
447 | #endif | |
448 | ||
449 | #ifdef USE_STD_VECTOR | |
450 | header ("matrix<std::vector> safe"); | |
451 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, safe_tag ()); | |
452 | ||
453 | header ("matrix<std::vector> fast"); | |
454 | bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, fast_tag ()); | |
455 | #endif | |
456 | ||
457 | #ifdef USE_STD_VALARRAY | |
458 | header ("std::valarray"); | |
459 | bench_cpp_matrix_add<std::valarray<T>, N> () (runs); | |
460 | #endif | |
461 | } | |
462 | ||
463 | #ifdef USE_FLOAT | |
464 | template struct bench_2<float, 3>; | |
465 | template struct bench_2<float, 10>; | |
466 | template struct bench_2<float, 30>; | |
467 | template struct bench_2<float, 100>; | |
468 | #endif | |
469 | ||
470 | #ifdef USE_DOUBLE | |
471 | template struct bench_2<double, 3>; | |
472 | template struct bench_2<double, 10>; | |
473 | template struct bench_2<double, 30>; | |
474 | template struct bench_2<double, 100>; | |
475 | #endif | |
476 | ||
477 | #ifdef USE_STD_COMPLEX | |
478 | #ifdef USE_FLOAT | |
479 | template struct bench_2<std::complex<float>, 3>; | |
480 | template struct bench_2<std::complex<float>, 10>; | |
481 | template struct bench_2<std::complex<float>, 30>; | |
482 | template struct bench_2<std::complex<float>, 100>; | |
483 | #endif | |
484 | ||
485 | #ifdef USE_DOUBLE | |
486 | template struct bench_2<std::complex<double>, 3>; | |
487 | template struct bench_2<std::complex<double>, 10>; | |
488 | template struct bench_2<std::complex<double>, 30>; | |
489 | template struct bench_2<std::complex<double>, 100>; | |
490 | #endif | |
491 | #endif |