RDCode: Vector.h Source File

# Vector.h

Go to the documentation of this file.

    00001 //
    00002 //  Copyright (C) 2004-2008 Greg Landrum and Rational Discovery LLC
    00003 //
    00004 //   @@ All Rights Reserved  @@
    00005 //
    00006 #ifndef __RD_VECTOR_H__
    00007 #define __RD_VECTOR_H__
    00008
    00009 #include <RDGeneral/Invariant.h>
    00010 #include <RDGeneral/utils.h>
    00011 #include <math.h>
    00012 #include <iostream>
    00013 #include <iomanip>
    00014 #include <cstdlib>
    00015 #include <cstring>
    00016 #include <time.h>
    00017 #include <boost/random.hpp>
    00018 #include <boost/smart_ptr.hpp>
    00019
    00020 namespace RDNumeric {
    00021
    00022
    00023   //! A class to represent vectors of numbers.
    00024   template <class TYPE> class Vector {
    00025
    00026   public:
    00027
    00028     typedef boost::shared_array<TYPE> DATA_SPTR;
    00029
    00030     //! Initialize with only a size.
    00031     explicit Vector(unsigned int N) {
    00032       d_size = N;
    00033       TYPE *data = new TYPE[N];
    00034       memset(static_cast<void *>(data),0,d_size*sizeof(TYPE));
    00035       d_data.reset(data);
    00036     }
    00037
    00038     //! Initialize with a size and default value.
    00039     Vector(unsigned int N, TYPE val) { //: Vector(N) {
    00040       d_size = N;
    00041       TYPE *data = new TYPE[N];
    00042
    00043       unsigned int i;
    00044       for (i = 0; i < N; i++) {
    00045         data[i] = val;
    00046       }
    00047       d_data.reset(data);
    00048     }
    00049
    00050     //! Initialize from a smart pointer.
    00051     /*!
    00052       <b>NOTE:</b> the data is not copied in this case
    00053     */
    00054     Vector(unsigned int N, DATA_SPTR data) {//TYPE *data) {
    00055       d_size = N;
    00056       d_data = data;
    00057     }
    00058
    00059     //! copy constructor
    00060     /*! We make a copy of the other vector's data.
    00061      */
    00062     Vector(const Vector &other) {
    00063       d_size = other.size();
    00064       const TYPE *otherData = other.getData();
    00065       TYPE *data = new TYPE[d_size];
    00066
    00067       memcpy(static_cast<void *>(data), static_cast<const void *>(otherData), d_size*sizeof(TYPE));
    00068       d_data.reset(data);
    00069     }
    00070
    00071     ~Vector() {
    00072     }
    00073
    00074     //! return the size (dimension) of the vector
    00075     unsigned int size() const {
    00076       return d_size;
    00077     }
    00078
    00079     //! returns the value at a particular index
    00080     inline TYPE getVal(unsigned int i) const {
    00081       RANGE_CHECK(0, i, d_size-1);
    00082       return d_data[i];
    00083     }
    00084
    00085     //! sets the index at a particular value
    00086     inline void setVal(unsigned int i, TYPE val) {
    00087       RANGE_CHECK(0, i, d_size-1);
    00088       d_data[i] = val;
    00089     }
    00090
    00091     inline TYPE operator[](unsigned int i) const {
    00092       RANGE_CHECK(0, i, d_size-1);
    00093       return d_data[i];
    00094     }
    00095
    00096     inline TYPE& operator[](unsigned int i) {
    00097       RANGE_CHECK(0, i, d_size-1);
    00098       return d_data[i];
    00099     }
    00100
    00101     //! returns a pointer to our data array
    00102     inline TYPE *getData() {
    00103       return d_data.get();
    00104     }
    00105
    00106     //! returns a const pointer to our data array
    00107     inline const TYPE *getData() const {
    00108       //return dp_data;
    00109       return d_data.get();
    00110     }
    00111
    00112     //! Copy operator.
    00113     /*! We make a copy of the other Vector's data.
    00114      */
    00115
    00116     Vector<TYPE>& assign(const Vector<TYPE> &other) {
    00117       CHECK_INVARIANT(d_size == other.size(), "Size mismatch in vector copying");
    00118       const TYPE *otherData = other.getData();
    00119       memcpy(static_cast<void *>(d_data.get()), static_cast<const void *>(otherData), d_size*sizeof(TYPE));
    00120       return *this;
    00121     }
    00122
    00123     //! elementwise addition, vectors must be the same size.
    00124     Vector<TYPE>& operator+=(const Vector<TYPE> &other) {
    00125       CHECK_INVARIANT(d_size == other.size(), "Size mismatch in vector addition");
    00126       const TYPE *otherData = other.getData();
    00127       TYPE *data = d_data.get();
    00128       unsigned int i;
    00129       for (i = 0; i < d_size; i++) {
    00130         data[i] += otherData[i];
    00131       }
    00132       return *this;
    00133     }
    00134
    00135     //! elementwise subtraction, vectors must be the same size.
    00136     Vector<TYPE>& operator-=(const Vector<TYPE> &other) {
    00137       CHECK_INVARIANT(d_size == other.size(), "Size mismatch in vector subtraction");
    00138       const TYPE *otherData = other.getData();
    00139       TYPE *data = d_data.get();
    00140       unsigned int i;
    00141       for (i = 0; i < d_size; i++) {
    00142         data[i] -= otherData[i];
    00143       }
    00144       return *this;
    00145     }
    00146
    00147     //! multiplication by a scalar
    00148     Vector<TYPE>& operator *=(TYPE scale) {
    00149       unsigned int i;
    00150       for (i = 0; i < d_size; i++) {
    00151         d_data[i] *= scale;
    00152       }
    00153       return *this;
    00154     }
    00155
    00156     //! division by a scalar
    00157     Vector<TYPE>& operator /=(TYPE scale) {
    00158       unsigned int i;
    00159       for (i = 0; i < d_size; i++) {
    00160         d_data[i] /= scale;
    00161       }
    00162       return *this;
    00163     }
    00164
    00165     //! L2 norm squared
    00166     inline TYPE normL2Sq() const {
    00167       TYPE res = (TYPE)0.0;
    00168       unsigned int i;
    00169       TYPE *data = d_data.get();
    00170       for (i = 0; i < d_size; i++) {
    00171         res += data[i]*data[i];
    00172       }
    00173       return res;
    00174     }
    00175
    00176     //! L2 norm
    00177     inline TYPE normL2() const {
    00178       return sqrt(this->normL2Sq());
    00179     }
    00180
    00181     //! L1 norm
    00182     inline TYPE normL1() const {
    00183       TYPE res = (TYPE)0.0;
    00184       unsigned int i;
    00185       TYPE *data = d_data.get();
    00186       for (i = 0; i < d_size; i++) {
    00187         res += fabs(data[i]);
    00188       }
    00189       return res;
    00190     }
    00191
    00192     //! L-infinity norm
    00193     inline TYPE normLinfinity() const {
    00194       TYPE res = (TYPE)(-1.0);
    00195       unsigned int i;
    00196       TYPE *data = d_data.get();
    00197       for (i = 0; i < d_size; i++) {
    00198         if (fabs(data[i]) > res) {
    00199           res = fabs(data[i]);
    00200         }
    00201       }
    00202       return res;
    00203     }
    00204
    00205     //! \brief Gets the ID of the entry that has the largest absolute value
    00206     //! i.e. the entry being used for the L-infinity norm
    00207     inline unsigned int largestAbsValId() const {
    00208       TYPE res = (TYPE)(-1.0);
    00209       unsigned int i, id=d_size;
    00210       TYPE *data = d_data.get();
    00211       for (i = 0; i < d_size; i++) {
    00212         if (fabs(data[i]) > res) {
    00213           res = fabs(data[i]);
    00214           id = i;
    00215         }
    00216       }
    00217       return id;
    00218     }
    00219
    00220     //! \brief Gets the ID of the entry that has the largest value
    00221     inline unsigned int largestValId() const {
    00222       TYPE res = (TYPE)(-1.e8);
    00223       unsigned int i, id=d_size;
    00224       TYPE *data = d_data.get();
    00225       for (i = 0; i < d_size; i++) {
    00226         if (data[i] > res) {
    00227           res = data[i];
    00228           id = i;
    00229         }
    00230       }
    00231       return id;
    00232     }
    00233
    00234     //! returns the dot product between two Vectors
    00235     inline TYPE dotProduct(const Vector<TYPE> other) {
    00236       CHECK_INVARIANT(d_size == other.size(), "Size mismatch in vector doct product");
    00237       const TYPE *oData = other.getData();
    00238       unsigned int i;
    00239       TYPE res = (TYPE)(0.0);
    00240       TYPE *data = d_data.get();
    00241       for (i = 0; i < d_size; i++) {
    00242         res += (data[i]*oData[i]);
    00243       }
    00244       return res;
    00245     }
    00246
    00247     //! Normalize the vector using the L2 norm
    00248     inline void normalize() {
    00249       TYPE val = this->normL2();
    00250       (*this) /= val;
    00251     }
    00252
    00253     //! Set to a random unit vector
    00254     inline void setToRandom(unsigned int seed=0) {
    00255       // we want to get our own RNG here instead of using the global
    00256       // one.  This is related to Issue285.
    00257       RDKit::rng_type generator(42u);
    00258       RDKit::uniform_double dist(0,1.0);
    00259       RDKit::double_source_type randSource(generator,dist);
    00260       if (seed > 0) {
    00261         generator.seed(seed);
    00262       } else {
    00263         // we can't initialize using only clock(), because it's possible
    00264         // that we'll get here fast enough that clock() will return 0
    00265         // and generator.seed(0) is an error:
    00266         generator.seed(clock()+1);
    00267       }
    00268
    00269       unsigned int i;
    00270       TYPE *data = d_data.get();
    00271       for (i = 0; i < d_size; i++) {
    00272         data[i] = randSource();
    00273       }
    00274       this->normalize();
    00275     }
    00276
    00277   private:
    00278     unsigned int d_size;     //! < our length
    00279     DATA_SPTR d_data;
    00280     Vector<TYPE>& operator=(const Vector<TYPE> &other);
    00281   };
    00282
    00283   typedef Vector<double> DoubleVector;
    00284 }
    00285
    00286 //! ostream operator for Vectors
    00287 template <typename TYPE> std::ostream & operator<<(std::ostream& target,
    00288                                                    const RDNumeric::Vector<TYPE> &vec) {
    00289   unsigned int siz = vec.size();
    00290   target << "Size: " << siz << " [";
    00291   unsigned int i;
    00292   for (i = 0; i < siz; i++) {
    00293     target << std::setw(7) << std::setprecision(3) << vec.getVal(i) << ", ";
    00294   }
    00295   target << "]\n";
    00296   return target;
    00297 }
    00298
    00299 #endif
    00300
    00301