OOF2: The Manual
Name
DoubleVec — A vector of double precision numbers
Synopses
C++ Synopsis
#include "common/doublevec.h"
class DoubleVec {DoubleVec();DoubleVec(int size,
double value= 0);DoubleVec(const DoubleVec& other);DoubleVec(DoubleVec&& other);DoubleVec(const std::initializer_list<double>& values);
// Assignment and initializationDoubleVec& operator=(const DoubleVec& other);void zero();void clear();void unit();void resize(std::size_t size,
double value= 0);
// Comparisonbool operator==(const DoubleVec& other) const;bool operator!=(const DoubleVec& other) const;
// Data accessint size() const;double& operator[](std::size_t index);double operator[](std::size_t index) const;DoubleVec subvec(std::size_t start,
std::size_t end) const;void subvec_copy(std::size_t destination,
const DoubleVec& other,
std::size_t pos,
std::size_t size);
// In-place arithmetic operatorsDoubleVec& operator+=(const DoubleVec& other);DoubleVec& operator-=(const DoubleVec& other);DoubleVec& operator*=(double factor);DoubleVec& operator/=(double divisor);void axpy(double alpha,
const DoubleVec& x);
// Non-in-place arithmetic operatorsDoubleVec operator+(const DoubleVec& other) const;DoubleVec operator-(const DoubleVec& other) const;DoubleVec operator-() const;DoubleVec operator*(double factor) const;DoubleVec operator/(double divisor) const;friend DoubleVec operator*(double factor,
const DoubleVec& vector);double dot(const DoubleVec& other) const;double operator*(const DoubleVec& other) const;double norm();
// iterators typedef Eigen::VectorXd::iterator iterator; typedef Eigen::VectorXd::const_iterator const_iterator;iterator begin();iterator end();const_iterator begin() const;const_iterator end() const;
}
Description
DoubleVec is the class that OOF2 uses
internally for vectors of double precision numbers. It is
basically a wrapper for Eigen::vectorXd. It
suppports all the usual arithmetic methods as well as STL style
iteration in C++.
Python vs C++
A DoubleVec can be created in Python or
returned from C++ to Python, and bulk operations (like adding
two vectors) can be performed from Python. Element-by-element
access is available in Python, but is discouraged, because it
is slow.
In Python, import DoubleVec like this:
from ooflib.SWIG.common.doublevec import DoubleVec
The Python class wraps all of the members of the C++ class, and works identically, with the following exceptions:
-
The null constructor is not provided. An initial size must be provided. An initial value is optional:
vec = doublevec.DoubleVec(10) # ten zeros vac = doublevec.DoubleVec(10, 2) # ten twos voc = doublevec.DoubleVec() # not allowed
-
There are no Python equivalents to the C++ iterator methods. This is because accessing indiviual vector elements from Python is inefficient and should be avoided.
__getitem__and__setitem__are provided but should only be used for debugging. -
The difference between C++ assignment (copying values) and Python assignment (reassigning references) shows up in a few important ways:
-
To make an independent copy of a DoubleVec, use the
clonemethod:vec = DoubleVec(10) not_a_copy = vec # refers to the same data as vec is_a_copy = vec.clone() # contains its own copy of vec's data
copy=vec.clone()in Python is the equivalent ofcopy=vecin C++.To copy the contents of a
DoubleVecto an existingDoubleVec, use thecopy_inplacemethod:this = doublevec.DoubleVec(10, 1) that = doublevec.DoubleVec(10, 2) this.copy_inplace(that)
-
In Python, the relationship between in-place and not-in-place arithmetic operators is not the same as in C++. In C++,
A = A+BandA += Bhave the same effect for twoDoubleVecsAandB. In PythonA+=Badds the contents ofBto the vectorA, and all other references toAwill see the new values, just like they would in C++. However, in PythonA = A+Bcreates a new vectorAcontaining the sum of the oldAandB. Other references toAwill not see the new values.
-
Constructors
DoubleVec::DoubleVec();
The default constructor creates a zero length vector. It will need to resized in order to be useful.
DoubleVec(int size, double value=0);
Create a vector of length size,
initializing each entry to value.
The initial value is 0 if it's not
specified.
DoubleVec(const DoubleVec&); // copy constructor DoubleVec(DoubleVec&&); // move constructor DoubleVec(const std::initializer_list<double>&); // initialization list constructor
The copy, move, and initialization list constructors are
inherited from the underlying Eigen::vectorXd class.
Methods
Assignment
DoubleVec& operator=(const DoubleVec&)
The assignment operator is inherited from the underlying Eigen::vectorXd class.
Comparison
bool DoubleVec::operator==(const DoubleVec& other) const; bool DoubleVec::operator!=(const DoubleVec& other) const;
The comparison operators compare each data element individually.
Initialization
void DoubleVec::zero(); void DoubleVec::clear();
Set all vector entries to zero. The two forms are identical.
void DoubleVec::unit();
Set all vector entries to one.
void DoubleVec::resize(size_type size, double value=0);
Resize the vector and set all entries to
value, which defaults to 0. The previous
contents of the vector will be lost.
Data Access
int DoubleVec::size() const;
Return the number of components in the vector.
double& DoubleVec::operator[](std::size_t index);
double DoubleVec::operator[](std::size_t index) const;
double& DoubleVec::operator[](const DoubleVec::iterator&);
double DoubleVec::operator[](const DoubleVec::const_iterator&) const;
Return the contents at location index, or a
reference to it if the DoubleVec is not
const.
DoubleVec subvec(std::size_t start, std::size_t end) const;
void subvec_copy(std::size_t destination, const DoubleVec& other,
std::size_t pos, std::size_t size);
The first form returns a new DoubleVec
containing the data from *this from position
start to end.
The second form copies data from the given
DoubleVec other to
*this. The data will be extracted from positions
pos to pos+size in
other, and will be inserted at positions
destination to
destination+size in *this.
Arithmetic
DoubleVec& DoubleVec::operator+=(const DoubleVec&); DoubleVec& DoubleVec::operator-=(const DoubleVec&); DoubleVec& DoubleVec::operator*=(double); DoubleVec& DoubleVec::operator/=(double); void DoubleVec::axpy(double alpha, const DoubleVec& x);
These are the in-place arithmetic operators.
axpy() multiplies vector x by
alpha and adds it to *this.
DoubleVec DoubleVec::operator+(const DoubleVec& other) const; DoubleVec DoubleVec::operator-(const DoubleVec& other) const; DoubleVec DoubleVec::operator-() const; DoubleVec DoubleVec::operator*(double factor) const; DoubleVec operator*(double factor, const DoubleVec& other); DoubleVec DoubleVec::operator/(double divisor) const;
These out-of-place arithmetic operators return a new object. Scalar multiplication can be done from either the left or the right.
Dot Product and Norm
double DoubleVec::dot(const DoubleVec&) const; double DoubleVec::operator*(const DoubleVec&) const;
The dot product of two DoubleVecs
A and B can be computed
either as A.dot(B) or A*B.
double DoubleVec::norm() const { return data.norm(); }
A.norm() is the L2 norm of A, or sqrt(A*A).
Iterators
DoubleVec::iterator DoubleVec::begin(); DoubleVec::iterator DoubleVec::end(); DoubleVec::const_iterator DoubleVec::begin() const; DoubleVec::const_iterator DoubleVec::end() const;
The iterator classes are typedefs of the Eigen iterators, and can be used like normal STL iterators. These loops are functionally identical:
DoubleVec A(10);
// Use a std::size_t (or int) index
for(std::size_t i=0; i<A.size(); i++)
A[i] = 2;
// Use an iterator as an index
for(DoubleVec::iterator i=A.begin(); i<A.end(); i++)
A[i] = 2;
// Use an iterator as a pointer
for(DoubleVec::iterator i=A.begin(); i<A.end(); i++)
*i = 2;
// Use a range-based loop
for(double& x : A)
x = 2;



