blas.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // The authors gratefully acknowledge the support of
  8. // GeNeSys mbH & Co. KG in producing this work.
  9. #ifndef _BOOST_UBLAS_BLAS_
  10. #define _BOOST_UBLAS_BLAS_
  11. #include <boost/numeric/ublas/traits.hpp>
  12. namespace boost { namespace numeric { namespace ublas {
  13. /** Interface and implementation of BLAS level 1
  14. * This includes functions which perform \b vector-vector operations.
  15. * More information about BLAS can be found at
  16. * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
  17. */
  18. namespace blas_1 {
  19. /** 1-Norm: \f$\sum_i |x_i|\f$ (also called \f$\mathcal{L}_1\f$ or Manhattan norm)
  20. *
  21. * \param v a vector or vector expression
  22. * \return the 1-Norm with type of the vector's type
  23. *
  24. * \tparam V type of the vector (not needed by default)
  25. */
  26. template<class V>
  27. typename type_traits<typename V::value_type>::real_type
  28. asum (const V &v) {
  29. return norm_1 (v);
  30. }
  31. /** 2-Norm: \f$\sum_i |x_i|^2\f$ (also called \f$\mathcal{L}_2\f$ or Euclidean norm)
  32. *
  33. * \param v a vector or vector expression
  34. * \return the 2-Norm with type of the vector's type
  35. *
  36. * \tparam V type of the vector (not needed by default)
  37. */
  38. template<class V>
  39. typename type_traits<typename V::value_type>::real_type
  40. nrm2 (const V &v) {
  41. return norm_2 (v);
  42. }
  43. /** Infinite-norm: \f$\max_i |x_i|\f$ (also called \f$\mathcal{L}_\infty\f$ norm)
  44. *
  45. * \param v a vector or vector expression
  46. * \return the Infinite-Norm with type of the vector's type
  47. *
  48. * \tparam V type of the vector (not needed by default)
  49. */
  50. template<class V>
  51. typename type_traits<typename V::value_type>::real_type
  52. amax (const V &v) {
  53. return norm_inf (v);
  54. }
  55. /** Inner product of vectors \f$v_1\f$ and \f$v_2\f$
  56. *
  57. * \param v1 first vector of the inner product
  58. * \param v2 second vector of the inner product
  59. * \return the inner product of the type of the most generic type of the 2 vectors
  60. *
  61. * \tparam V1 type of first vector (not needed by default)
  62. * \tparam V2 type of second vector (not needed by default)
  63. */
  64. template<class V1, class V2>
  65. typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type
  66. dot (const V1 &v1, const V2 &v2) {
  67. return inner_prod (v1, v2);
  68. }
  69. /** Copy vector \f$v_2\f$ to \f$v_1\f$
  70. *
  71. * \param v1 target vector
  72. * \param v2 source vector
  73. * \return a reference to the target vector
  74. *
  75. * \tparam V1 type of first vector (not needed by default)
  76. * \tparam V2 type of second vector (not needed by default)
  77. */
  78. template<class V1, class V2>
  79. V1 & copy (V1 &v1, const V2 &v2)
  80. {
  81. return v1.assign (v2);
  82. }
  83. /** Swap vectors \f$v_1\f$ and \f$v_2\f$
  84. *
  85. * \param v1 first vector
  86. * \param v2 second vector
  87. *
  88. * \tparam V1 type of first vector (not needed by default)
  89. * \tparam V2 type of second vector (not needed by default)
  90. */
  91. template<class V1, class V2>
  92. void swap (V1 &v1, V2 &v2)
  93. {
  94. v1.swap (v2);
  95. }
  96. /** scale vector \f$v\f$ with scalar \f$t\f$
  97. *
  98. * \param v vector to be scaled
  99. * \param t the scalar
  100. * \return \c t*v
  101. *
  102. * \tparam V type of the vector (not needed by default)
  103. * \tparam T type of the scalar (not needed by default)
  104. */
  105. template<class V, class T>
  106. V & scal (V &v, const T &t)
  107. {
  108. return v *= t;
  109. }
  110. /** Compute \f$v_1= v_1 + t.v_2\f$
  111. *
  112. * \param v1 target and first vector
  113. * \param t the scalar
  114. * \param v2 second vector
  115. * \return a reference to the first and target vector
  116. *
  117. * \tparam V1 type of the first vector (not needed by default)
  118. * \tparam T type of the scalar (not needed by default)
  119. * \tparam V2 type of the second vector (not needed by default)
  120. */
  121. template<class V1, class T, class V2>
  122. V1 & axpy (V1 &v1, const T &t, const V2 &v2)
  123. {
  124. return v1.plus_assign (t * v2);
  125. }
  126. /** Performs rotation of points in the plane and assign the result to the first vector
  127. *
  128. * Each point is defined as a pair \c v1(i) and \c v2(i), being respectively
  129. * the \f$x\f$ and \f$y\f$ coordinates. The parameters \c t1 and \t2 are respectively
  130. * the cosine and sine of the angle of the rotation.
  131. * Results are not returned but directly written into \c v1.
  132. *
  133. * \param t1 cosine of the rotation
  134. * \param v1 vector of \f$x\f$ values
  135. * \param t2 sine of the rotation
  136. * \param v2 vector of \f$y\f$ values
  137. *
  138. * \tparam T1 type of the cosine value (not needed by default)
  139. * \tparam V1 type of the \f$x\f$ vector (not needed by default)
  140. * \tparam T2 type of the sine value (not needed by default)
  141. * \tparam V2 type of the \f$y\f$ vector (not needed by default)
  142. */
  143. template<class T1, class V1, class T2, class V2>
  144. void rot (const T1 &t1, V1 &v1, const T2 &t2, V2 &v2)
  145. {
  146. typedef typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type promote_type;
  147. vector<promote_type> vt (t1 * v1 + t2 * v2);
  148. v2.assign (- t2 * v1 + t1 * v2);
  149. v1.assign (vt);
  150. }
  151. }
  152. /** \brief Interface and implementation of BLAS level 2
  153. * This includes functions which perform \b matrix-vector operations.
  154. * More information about BLAS can be found at
  155. * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
  156. */
  157. namespace blas_2 {
  158. /** \brief multiply vector \c v with triangular matrix \c m
  159. *
  160. * \param v a vector
  161. * \param m a triangular matrix
  162. * \return the result of the product
  163. *
  164. * \tparam V type of the vector (not needed by default)
  165. * \tparam M type of the matrix (not needed by default)
  166. */
  167. template<class V, class M>
  168. V & tmv (V &v, const M &m)
  169. {
  170. return v = prod (m, v);
  171. }
  172. /** \brief solve \f$m.x = v\f$ in place, where \c m is a triangular matrix
  173. *
  174. * \param v a vector
  175. * \param m a matrix
  176. * \param C (this parameter is not needed)
  177. * \return a result vector from the above operation
  178. *
  179. * \tparam V type of the vector (not needed by default)
  180. * \tparam M type of the matrix (not needed by default)
  181. * \tparam C n/a
  182. */
  183. template<class V, class M, class C>
  184. V & tsv (V &v, const M &m, C)
  185. {
  186. return v = solve (m, v, C ());
  187. }
  188. /** \brief compute \f$ v_1 = t_1.v_1 + t_2.(m.v_2)\f$, a general matrix-vector product
  189. *
  190. * \param v1 a vector
  191. * \param t1 a scalar
  192. * \param t2 another scalar
  193. * \param m a matrix
  194. * \param v2 another vector
  195. * \return the vector \c v1 with the result from the above operation
  196. *
  197. * \tparam V1 type of first vector (not needed by default)
  198. * \tparam T1 type of first scalar (not needed by default)
  199. * \tparam T2 type of second scalar (not needed by default)
  200. * \tparam M type of matrix (not needed by default)
  201. * \tparam V2 type of second vector (not needed by default)
  202. */
  203. template<class V1, class T1, class T2, class M, class V2>
  204. V1 & gmv (V1 &v1, const T1 &t1, const T2 &t2, const M &m, const V2 &v2)
  205. {
  206. return v1 = t1 * v1 + t2 * prod (m, v2);
  207. }
  208. /** \brief Rank 1 update: \f$ m = m + t.(v_1.v_2^T)\f$
  209. *
  210. * \param m a matrix
  211. * \param t a scalar
  212. * \param v1 a vector
  213. * \param v2 another vector
  214. * \return a matrix with the result from the above operation
  215. *
  216. * \tparam M type of matrix (not needed by default)
  217. * \tparam T type of scalar (not needed by default)
  218. * \tparam V1 type of first vector (not needed by default)
  219. * \tparam V2type of second vector (not needed by default)
  220. */
  221. template<class M, class T, class V1, class V2>
  222. M & gr (M &m, const T &t, const V1 &v1, const V2 &v2)
  223. {
  224. #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
  225. return m += t * outer_prod (v1, v2);
  226. #else
  227. return m = m + t * outer_prod (v1, v2);
  228. #endif
  229. }
  230. /** \brief symmetric rank 1 update: \f$m = m + t.(v.v^T)\f$
  231. *
  232. * \param m a matrix
  233. * \param t a scalar
  234. * \param v a vector
  235. * \return a matrix with the result from the above operation
  236. *
  237. * \tparam M type of matrix (not needed by default)
  238. * \tparam T type of scalar (not needed by default)
  239. * \tparam V type of vector (not needed by default)
  240. */
  241. template<class M, class T, class V>
  242. M & sr (M &m, const T &t, const V &v)
  243. {
  244. #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
  245. return m += t * outer_prod (v, v);
  246. #else
  247. return m = m + t * outer_prod (v, v);
  248. #endif
  249. }
  250. /** \brief hermitian rank 1 update: \f$m = m + t.(v.v^H)\f$
  251. *
  252. * \param m a matrix
  253. * \param t a scalar
  254. * \param v a vector
  255. * \return a matrix with the result from the above operation
  256. *
  257. * \tparam M type of matrix (not needed by default)
  258. * \tparam T type of scalar (not needed by default)
  259. * \tparam V type of vector (not needed by default)
  260. */
  261. template<class M, class T, class V>
  262. M & hr (M &m, const T &t, const V &v)
  263. {
  264. #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
  265. return m += t * outer_prod (v, conj (v));
  266. #else
  267. return m = m + t * outer_prod (v, conj (v));
  268. #endif
  269. }
  270. /** \brief symmetric rank 2 update: \f$ m=m+ t.(v_1.v_2^T + v_2.v_1^T)\f$
  271. *
  272. * \param m a matrix
  273. * \param t a scalar
  274. * \param v1 a vector
  275. * \param v2 another vector
  276. * \return a matrix with the result from the above operation
  277. *
  278. * \tparam M type of matrix (not needed by default)
  279. * \tparam T type of scalar (not needed by default)
  280. * \tparam V1 type of first vector (not needed by default)
  281. * \tparam V2type of second vector (not needed by default)
  282. */
  283. template<class M, class T, class V1, class V2>
  284. M & sr2 (M &m, const T &t, const V1 &v1, const V2 &v2)
  285. {
  286. #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
  287. return m += t * (outer_prod (v1, v2) + outer_prod (v2, v1));
  288. #else
  289. return m = m + t * (outer_prod (v1, v2) + outer_prod (v2, v1));
  290. #endif
  291. }
  292. /** \brief hermitian rank 2 update: \f$m=m+t.(v_1.v_2^H) + v_2.(t.v_1)^H)\f$
  293. *
  294. * \param m a matrix
  295. * \param t a scalar
  296. * \param v1 a vector
  297. * \param v2 another vector
  298. * \return a matrix with the result from the above operation
  299. *
  300. * \tparam M type of matrix (not needed by default)
  301. * \tparam T type of scalar (not needed by default)
  302. * \tparam V1 type of first vector (not needed by default)
  303. * \tparam V2type of second vector (not needed by default)
  304. */
  305. template<class M, class T, class V1, class V2>
  306. M & hr2 (M &m, const T &t, const V1 &v1, const V2 &v2)
  307. {
  308. #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
  309. return m += t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
  310. #else
  311. return m = m + t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
  312. #endif
  313. }
  314. }
  315. /** \brief Interface and implementation of BLAS level 3
  316. * This includes functions which perform \b matrix-matrix operations.
  317. * More information about BLAS can be found at
  318. * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
  319. */
  320. namespace blas_3 {
  321. /** \brief triangular matrix multiplication \f$m_1=t.m_2.m_3\f$ where \f$m_2\f$ and \f$m_3\f$ are triangular
  322. *
  323. * \param m1 a matrix for storing result
  324. * \param t a scalar
  325. * \param m2 a triangular matrix
  326. * \param m3 a triangular matrix
  327. * \return the matrix \c m1
  328. *
  329. * \tparam M1 type of the result matrix (not needed by default)
  330. * \tparam T type of the scalar (not needed by default)
  331. * \tparam M2 type of the first triangular matrix (not needed by default)
  332. * \tparam M3 type of the second triangular matrix (not needed by default)
  333. *
  334. */
  335. template<class M1, class T, class M2, class M3>
  336. M1 & tmm (M1 &m1, const T &t, const M2 &m2, const M3 &m3)
  337. {
  338. return m1 = t * prod (m2, m3);
  339. }
  340. /** \brief triangular solve \f$ m_2.x = t.m_1\f$ in place, \f$m_2\f$ is a triangular matrix
  341. *
  342. * \param m1 a matrix
  343. * \param t a scalar
  344. * \param m2 a triangular matrix
  345. * \param C (not used)
  346. * \return the \f$m_1\f$ matrix
  347. *
  348. * \tparam M1 type of the first matrix (not needed by default)
  349. * \tparam T type of the scalar (not needed by default)
  350. * \tparam M2 type of the triangular matrix (not needed by default)
  351. * \tparam C (n/a)
  352. */
  353. template<class M1, class T, class M2, class C>
  354. M1 & tsm (M1 &m1, const T &t, const M2 &m2, C)
  355. {
  356. return m1 = solve (m2, t * m1, C ());
  357. }
  358. /** \brief general matrix multiplication \f$m_1=t_1.m_1 + t_2.m_2.m_3\f$
  359. *
  360. * \param m1 first matrix
  361. * \param t1 first scalar
  362. * \param t2 second scalar
  363. * \param m2 second matrix
  364. * \param m3 third matrix
  365. * \return the matrix \c m1
  366. *
  367. * \tparam M1 type of the first matrix (not needed by default)
  368. * \tparam T1 type of the first scalar (not needed by default)
  369. * \tparam T2 type of the second scalar (not needed by default)
  370. * \tparam M2 type of the second matrix (not needed by default)
  371. * \tparam M3 type of the third matrix (not needed by default)
  372. */
  373. template<class M1, class T1, class T2, class M2, class M3>
  374. M1 & gmm (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
  375. {
  376. return m1 = t1 * m1 + t2 * prod (m2, m3);
  377. }
  378. /** \brief symmetric rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m_2^T)\f$
  379. *
  380. * \param m1 first matrix
  381. * \param t1 first scalar
  382. * \param t2 second scalar
  383. * \param m2 second matrix
  384. * \return matrix \c m1
  385. *
  386. * \tparam M1 type of the first matrix (not needed by default)
  387. * \tparam T1 type of the first scalar (not needed by default)
  388. * \tparam T2 type of the second scalar (not needed by default)
  389. * \tparam M2 type of the second matrix (not needed by default)
  390. * \todo use opb_prod()
  391. */
  392. template<class M1, class T1, class T2, class M2>
  393. M1 & srk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2)
  394. {
  395. return m1 = t1 * m1 + t2 * prod (m2, trans (m2));
  396. }
  397. /** \brief hermitian rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m2^H)\f$
  398. *
  399. * \param m1 first matrix
  400. * \param t1 first scalar
  401. * \param t2 second scalar
  402. * \param m2 second matrix
  403. * \return matrix \c m1
  404. *
  405. * \tparam M1 type of the first matrix (not needed by default)
  406. * \tparam T1 type of the first scalar (not needed by default)
  407. * \tparam T2 type of the second scalar (not needed by default)
  408. * \tparam M2 type of the second matrix (not needed by default)
  409. * \todo use opb_prod()
  410. */
  411. template<class M1, class T1, class T2, class M2>
  412. M1 & hrk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2)
  413. {
  414. return m1 = t1 * m1 + t2 * prod (m2, herm (m2));
  415. }
  416. /** \brief generalized symmetric rank \a k update: \f$m_1=t_1.m_1+t_2.(m_2.m3^T)+t_2.(m_3.m2^T)\f$
  417. *
  418. * \param m1 first matrix
  419. * \param t1 first scalar
  420. * \param t2 second scalar
  421. * \param m2 second matrix
  422. * \param m3 third matrix
  423. * \return matrix \c m1
  424. *
  425. * \tparam M1 type of the first matrix (not needed by default)
  426. * \tparam T1 type of the first scalar (not needed by default)
  427. * \tparam T2 type of the second scalar (not needed by default)
  428. * \tparam M2 type of the second matrix (not needed by default)
  429. * \tparam M3 type of the third matrix (not needed by default)
  430. * \todo use opb_prod()
  431. */
  432. template<class M1, class T1, class T2, class M2, class M3>
  433. M1 & sr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
  434. {
  435. return m1 = t1 * m1 + t2 * (prod (m2, trans (m3)) + prod (m3, trans (m2)));
  436. }
  437. /** \brief generalized hermitian rank \a k update: * \f$m_1=t_1.m_1+t_2.(m_2.m_3^H)+(m_3.(t_2.m_2)^H)\f$
  438. *
  439. * \param m1 first matrix
  440. * \param t1 first scalar
  441. * \param t2 second scalar
  442. * \param m2 second matrix
  443. * \param m3 third matrix
  444. * \return matrix \c m1
  445. *
  446. * \tparam M1 type of the first matrix (not needed by default)
  447. * \tparam T1 type of the first scalar (not needed by default)
  448. * \tparam T2 type of the second scalar (not needed by default)
  449. * \tparam M2 type of the second matrix (not needed by default)
  450. * \tparam M3 type of the third matrix (not needed by default)
  451. * \todo use opb_prod()
  452. */
  453. template<class M1, class T1, class T2, class M2, class M3>
  454. M1 & hr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
  455. {
  456. return m1 =
  457. t1 * m1
  458. + t2 * prod (m2, herm (m3))
  459. + type_traits<T2>::conj (t2) * prod (m3, herm (m2));
  460. }
  461. }
  462. }}}
  463. #endif