RDCode: Vector.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories

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