indii/ml/aux/vector.hpp

00001 #ifndef INDII_ML_AUX_VECTOR_HPP
00002 #define INDII_ML_AUX_VECTOR_HPP
00003 
00004 #include "boost/numeric/ublas/vector.hpp"
00005 #include "boost/numeric/ublas/vector_sparse.hpp"
00006 #include "boost/numeric/ublas/vector_proxy.hpp"
00007 #include "boost/numeric/ublas/io.hpp"
00008 #include "boost/numeric/ublas/storage.hpp"
00009 
00010 namespace indii {
00011   namespace ml {
00012     namespace aux {
00013 
00014       /**
00015        * General vector.
00016        */
00017       typedef boost::numeric::ublas::vector<double,
00018           boost::numeric::ublas::unbounded_array<double> > vector;
00019 
00020       /**
00021        * Zero vector.
00022        */
00023       typedef boost::numeric::ublas::zero_vector<double> zero_vector;
00024 
00025       /**
00026        * Scalar vector.
00027        */
00028       typedef boost::numeric::ublas::scalar_vector<double> scalar_vector;
00029 
00030       /**
00031        * Sparse vector.
00032        */
00033       typedef boost::numeric::ublas::mapped_vector<double> sparse_vector;
00034 
00035       /**
00036        * Element-wise vector exponential.
00037        *
00038        * @param x \f$\mathbf{x}\f$; a vector.
00039        *
00040        * @return Vector \f$\mathbf{y}\f$ with each \f$y_i = \exp(x_i)\f$.
00041        */
00042       template <class T>
00043       vector element_exp(const T& x);
00044       
00045       /**
00046        * Element-wise vector square root.
00047        *
00048        * @param x \f$\mathbf{x}\f$; a vector.
00049        *
00050        * @return Vector \f$\mathbf{y}\f$ with each \f$y_i = \sqrt{x_i}\f$.
00051        */
00052       template <class T>
00053       vector element_sqrt(const T& x);
00054       
00055       /**
00056        * Element-wise vector power.
00057        *
00058        * @param a \f$\mathbf{a}\f$; a vector.
00059        * @param b \f$\mathbf{b}\f$; a vector.
00060        *
00061        * @return Vector \f$\mathbf{y}\f$ with each \f$y_i = a_i^{b_i}\f$.
00062        */
00063       template <class A, class B>
00064       vector element_pow(const A& a, const B& b);
00065 
00066       /**
00067        * Element-wise vector power.
00068        *
00069        * @param a \f$\mathbf{a}\f$; a vector.
00070        * @param b \f$b\f$; a scalar.
00071        *
00072        * @return Vector \f$\mathbf{y}\f$ with each \f$y_i = a_i^b\f$.
00073        */
00074       template <class A, class B>
00075       vector scalar_pow(const A& a, const B b);
00076 
00077       /**
00078        * Vector p-norm.
00079        *
00080        * @param P \f$p\f$; degree of the norm.
00081        *
00082        * @param x \f$\mathbf{x}\f$; a vector.
00083        *
00084        * @return \f$\|\mathbf{x}\|_p\f$; p-norm of the given vector.
00085        *
00086        * Implementation uses template metaprogramming to utilise uBLAS
00087        * norm_1 and norm_2 functions where possible.
00088        */
00089       template <unsigned int P, class T>
00090       double norm(const T& x);
00091 
00092       /* Omit these from documentation */
00093       /// @cond NORMIMPL
00094       template <unsigned int P, class T>
00095       struct normImpl {
00096         static double evaluate(const T& t);
00097       };
00098 
00099       template <class T>
00100       struct normImpl<1,T> {
00101         static double evaluate(const T& t);      
00102       };
00103       
00104       template <class T>
00105       struct normImpl<2,T> {
00106         static double evaluate(const T& t);      
00107       };
00108       /// @endcond
00109 
00110       /**
00111        * Convert vector to double[].
00112        *
00113        * @param x Vector to convert.
00114        * @param a Array into which to write conversion.
00115        *
00116        * The array is assumed to have a length greater than or equal
00117        * to the vector.
00118        */
00119       template <class T>
00120       void vectorToArray(const T& x, double a[]);
00121 
00122       /**
00123        * Convert double[] to vector.
00124        *
00125        * @param a Array to convert.
00126        * @param x Vector into which to write conversion.
00127        *
00128        * The array is assumed to have a length greater than or equal to the
00129        * vector.
00130        */
00131       template <class T>
00132       void arrayToVector(const double a[], T& x);
00133 
00134     }
00135   }
00136 }
00137 
00138 template <class T>
00139 inline indii::ml::aux::vector indii::ml::aux::element_exp(const T& x) {
00140   unsigned int i;
00141   const unsigned int N = x.size();
00142   vector y(N);
00143   
00144   for (i = 0; i < N; i++) {
00145     y(i) = exp(x(i));
00146   }
00147   
00148   return y;
00149 }
00150       
00151 template <class T>
00152 inline indii::ml::aux::vector indii::ml::aux::element_sqrt(const T& x) {
00153   unsigned int i;
00154   const unsigned int N = x.size();
00155   vector y(N);
00156   
00157   for (i = 0; i < N; i++) {
00158     y(i) = sqrt(x(i));
00159   }
00160   
00161   return y;
00162 }
00163       
00164 template <class A, class B>
00165 inline indii::ml::aux::vector indii::ml::aux::element_pow(const A& a,
00166     const B& b) {
00167   /* pre-condition */
00168   assert (a.size() == b.size());
00169 
00170   unsigned int i;
00171   const unsigned int N = a.size();
00172   vector y(N);
00173 
00174   for (i = 0; i < N; i++) {
00175     y(i) = pow(a(i), b(i));
00176   }
00177   
00178   return y;
00179 }
00180 
00181 template <class A, class B>
00182 inline indii::ml::aux::vector indii::ml::aux::scalar_pow(const A& a,
00183     const B b) {
00184   unsigned int i;
00185   const unsigned int N = a.size();
00186   vector y(N);
00187   
00188   for (i = 0; i < N; i++) {
00189     y(i) = pow(a(i), b);
00190   }    
00191 
00192   return y;
00193 }
00194 
00195 /// @cond NORMIMPL
00196 template <class T>
00197 inline double indii::ml::aux::normImpl<1,T>::evaluate(const T& x) {
00198   return norm_1(x);
00199 }
00200 
00201 template <class T>
00202 inline double indii::ml::aux::normImpl<2,T>::evaluate(const T& x) {
00203   return norm_2(x);
00204 }
00205 
00206 template <unsigned int P, class T>
00207 double indii::ml::aux::normImpl<P,T>::evaluate(const T& x) {
00208   /* pre-condition */
00209   assert (P > 0);
00210 
00211   unsigned int i;
00212   double norm = 0.0;
00213   typename T::const_iterator iter, end;
00214   iter = x.begin();
00215   end = x.end();
00216   
00217   if (P % 2 == 0) {
00218     /* even number, needn't worry about abs() */
00219     while (iter != end) {
00220       norm += pow(*iter, P);
00221       iter++;
00222     }
00223   } else {
00224     /* odd number, abs() all values */
00225     while (iter != end) {
00226       norm += pow(fabs(*iter), P);
00227       iter++;
00228     }
00229   }
00230   
00231   return pow(norm, 1.0 / P);
00232 }
00233 
00234 /// @endcond
00235 
00236 template <unsigned int P, class T>
00237 inline double indii::ml::aux::norm(const T& x) {
00238   return normImpl<P,T>::evaluate(x);
00239 }
00240 
00241 template <class T>
00242 void indii::ml::aux::vectorToArray(const T& x, double a[]) {
00243   unsigned int i, len = x.size();
00244   for (i = 0; i < len; i++) {
00245     a[i] = x(i);
00246   }
00247 }
00248 
00249 template <class T>
00250 void indii::ml::aux::arrayToVector(const double a[], T& x) {
00251   unsigned int i, len = x.size();
00252   for (i = 0; i < len; i++) {
00253     x(i) = a[i];
00254   }
00255 }
00256 
00257 #endif
00258 

Generated on Wed Dec 17 15:11:57 2008 for dysii Dynamical Systems Library by  doxygen 1.5.3