Ticket #4917: ublas-pow

File ublas-pow, 10.1 KB (added by matwey.kornilov@…, 12 years ago)
Line 
1Index: boost/numeric/ublas/vector_expression.hpp
2===================================================================
3--- boost/numeric/ublas/vector_expression.hpp (revision 66890)
4+++ boost/numeric/ublas/vector_expression.hpp (working copy)
5@@ -950,6 +950,17 @@
6 return expression_type (e1 (), e2 ());
7 }
8
9+ // pow (v1, v2) [i] = pow( v1 [i], v2 [i] )
10+ template<class E1, class E2>
11+ BOOST_UBLAS_INLINE
12+ typename vector_binary_traits<E1, E2, scalar_pow<typename E1::value_type,
13+ typename E2::value_type> >::result_type
14+ element_pow (const vector_expression<E1> &e1,
15+ const vector_expression<E2> &e2) {
16+ typedef typename vector_binary_traits<E1, E2, scalar_pow<typename E1::value_type,
17+ typename E2::value_type> >::expression_type expression_type;
18+ return expression_type (e1 (), e2 ());
19+ }
20
21 template<class E1, class E2, class F>
22 class vector_binary_scalar1:
23@@ -1416,6 +1427,15 @@
24 return expression_type (e1 (), e2);
25 }
26
27+ // pow (v, t) [i] = pow( v [i], t )
28+ template<class E1, class T2>
29+ BOOST_UBLAS_INLINE
30+ typename vector_binary_scalar2_traits<E1, const T2, scalar_pow<typename E1::value_type, T2> >::result_type
31+ pow (const vector_expression<E1> &e1,
32+ const T2 &e2) {
33+ typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_pow<typename E1::value_type, T2> >::expression_type expression_type;
34+ return expression_type (e1 (), e2);
35+ }
36
37 template<class E, class F>
38 class vector_scalar_unary:
39Index: boost/numeric/ublas/matrix_expression.hpp
40===================================================================
41--- boost/numeric/ublas/matrix_expression.hpp (revision 66890)
42+++ boost/numeric/ublas/matrix_expression.hpp (working copy)
43@@ -2518,6 +2518,18 @@
44 return expression_type (e1 (), e2 ());
45 }
46
47+ // pow (m1, m2) [i] [j] = pow (m1 [i] [j], m2 [i] [j])
48+ template<class E1, class E2>
49+ BOOST_UBLAS_INLINE
50+ typename matrix_binary_traits<E1, E2, scalar_pow<typename E1::value_type,
51+ typename E2::value_type> >::result_type
52+ element_pow (const matrix_expression<E1> &e1,
53+ const matrix_expression<E2> &e2) {
54+ typedef typename matrix_binary_traits<E1, E2, scalar_pow<typename E1::value_type,
55+ typename E2::value_type> >::expression_type expression_type;
56+ return expression_type (e1 (), e2 ());
57+ }
58+
59 template<class E1, class E2, class F>
60 class matrix_binary_scalar1:
61 public matrix_expression<matrix_binary_scalar1<E1, E2, F> > {
62@@ -3394,6 +3406,15 @@
63 return expression_type (e1 (), e2);
64 }
65
66+ // pow (m, p) [i] [j] = pow (m [i] [j], p)
67+ template<class E1, class T2>
68+ BOOST_UBLAS_INLINE
69+ typename matrix_binary_scalar2_traits<E1, const T2, scalar_pow<typename E1::value_type, T2> >::result_type
70+ pow (const matrix_expression<E1> &e1,
71+ const T2 &e2) {
72+ typedef typename matrix_binary_scalar2_traits<E1, const T2, scalar_pow<typename E1::value_type, T2> >::expression_type expression_type;
73+ return expression_type (e1 (), e2);
74+ }
75
76 template<class E1, class E2, class F>
77 class matrix_vector_binary1:
78Index: boost/numeric/ublas/functional.hpp
79===================================================================
80--- boost/numeric/ublas/functional.hpp (revision 66890)
81+++ boost/numeric/ublas/functional.hpp (working copy)
82@@ -172,7 +172,19 @@
83 return t1 / t2;
84 }
85 };
86+ template<class T, class U>
87+ struct scalar_pow:
88+ public scalar_binary_functor<T, U> {
89+ typedef typename scalar_binary_functor<T, U>::argument1_type argument1_type;
90+ typedef typename scalar_binary_functor<T, U>::argument2_type argument2_type;
91+ typedef typename boost::remove_reference< argument1_type >::type result_type;
92
93+ static BOOST_UBLAS_INLINE
94+ result_type apply (argument1_type t, argument2_type p) {
95+ return type_traits<T>::type_pow (t,p);
96+ }
97+ };
98+
99 template<class T1, class T2>
100 struct scalar_binary_assign_functor {
101 // ISSUE Remove reference to avoid reference to reference problems
102Index: boost/numeric/ublas/traits.hpp
103===================================================================
104--- boost/numeric/ublas/traits.hpp (revision 66890)
105+++ boost/numeric/ublas/traits.hpp (working copy)
106@@ -41,6 +41,11 @@
107 // we'll find either std::abs or else another version via ADL:
108 return abs (t);
109 }
110+ template<class T, class U> T boost_numeric_ublas_pow (const T& t, const U& p) {
111+ using namespace std;
112+ // we'll find either std::pow or else another version via ADL:
113+ return pow (t,p);
114+ }
115 }
116
117 namespace boost { namespace numeric { namespace ublas {
118@@ -186,6 +191,11 @@
119 real_type type_abs (const_reference t) {
120 return boost_numeric_ublas_abs (t);
121 }
122+ template<class U> static
123+ BOOST_UBLAS_INLINE
124+ value_type type_pow (const_reference t, const U& p) {
125+ return boost_numeric_ublas_pow (t,p);
126+ }
127 static
128 BOOST_UBLAS_INLINE
129 value_type type_sqrt (const_reference t) {
130@@ -297,6 +307,11 @@
131 real_type type_abs (const_reference t) {
132 return abs (t);
133 }
134+ template<class U> static
135+ BOOST_UBLAS_INLINE
136+ value_type type_pow (const_reference t, const U& p) {
137+ return boost_numeric_ublas_pow (t,p);
138+ }
139 static
140 BOOST_UBLAS_INLINE
141 value_type type_sqrt (const_reference t) {
142Index: libs/numeric/ublas/test/test_pow.cpp
143===================================================================
144--- libs/numeric/ublas/test/test_pow.cpp (revision 0)
145+++ libs/numeric/ublas/test/test_pow.cpp (revision 0)
146@@ -0,0 +1,118 @@
147+#include "test_pow.hpp"
148+
149+template<class V, int N>
150+struct test_vector_pow {
151+ typedef typename V::value_type value_type;
152+ typedef typename V::size_type size_type;
153+ typedef typename ublas::type_traits<value_type>::real_type real_type;
154+
155+ template<class VP>
156+ void test_pow_with (VP &v1, VP &v2, VP &v3) const {
157+ initialize_vector (v1);
158+ v2 = v1;
159+ std::cout << "v2 = v1 = " << v1 << std::endl;
160+ v2 = pow( v1, 2 );
161+ std::cout << "pow( v1, 2 ) = " << v2 << std::endl;
162+ v1 = pow( v2, 0.5 );
163+ std::cout << "pow( v2, 0.5 ) = " << v1 << std::endl;
164+
165+ initialize_vector (v1);
166+ v2 = v1;
167+ std::cout << "v2 = v1 = " << v1 << std::endl;
168+ v3 = element_pow( v1, v2 );
169+ std::cout << "element_pow( v1, v2 ) = " << v3 << std::endl;
170+ }
171+
172+ void operator () () const {
173+ V v1 (N);
174+ V v2 (N);
175+ V v3 (N);
176+ test_pow_with (v1, v2, v3);
177+ }
178+};
179+
180+template<class M, int N>
181+struct test_matrix_pow {
182+ typedef typename M::value_type value_type;
183+
184+ template<class MP>
185+ void test_pow_with (MP &m1, MP &m2, MP &m3) const {
186+ initialize_matrix (m1);
187+ m2 = m1;
188+ std::cout << "m2 = m1 = " << m1 << std::endl;
189+ m2 = pow( m1, 2 );
190+ std::cout << "pow( m1, 2 ) = " << m2 << std::endl;
191+ m1 = pow( m2, 0.5 );
192+ std::cout << "pow( m2, 0.5 ) = " << m1 << std::endl;
193+
194+ initialize_matrix (m1);
195+ m2 = m1;
196+ std::cout << "m2 = m1 = " << m1 << std::endl;
197+ m3 = element_pow( m1, m2 );
198+ std::cout << "element_pow( m1, m2 ) = " << m3 << std::endl;
199+ }
200+ void operator () () const {
201+ M m1 (N, N);
202+ M m2 (N, N);
203+ M m3 (N, N);
204+ test_pow_with (m1, m2, m3);
205+ }
206+};
207+
208+void test_vector () {
209+ std::cout << "test_vector" << std::endl;
210+
211+#ifdef USE_FLOAT
212+ std::cout << "float" << std::endl;
213+ test_vector_pow<ublas::vector<float>, 3> () ();
214+#endif
215+
216+#ifdef USE_DOUBLE
217+ std::cout << "double" << std::endl;
218+ test_vector_pow<ublas::vector<double>, 3> () ();
219+#endif
220+
221+#ifdef USE_STD_COMPLEX
222+#ifdef USE_FLOAT
223+ std::cout << "std::complex<float>" << std::endl;
224+ test_vector_pow<ublas::vector<std::complex<float> >, 3> () ();
225+#endif
226+
227+#ifdef USE_DOUBLE
228+ std::cout << "std::complex<double>" << std::endl;
229+ test_vector_pow<ublas::vector<std::complex<double> >, 3> () ();
230+#endif
231+#endif
232+}
233+
234+void test_matrix () {
235+ std::cout << "test_matrix" << std::endl;
236+
237+#ifdef USE_FLOAT
238+ std::cout << "float" << std::endl;
239+ test_matrix_pow<ublas::matrix<float>, 3> () ();
240+#endif
241+
242+#ifdef USE_DOUBLE
243+ std::cout << "double" << std::endl;
244+ test_matrix_pow<ublas::matrix<double>, 3> () ();
245+#endif
246+
247+#ifdef USE_STD_COMPLEX
248+#ifdef USE_FLOAT
249+ std::cout << "std::complex<float>" << std::endl;
250+ test_matrix_pow<ublas::matrix<std::complex<float> >, 3> () ();
251+#endif
252+
253+#ifdef USE_DOUBLE
254+ std::cout << "std::complex<double>" << std::endl;
255+ test_matrix_pow<ublas::matrix<std::complex<double> >, 3> () ();
256+#endif
257+#endif
258+}
259+
260+int main () {
261+ test_vector ();
262+ test_matrix ();
263+ return 0;
264+}
265Index: libs/numeric/ublas/test/test_pow.hpp
266===================================================================
267--- libs/numeric/ublas/test/test_pow.hpp (revision 0)
268+++ libs/numeric/ublas/test/test_pow.hpp (revision 0)
269@@ -0,0 +1,20 @@
270+#ifndef TEST_POW_H
271+#define TEST_POW_H
272+
273+#include <iostream>
274+
275+#include <boost/numeric/ublas/vector.hpp>
276+#include <boost/numeric/ublas/vector_proxy.hpp>
277+#include <boost/numeric/ublas/matrix.hpp>
278+#include <boost/numeric/ublas/matrix_proxy.hpp>
279+#include <boost/numeric/ublas/io.hpp>
280+
281+namespace ublas = boost::numeric::ublas;
282+
283+#include "common/init.hpp"
284+
285+void test_vector ();
286+void test_matrix ();
287+
288+
289+#endif
290Index: libs/numeric/ublas/test/Jamfile.v2
291===================================================================
292--- libs/numeric/ublas/test/Jamfile.v2 (revision 66890)
293+++ libs/numeric/ublas/test/Jamfile.v2 (working copy)
294@@ -132,6 +132,10 @@
295 ]
296 [ run test_complex_norms.cpp
297 ]
298+ [ run test_pow.cpp
299+ : : :
300+ <define>$(UBLAS_TESTSET)
301+ ]
302 [ run test_assignment.cpp
303 ]
304 ;