2 // Copyright (c) 2000-2002
3 // Joerg Walter, Mathias Koch
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)
9 // The authors gratefully acknowledge the support of
10 // GeNeSys mbH & Co. KG in producing this work.
15 template<class T
, int N
>
16 struct bench_c_outer_prod
{
19 void operator () (int runs
) const {
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
);
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
];
32 // sink_c_matrix<T, N, N> () (m);
33 BOOST_UBLAS_NOT_USED(m
);
35 footer
<value_type
> () (N
* N
, N
* N
, runs
, t
.elapsed ());
37 catch (std::exception
&e
) {
38 std::cout
<< e
.what () << std::endl
;
42 template<class M
, class V
, int N
>
43 struct bench_my_outer_prod
{
44 typedef typename
M::value_type value_type
;
46 void operator () (int runs
, safe_tag
) const {
49 ublas::matrix_range
<M
> mr (m
, ublas::range (0, N
), ublas::range (0, N
));
50 static V
v1 (N
), v2 (N
);
51 ublas::vector_range
<V
> vr1 (v1
, ublas::range (0, N
)),
52 vr2 (v2
, ublas::range (0, N
));
53 initialize_vector (vr1
);
54 initialize_vector (vr2
);
56 for (int i
= 0; i
< runs
; ++ i
) {
57 mr
= - ublas::outer_prod (vr1
, vr2
);
60 footer
<value_type
> () (N
* N
, N
* N
, runs
, t
.elapsed ());
62 catch (std::exception
&e
) {
63 std::cout
<< e
.what () << std::endl
;
66 void operator () (int runs
, fast_tag
) const {
69 ublas::matrix_range
<M
> mr (m
, ublas::range (0, N
), ublas::range (0, N
));
70 static V
v1 (N
), v2 (N
);
71 ublas::vector_range
<V
> vr1 (v1
, ublas::range (0, N
)),
72 vr2 (v2
, ublas::range (0, N
));
73 initialize_vector (vr1
);
74 initialize_vector (vr2
);
76 for (int i
= 0; i
< runs
; ++ i
) {
77 mr
.assign (- ublas::outer_prod (vr1
, vr2
));
80 footer
<value_type
> () (N
* N
, N
* N
, runs
, t
.elapsed ());
82 catch (std::exception
&e
) {
83 std::cout
<< e
.what () << std::endl
;
87 template<class M
, class V
, int N
>
88 struct bench_cpp_outer_prod
{
89 typedef typename
M::value_type value_type
;
91 void operator () (int runs
) const {
94 static V
v1 (N
), v2 (N
);
95 initialize_vector (v1
);
96 initialize_vector (v2
);
98 for (int i
= 0; i
< runs
; ++ i
) {
99 for (int j
= 0; j
< N
; ++ j
) {
100 for (int k
= 0; k
< N
; ++ k
) {
101 m
[N
* j
+ k
] = - v1
[j
] * v2
[k
];
106 footer
<value_type
> () (N
* N
, N
* N
, runs
, t
.elapsed ());
108 catch (std::exception
&e
) {
109 std::cout
<< e
.what () << std::endl
;
114 template<class T
, int N
>
115 struct bench_c_matrix_vector_prod
{
116 typedef T value_type
;
118 void operator () (int runs
) const {
120 static typename c_matrix_traits
<T
, N
, N
>::type m
;
121 static typename c_vector_traits
<T
, N
>::type v1
, v2
;
122 initialize_c_matrix
<T
, N
, N
> () (m
);
123 initialize_c_vector
<T
, N
> () (v1
);
125 for (int i
= 0; i
< runs
; ++ i
) {
126 for (int j
= 0; j
< N
; ++ j
) {
128 for (int k
= 0; k
< N
; ++ k
) {
129 v2
[j
] += m
[j
] [k
] * v1
[k
];
132 // sink_c_vector<T, N> () (v2);
134 footer
<value_type
> () (N
* N
, N
* (N
- 1), runs
, t
.elapsed ());
136 catch (std::exception
&e
) {
137 std::cout
<< e
.what () << std::endl
;
141 template<class M
, class V
, int N
>
142 struct bench_my_matrix_vector_prod
{
143 typedef typename
M::value_type value_type
;
145 void operator () (int runs
, safe_tag
) const {
148 ublas::matrix_range
<M
> mr (m
, ublas::range (0, N
), ublas::range (0, N
));
149 static V
v1 (N
), v2 (N
);
150 ublas::vector_range
<V
> vr1 (v1
, ublas::range (0, N
)),
151 vr2 (v2
, ublas::range (0, N
));
152 initialize_matrix (mr
);
153 initialize_vector (vr1
);
155 for (int i
= 0; i
< runs
; ++ i
) {
156 vr2
= ublas::prod (mr
, vr1
);
157 // sink_vector (vr2);
159 footer
<value_type
> () (N
* N
, N
* (N
- 1), runs
, t
.elapsed ());
161 catch (std::exception
&e
) {
162 std::cout
<< e
.what () << std::endl
;
165 void operator () (int runs
, fast_tag
) const {
168 ublas::matrix_range
<M
> mr (m
, ublas::range (0, N
), ublas::range (0, N
));
169 static V
v1 (N
), v2 (N
);
170 ublas::vector_range
<V
> vr1 (v1
, ublas::range (0, N
)),
171 vr2 (v2
, ublas::range (0, N
));
172 initialize_matrix (mr
);
173 initialize_vector (vr1
);
175 for (int i
= 0; i
< runs
; ++ i
) {
176 vr2
.assign (ublas::prod (mr
, vr1
));
177 // sink_vector (vr2);
179 footer
<value_type
> () (N
* N
, N
* (N
- 1), runs
, t
.elapsed ());
181 catch (std::exception
&e
) {
182 std::cout
<< e
.what () << std::endl
;
186 template<class M
, class V
, int N
>
187 struct bench_cpp_matrix_vector_prod
{
188 typedef typename
M::value_type value_type
;
190 void operator () (int runs
) const {
193 static V
v1 (N
), v2 (N
);
194 initialize_vector (m
);
195 initialize_vector (v1
);
197 for (int i
= 0; i
< runs
; ++ i
) {
198 for (int j
= 0; j
< N
; ++ j
) {
199 std::valarray
<value_type
> row (m
[std::slice (N
* j
, N
, 1)]);
200 v2
[j
] = (row
* v1
).sum ();
204 footer
<value_type
> () (N
* N
, N
* (N
- 1), runs
, t
.elapsed ());
206 catch (std::exception
&e
) {
207 std::cout
<< e
.what () << std::endl
;
212 template<class T
, int N
>
213 struct bench_c_matrix_add
{
214 typedef T value_type
;
216 void operator () (int runs
) const {
218 static typename c_matrix_traits
<T
, N
, N
>::type m1
, m2
, m3
;
219 initialize_c_matrix
<T
, N
, N
> () (m1
);
220 initialize_c_matrix
<T
, N
, N
> () (m2
);
222 for (int i
= 0; i
< runs
; ++ i
) {
223 for (int j
= 0; j
< N
; ++ j
) {
224 for (int k
= 0; k
< N
; ++ k
) {
225 m3
[j
] [k
] = - (m1
[j
] [k
] + m2
[j
] [k
]);
228 // sink_c_matrix<T, N, N> () (m3);
229 BOOST_UBLAS_NOT_USED(m3
);
231 footer
<value_type
> () (0, 2 * N
* N
, runs
, t
.elapsed ());
233 catch (std::exception
&e
) {
234 std::cout
<< e
.what () << std::endl
;
238 template<class M
, int N
>
239 struct bench_my_matrix_add
{
240 typedef typename
M::value_type value_type
;
242 void operator () (int runs
, safe_tag
) const {
244 static M
m1 (N
, N
), m2 (N
, N
), m3 (N
, N
);
245 initialize_matrix (m1
);
246 initialize_matrix (m2
);
248 for (int i
= 0; i
< runs
; ++ i
) {
252 footer
<value_type
> () (0, 2 * N
* N
, runs
, t
.elapsed ());
254 catch (std::exception
&e
) {
255 std::cout
<< e
.what () << std::endl
;
258 void operator () (int runs
, fast_tag
) const {
260 static M
m1 (N
, N
), m2 (N
, N
), m3 (N
, N
);
261 initialize_matrix (m1
);
262 initialize_matrix (m2
);
264 for (int i
= 0; i
< runs
; ++ i
) {
265 m3
.assign (- (m1
+ m2
));
268 footer
<value_type
> () (0, 2 * N
* N
, runs
, t
.elapsed ());
270 catch (std::exception
&e
) {
271 std::cout
<< e
.what () << std::endl
;
275 template<class M
, int N
>
276 struct bench_cpp_matrix_add
{
277 typedef typename
M::value_type value_type
;
279 void operator () (int runs
) const {
281 static M
m1 (N
* N
), m2 (N
* N
), m3 (N
* N
);
282 initialize_vector (m1
);
283 initialize_vector (m2
);
285 for (int i
= 0; i
< runs
; ++ i
) {
289 footer
<value_type
> () (0, 2 * N
* N
, runs
, t
.elapsed ());
291 catch (std::exception
&e
) {
292 std::cout
<< e
.what () << std::endl
;
297 // Benchmark O (n ^ 2)
298 template<class T
, int N
>
299 void bench_2
<T
, N
>::operator () (int runs
) {
302 header ("outer_prod");
305 bench_c_outer_prod
<T
, N
> () (runs
);
308 header ("c_matrix, c_vector safe");
309 bench_my_outer_prod
<ublas::c_matrix
<T
, N
, N
>,
310 ublas::c_vector
<T
, N
>, N
> () (runs
, safe_tag ());
312 header ("c_matrix, c_vector fast");
313 bench_my_outer_prod
<ublas::c_matrix
<T
, N
, N
>,
314 ublas::c_vector
<T
, N
>, N
> () (runs
, fast_tag ());
317 #ifdef USE_BOUNDED_ARRAY
318 header ("matrix<bounded_array>, vector<bounded_array> safe");
319 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >,
320 ublas::vector
<T
, ublas::bounded_array
<T
, N
> >, N
> () (runs
, safe_tag ());
322 header ("matrix<bounded_array>, vector<bounded_array> fast");
323 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >,
324 ublas::vector
<T
, ublas::bounded_array
<T
, N
> >, N
> () (runs
, fast_tag ());
327 #ifdef USE_UNBOUNDED_ARRAY
328 header ("matrix<unbounded_array>, vector<unbounded_array> safe");
329 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >,
330 ublas::vector
<T
, ublas::unbounded_array
<T
> >, N
> () (runs
, safe_tag ());
332 header ("matrix<unbounded_array>, vector<unbounded_array> fast");
333 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >,
334 ublas::vector
<T
, ublas::unbounded_array
<T
> >, N
> () (runs
, fast_tag ());
337 #ifdef USE_STD_VALARRAY
338 header ("matrix<std::valarray>, vector<std::valarray> safe");
339 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >,
340 ublas::vector
<T
, std::valarray
<T
> >, N
> () (runs
, safe_tag ());
342 header ("matrix<std::valarray>, vector<std::valarray> fast");
343 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >,
344 ublas::vector
<T
, std::valarray
<T
> >, N
> () (runs
, fast_tag ());
347 #ifdef USE_STD_VECTOR
348 header ("matrix<std::vector>, vector<std::vector> safe");
349 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >,
350 ublas::vector
<T
, std::vector
<T
> >, N
> () (runs
, safe_tag ());
352 header ("matrix<std::vector>, vector<std::vector> fast");
353 bench_my_outer_prod
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >,
354 ublas::vector
<T
, std::vector
<T
> >, N
> () (runs
, fast_tag ());
357 #ifdef USE_STD_VALARRAY
358 header ("std::valarray");
359 bench_cpp_outer_prod
<std::valarray
<T
>, std::valarray
<T
>, N
> () (runs
);
362 header ("prod (matrix, vector)");
365 bench_c_matrix_vector_prod
<T
, N
> () (runs
);
368 header ("c_matrix, c_vector safe");
369 bench_my_matrix_vector_prod
<ublas::c_matrix
<T
, N
, N
>,
370 ublas::c_vector
<T
, N
>, N
> () (runs
, safe_tag ());
372 header ("c_matrix, c_vector fast");
373 bench_my_matrix_vector_prod
<ublas::c_matrix
<T
, N
, N
>,
374 ublas::c_vector
<T
, N
>, N
> () (runs
, fast_tag ());
377 #ifdef USE_BOUNDED_ARRAY
378 header ("matrix<bounded_array>, vector<bounded_array> safe");
379 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >,
380 ublas::vector
<T
, ublas::bounded_array
<T
, N
> >, N
> () (runs
, safe_tag ());
382 header ("matrix<bounded_array>, vector<bounded_array> fast");
383 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >,
384 ublas::vector
<T
, ublas::bounded_array
<T
, N
> >, N
> () (runs
, fast_tag ());
387 #ifdef USE_UNBOUNDED_ARRAY
388 header ("matrix<unbounded_array>, vector<unbounded_array> safe");
389 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >,
390 ublas::vector
<T
, ublas::unbounded_array
<T
> >, N
> () (runs
, safe_tag ());
392 header ("matrix<unbounded_array>, vector<unbounded_array> fast");
393 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >,
394 ublas::vector
<T
, ublas::unbounded_array
<T
> >, N
> () (runs
, fast_tag ());
397 #ifdef USE_STD_VALARRAY
398 header ("matrix<std::valarray>, vector<std::valarray> safe");
399 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >,
400 ublas::vector
<T
, std::valarray
<T
> >, N
> () (runs
, safe_tag ());
402 header ("matrix<std::valarray>, vector<std::valarray> fast");
403 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >,
404 ublas::vector
<T
, std::valarray
<T
> >, N
> () (runs
, fast_tag ());
407 #ifdef USE_STD_VECTOR
408 header ("matrix<std::vector>, vector<std::vector> safe");
409 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >,
410 ublas::vector
<T
, std::vector
<T
> >, N
> () (runs
, safe_tag ());
412 header ("matrix<std::vector>, vector<std::vector> fast");
413 bench_my_matrix_vector_prod
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >,
414 ublas::vector
<T
, std::vector
<T
> >, N
> () (runs
, fast_tag ());
417 #ifdef USE_STD_VALARRAY
418 header ("std::valarray");
419 bench_cpp_matrix_vector_prod
<std::valarray
<T
>, std::valarray
<T
>, N
> () (runs
);
422 header ("matrix + matrix");
425 bench_c_matrix_add
<T
, N
> () (runs
);
428 header ("c_matrix safe");
429 bench_my_matrix_add
<ublas::c_matrix
<T
, N
, N
>, N
> () (runs
, safe_tag ());
431 header ("c_matrix fast");
432 bench_my_matrix_add
<ublas::c_matrix
<T
, N
, N
>, N
> () (runs
, fast_tag ());
435 #ifdef USE_BOUNDED_ARRAY
436 header ("matrix<bounded_array> safe");
437 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >, N
> () (runs
, safe_tag ());
439 header ("matrix<bounded_array> fast");
440 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, ublas::bounded_array
<T
, N
* N
> >, N
> () (runs
, fast_tag ());
443 #ifdef USE_UNBOUNDED_ARRAY
444 header ("matrix<unbounded_array> safe");
445 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >, N
> () (runs
, safe_tag ());
447 header ("matrix<unbounded_array> fast");
448 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, ublas::unbounded_array
<T
> >, N
> () (runs
, fast_tag ());
451 #ifdef USE_STD_VALARRAY
452 header ("matrix<std::valarray> safe");
453 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >, N
> () (runs
, safe_tag ());
455 header ("matrix<std::valarray> fast");
456 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, std::valarray
<T
> >, N
> () (runs
, fast_tag ());
459 #ifdef USE_STD_VECTOR
460 header ("matrix<std::vector> safe");
461 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >, N
> () (runs
, safe_tag ());
463 header ("matrix<std::vector> fast");
464 bench_my_matrix_add
<ublas::matrix
<T
, ublas::row_major
, std::vector
<T
> >, N
> () (runs
, fast_tag ());
467 #ifdef USE_STD_VALARRAY
468 header ("std::valarray");
469 bench_cpp_matrix_add
<std::valarray
<T
>, N
> () (runs
);
474 template struct bench_2
<float, 3>;
475 template struct bench_2
<float, 10>;
476 template struct bench_2
<float, 30>;
477 template struct bench_2
<float, 100>;
481 template struct bench_2
<double, 3>;
482 template struct bench_2
<double, 10>;
483 template struct bench_2
<double, 30>;
484 template struct bench_2
<double, 100>;
487 #ifdef USE_STD_COMPLEX
489 template struct bench_2
<std::complex<float>, 3>;
490 template struct bench_2
<std::complex<float>, 10>;
491 template struct bench_2
<std::complex<float>, 30>;
492 template struct bench_2
<std::complex<float>, 100>;
496 template struct bench_2
<std::complex<double>, 3>;
497 template struct bench_2
<std::complex<double>, 10>;
498 template struct bench_2
<std::complex<double>, 30>;
499 template struct bench_2
<std::complex<double>, 100>;