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.
13 #ifndef _BOOST_UBLAS_BLAS_
14 #define _BOOST_UBLAS_BLAS_
16 #include <boost/numeric/ublas/traits.hpp>
18 namespace boost
{ namespace numeric
{ namespace ublas
{
22 /** \namespace boost::numeric::ublas::blas_1
23 \brief wrapper functions for level 1 blas
27 /** \brief 1-Norm: \f$\sum_i |x_i|\f$
31 typename type_traits
<typename
V::value_type
>::real_type
35 /** \brief 2-Norm: \f$\sum_i |x_i|^2\f$
39 typename type_traits
<typename
V::value_type
>::real_type
43 /** \brief element with larges absolute value: \f$\max_i |x_i|\f$
47 typename type_traits
<typename
V::value_type
>::real_type
52 /** \brief inner product of vectors \a v1 and \a v2
55 template<class V1
, class V2
>
56 typename promote_traits
<typename
V1::value_type
, typename
V2::value_type
>::promote_type
57 dot (const V1
&v1
, const V2
&v2
) {
58 return inner_prod (v1
, v2
);
61 /** \brief copy vector \a v2 to \a v1
64 template<class V1
, class V2
>
66 copy (V1
&v1
, const V2
&v2
) {
67 return v1
.assign (v2
);
70 /** \brief swap vectors \a v1 and \a v2
73 template<class V1
, class V2
>
74 void swap (V1
&v1
, V2
&v2
) {
78 /** \brief scale vector \a v with scalar \a t
81 template<class V
, class T
>
83 scal (V
&v
, const T
&t
) {
87 /** \brief compute \a v1 = \a v1 + \a t * \a v2
90 template<class V1
, class T
, class V2
>
92 axpy (V1
&v1
, const T
&t
, const V2
&v2
) {
93 return v1
.plus_assign (t
* v2
);
96 /** \brief apply plane rotation
99 template<class T1
, class V1
, class T2
, class V2
>
101 rot (const T1
&t1
, V1
&v1
, const T2
&t2
, V2
&v2
) {
102 typedef typename promote_traits
<typename
V1::value_type
, typename
V2::value_type
>::promote_type promote_type
;
103 vector
<promote_type
> vt (t1
* v1
+ t2
* v2
);
104 v2
.assign (- t2
* v1
+ t1
* v2
);
112 /** \namespace boost::numeric::ublas::blas_2
113 \brief wrapper functions for level 2 blas
116 /** \brief multiply vector \a v with triangular matrix \a m
118 \todo: check that matrix is really triangular
120 template<class V
, class M
>
122 tmv (V
&v
, const M
&m
) {
123 return v
= prod (m
, v
);
126 /** \brief solve \a m \a x = \a v in place, \a m is triangular matrix
129 template<class V
, class M
, class C
>
131 tsv (V
&v
, const M
&m
, C
) {
132 return v
= solve (m
, v
, C ());
135 /** \brief compute \a v1 = \a t1 * \a v1 + \a t2 * (\a m * \a v2)
138 template<class V1
, class T1
, class T2
, class M
, class V2
>
140 gmv (V1
&v1
, const T1
&t1
, const T2
&t2
, const M
&m
, const V2
&v2
) {
141 return v1
= t1
* v1
+ t2
* prod (m
, v2
);
144 /** \brief rank 1 update: \a m = \a m + \a t * (\a v1 * \a v2<sup>T</sup>)
147 template<class M
, class T
, class V1
, class V2
>
149 gr (M
&m
, const T
&t
, const V1
&v1
, const V2
&v2
) {
150 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
151 return m
+= t
* outer_prod (v1
, v2
);
153 return m
= m
+ t
* outer_prod (v1
, v2
);
157 /** \brief symmetric rank 1 update: \a m = \a m + \a t * (\a v * \a v<sup>T</sup>)
160 template<class M
, class T
, class V
>
162 sr (M
&m
, const T
&t
, const V
&v
) {
163 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
164 return m
+= t
* outer_prod (v
, v
);
166 return m
= m
+ t
* outer_prod (v
, v
);
169 /** \brief hermitian rank 1 update: \a m = \a m + \a t * (\a v * \a v<sup>H</sup>)
172 template<class M
, class T
, class V
>
174 hr (M
&m
, const T
&t
, const V
&v
) {
175 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
176 return m
+= t
* outer_prod (v
, conj (v
));
178 return m
= m
+ t
* outer_prod (v
, conj (v
));
182 /** \brief symmetric rank 2 update: \a m = \a m + \a t *
183 (\a v1 * \a v2<sup>T</sup> + \a v2 * \a v1<sup>T</sup>)
186 template<class M
, class T
, class V1
, class V2
>
188 sr2 (M
&m
, const T
&t
, const V1
&v1
, const V2
&v2
) {
189 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
190 return m
+= t
* (outer_prod (v1
, v2
) + outer_prod (v2
, v1
));
192 return m
= m
+ t
* (outer_prod (v1
, v2
) + outer_prod (v2
, v1
));
195 /** \brief hermitian rank 2 update: \a m = \a m +
196 \a t * (\a v1 * \a v2<sup>H</sup>)
197 + \a v2 * (\a t * \a v1)<sup>H</sup>)
200 template<class M
, class T
, class V1
, class V2
>
202 hr2 (M
&m
, const T
&t
, const V1
&v1
, const V2
&v2
) {
203 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
204 return m
+= t
* outer_prod (v1
, conj (v2
)) + type_traits
<T
>::conj (t
) * outer_prod (v2
, conj (v1
));
206 return m
= m
+ t
* outer_prod (v1
, conj (v2
)) + type_traits
<T
>::conj (t
) * outer_prod (v2
, conj (v1
));
214 /** \namespace boost::numeric::ublas::blas_3
215 \brief wrapper functions for level 3 blas
218 /** \brief triangular matrix multiplication
221 template<class M1
, class T
, class M2
, class M3
>
223 tmm (M1
&m1
, const T
&t
, const M2
&m2
, const M3
&m3
) {
224 return m1
= t
* prod (m2
, m3
);
227 /** \brief triangular solve \a m2 * \a x = \a t * \a m1 in place,
228 \a m2 is a triangular matrix
231 template<class M1
, class T
, class M2
, class C
>
233 tsm (M1
&m1
, const T
&t
, const M2
&m2
, C
) {
234 return m1
= solve (m2
, t
* m1
, C ());
237 /** \brief general matrix multiplication
240 template<class M1
, class T1
, class T2
, class M2
, class M3
>
242 gmm (M1
&m1
, const T1
&t1
, const T2
&t2
, const M2
&m2
, const M3
&m3
) {
243 return m1
= t1
* m1
+ t2
* prod (m2
, m3
);
246 /** \brief symmetric rank k update: \a m1 = \a t * \a m1 +
247 \a t2 * (\a m2 * \a m2<sup>T</sup>)
251 template<class M1
, class T1
, class T2
, class M2
>
253 srk (M1
&m1
, const T1
&t1
, const T2
&t2
, const M2
&m2
) {
254 return m1
= t1
* m1
+ t2
* prod (m2
, trans (m2
));
256 /** \brief hermitian rank k update: \a m1 = \a t * \a m1 +
257 \a t2 * (\a m2 * \a m2<sup>H</sup>)
261 template<class M1
, class T1
, class T2
, class M2
>
263 hrk (M1
&m1
, const T1
&t1
, const T2
&t2
, const M2
&m2
) {
264 return m1
= t1
* m1
+ t2
* prod (m2
, herm (m2
));
267 /** \brief generalized symmetric rank k update:
268 \a m1 = \a t1 * \a m1 + \a t2 * (\a m2 * \a m3<sup>T</sup>)
269 + \a t2 * (\a m3 * \a m2<sup>T</sup>)
273 template<class M1
, class T1
, class T2
, class M2
, class M3
>
275 sr2k (M1
&m1
, const T1
&t1
, const T2
&t2
, const M2
&m2
, const M3
&m3
) {
276 return m1
= t1
* m1
+ t2
* (prod (m2
, trans (m3
)) + prod (m3
, trans (m2
)));
278 /** \brief generalized hermitian rank k update:
279 \a m1 = \a t1 * \a m1 + \a t2 * (\a m2 * \a m3<sup>H</sup>)
280 + (\a m3 * (\a t2 * \a m2)<sup>H</sup>)
284 template<class M1
, class T1
, class T2
, class M2
, class M3
>
286 hr2k (M1
&m1
, const T1
&t1
, const T2
&t2
, const M2
&m2
, const M3
&m3
) {
287 return m1
= t1
* m1
+ t2
* prod (m2
, herm (m3
)) + type_traits
<T2
>::conj (t2
) * prod (m3
, herm (m2
));