\chapter{Vectors: NRVec}\label{ch:vec} \laheader{vec.h, vec.cc} \section{Purpose and main idea}\label{sec:vec:purpose} \code{NRVec} is the basic dense vector class template of \LA{}: a contiguous array of \code{nn} elements of type \code{T}, indexed from zero, with reference-counted storage (copy on demand). It is used directly as the vector type of linear algebra (BLAS-1 and BLAS-2 operations for \code{double} and \code{std::complex}), as a general resizable container of arbitrary elements (including nested \LA{} objects such as \code{NRVec >}), and as the storage backbone of other classes (\code{NRMat} and \code{NRSMat} can be viewed as vectors without copying, see Sec.~\ref{sec:vec:construct}). \code{NRVec_from1} (Sec.~\ref{sec:vec:from1}) is a thin derived class with indexing from one. The class is explicitly instantiated in \texttt{vec.cc} for the element types \code{double}, \code{char}, \code{short}, \code{int}, \code{long}, \code{long long}, their \code{unsigned} variants, and for \code{std::complex}. Members defined in \texttt{vec.h} can be used with any other element type (user classes, nested \LA{} types, \code{float}, \dots); members defined only in \texttt{vec.cc} (\code{NRVec(const NRMat&)}, \code{fprintf}, \code{fscanf}, unary \code{operator-}, \code{operator<}, \code{operator>}, \code{find}, \code{findthr}, \code{permuteme(const CyclePerm&)}, \code{conjugateme}, \code{negateme}, \code{negateconjugateme}, \code{sum}) are available only for the instantiated types. Numerical members based on BLAS are intended for floating-point element types only (real and complex), not for integers; at present they exist for \code{double} and \code{std::complex} (see the remarks in the reference below). \section{Storage and class-specific concepts}\label{sec:vec:storage} The object holds the size \code{nn}, a data pointer \code{v} and a pointer \code{count} to the reference counter (plus a location tag in GPU builds, see Sec.~\ref{sec:concepts:gpu}). A default-constructed vector has \code{nn==0}, \code{v==0}, \code{count==0}. \code{NRVec} follows the copy-on-demand scheme of Sec.~\ref{sec:concepts:refcount}: copy construction and \code{operator=} share the data, \code{operator|=} makes a deep copy (Sec.~\ref{sec:concepts:assign}), member functions that modify the data call \code{copyonwrite()} themselves, \code{resize()} detaches shared data, and an explicit \code{copyonwrite()} is needed only before writing through \code{operator[]} or a raw pointer. In DEBUG builds the non-const \code{operator[]} raises \code{laerror} if the reference count is larger than one and \code{_LA_count_check} is set. For element types that are not plain data (\code{LA_traits::is_plaindata()} false, e.g.\ nested vectors), \code{copyonwrite()} recursively calls \code{copyonwrite()} on the elements, see Sec.~\ref{sec:concepts:traits}. The element-level member \code{swap(int,int)} does not call \code{copyonwrite()} by design, like \code{operator[]}: call \code{copyonwrite()} once before using it on a vector that may share its data (Sec.~\ref{sec:concepts:refcount}). Elements are stored contiguously, so \code{(T*)x} or \code{&x[0]} can be passed to C/Fortran routines expecting an array. The nested type \code{ROWTYPE} is \code{T}. \section{Construction, assignment, conversion}\label{sec:vec:construct} \begin{lareference} \lafunc{NRVec()}{Empty vector (size 0, nothing allocated).} \lafunc{explicit NRVec(const int n, const GPUID loc = undefined)}{Vector of \code{n} elements, \emph{not initialized} (for plain data). \code{loc} is the memory location in GPU builds, ignored otherwise.} \lafunc{NRVec(const T &a, const int n, const GPUID loc = undefined)}{Vector of \code{n} elements all equal to \code{a}. Note the order of arguments: value first, size second.} \lafunc{template NRVec(const T (&a)[SIZE])}{Copy of a C array; also accepts a braced list, e.g.\ \code{NRVec x({1.,2.,3.})}.} \lafunc{NRVec(const T *a, const int n)}{Copy of \code{n} elements from memory at \code{a}.} \lafunc{NRVec(T *a, const int n, bool skeleton)}{With \code{skeleton==false} same as the previous one. With \code{skeleton==true} the vector \emph{wraps} the external memory \code{a} without copying; the reference count is set to 2 so that the memory is never freed by \LA{}. Consequently any modifying member function makes a private copy first (the external memory is \emph{not} modified), and DEBUG-mode \code{operator[]} for writing raises an error. Use it for read-only views of foreign data.} \lafunc{NRVec(const Vec3 &rhs)}{Copy of the three components of a \code{Vec3} (from \texttt{vecmat3.h}, see Chapter~\ref{ch:vecmat3}).} \lafunc{NRVec(const NRVec &rhs)}{Copy constructor, shares data.} \lafunc{explicit NRVec(const std::list l)}{Copy of the elements of a \code{std::list} (the list is passed by value).} \lafunc{NRVec(const typename LA_traits_complex::NRVec_Noncomplex_type &rhs, bool imagpart=false)}{Complex vector from a real one: \code{rhs} becomes the real part (or the imaginary part if \code{imagpart}), the other part is zero. Implemented only for \code{NRVec >} from \code{NRVec}.} \lafunc{explicit NRVec(const NRSMat &S)}{View of the packed storage of a symmetric matrix of order $n$ as a vector of $n(n+1)/2$ elements. \emph{Shares} the data with \code{S} (no copy).} \lafunc{explicit NRVec(const NRMat &rhs)}{View of the row-major storage of an $n\times m$ matrix as a vector of $nm$ elements. \emph{Shares} the data with \code{rhs}; if the library is compiled with \code{MATPTR}, the data are copied instead.} \lafunc{explicit NRVec(const CSRMat &rhs)}{The same from a compressed row sparse matrix (section~\ref{sec:sparse:csr}).} \lafunc{explicit NRVec(const SparseMat &rhs)}{Dense vector from a sparse matrix having one row or one column (otherwise \code{laerror}); duplicate entries are summed. Defined in \texttt{sparsemat.cc} for \code{double} and \code{std::complex}.} \lafunc{~NRVec()}{Decrements the reference count, frees the data when it reaches zero.} \lafunc{NRVec& operator=(const NRVec &rhs)}{Shallow assignment (shares data), see Sec.~\ref{sec:concepts:assign}.} \lafunc{NRVec& operator|=(const NRVec &rhs)}{Deep copy; \code{rhs} must be allocated (checked in DEBUG).} \lafunc{NRVec& operator=(const T &a)}{Sets all elements to \code{a} (keeps the size); calls copyonwrite.} \lafunc{void copyonwrite(bool detachonly=false, bool deep=true)}{If the data are shared, allocate a private copy. \code{detachonly=true} allocates private storage without copying the contents (they are undefined afterwards). With \code{deep} and non-plain-data \code{T}, elements are made unique recursively even if this object is not shared. Calling it on an empty vector is harmless (prints a warning if \code{_LA_warn_empty_copyonwrite} is set).} \lafunc{int getcount() const}{Current reference count (0 for an empty vector).} \lafunc{void resize(const int n, const bool preserve=false, const bool preserve_at_end=false)}{Change size; detaches from shared data. Without \code{preserve} the new contents are undefined (no-op if the size does not change and the data are not shared). With \code{preserve} the first $\min(n_\text{old},n)$ elements are kept and new elements are zeroed (by \code{memset}); with \code{preserve_at_end} the last elements are kept and aligned to the end, the new ones being at the beginning. \code{resize(0)} deallocates.} \lafunc{void dealloc(void)}{Same as \code{resize(0)}.} \lafunc{void clear()}{Set all elements to zero (\code{LA_traits::clear}); detaches shared plain data.} \lafunc{void swap(NRVec &rhs)}{Exchange contents (size, data, counter) of two vectors in $O(1)$.} \lafunc{template NRVec > complexify(const NRVec &rhs)}{(free function) Complex vector with real part \code{rhs}. CPU only (NOT\_GPU) in the generic version; specialized for \code{double} via BLAS.} \lafunc{template void NRVec_convert(NRVec &a, const NRVec &b)}{(free function) Resize \code{a} and set \code{a[i] = (T)b[i]}.} \end{lareference} \section{Element access}\label{sec:vec:access} \begin{lareference} \lafunc{T & operator[](const int i); const T & operator[](const int i) const}{Element $i$, $0\le i &selection) const}{Gather into a new vector: \code{r[i] = x[selection[i]]}. Index range is always checked.} \lafunc{void subvector_from(const NRVec &selection, const NRVec &rhs)}{Gather into \code{*this}: \code{x[i] = rhs[selection[i]]}; \code{x.size()} must equal \code{selection.size()} (otherwise \code{laerror}); calls copyonwrite.} \lafunc{void storesubvector(const int from, const NRVec &rhs)}{Copy \code{rhs} into positions \code{from}\dots\code{from+rhs.size()-1}; plain data only; calls copyonwrite.} \lafunc{void storesubvector(const NRVec &selection, const NRVec &rhs)}{Scatter into \code{*this}: \code{x[selection[i]] = rhs[i]}; sizes of \code{selection} and \code{rhs} must agree; calls copyonwrite.} \lafunc{void storesubvector_to(const NRVec &selection, NRVec &rhs) const}{Scatter \code{*this} into \code{rhs}: \code{rhs[selection[i]] = x[i]}; \code{x.size()} must equal \code{selection.size()}; calls \code{rhs.copyonwrite()}.} \lafunc{NRVec reverse() const}{Copy with reversed order of elements.} \lafunc{NRVec concat(const NRVec &rhs) const; NRVec concatscaled(const NRVec &rhs, const T alpha=1) const}{New vector $(x, \mathtt{rhs})$, resp.\ $(x, \alpha\,\mathtt{rhs})$. If one of the vectors is empty, the other one is returned (shared; for \code{concatscaled} with an empty \code{*this} and $\alpha\neq1$ a scaled copy of \code{rhs}).} \lafunc{void concatme(const NRVec &rhs); void concatmescaled(const NRVec &rhs, const T alpha=1)}{Append \code{rhs} (resp.\ $\alpha\,\mathtt{rhs}$) to \code{*this} in place (via \code{resize} with preservation).} \lafunc{void append(const T &a); void prepend(const T &a)}{Add one element at the end / beginning. Each call reallocates; inefficient when repeated.} \lafunc{const int find(const T &val) const}{Index of the first element equal to \code{val}, $-1$ if none.} \lafunc{const int findthr(const T &val, const typename LA_traits::normtype &thr=0) const}{Index of the first element with $|x_i-\mathtt{val}|<\mathtt{thr}$, $-1$ if none (note the strict inequality: the default \code{thr=0} never matches).} \end{lareference} \section{Arithmetic and BLAS-backed operations}\label{sec:vec:arith} All compound operators call \code{copyonwrite()}. Dimensions of vector operands are checked only in DEBUG builds. For \code{double} and \code{std::complex} the operations marked BLAS are specialized to call CBLAS; the generic versions are element-wise loops (CPU only). \begin{lareference} \lafunc{NRVec& operator+=(const NRVec &rhs); NRVec& operator-=(const NRVec &rhs)}{Element-wise sum/difference (BLAS axpy).} \lafunc{NRVec& operator*=(const NRVec &rhs); NRVec& operator/=(const NRVec &rhs)}{Element-wise (Hadamard) product/quotient.} \lafunc{const NRVec operator+(const NRVec &rhs) const; const NRVec operator-(const NRVec &rhs) const}{Sum/difference. There are no binary element-wise \code{*} and \code{/} of two vectors; \code{x*y} is the scalar product.} \lafunc{NRVec& operator+=(const T &a); NRVec& operator-=(const T &a)}{Add/subtract \code{a} to/from every element (BLAS).} \lafunc{NRVec& operator*=(const T &a); NRVec& operator/=(const T &a)}{Scale every element (BLAS scal; division as multiplication by $1/a$ for the specialized types).} \lafunc{const NRVec operator+(const T &a) const; ... operator-, operator*, operator/}{\code{x+a}, \code{x-a}, \code{x*a}, \code{x/a} element-wise with a scalar.} \lafunc{const NRVec operator+(const T &a, const NRVec &x); const NRVec operator*(const T &a, const NRVec &x)}{(free functions) Scalar on the left: $a+x$ and $ax$. The noncommutative \code{a-x} and \code{a/x} are deliberately not available (declared \code{= delete}, a compile error); write \code{-x+a} explicitly.} \lafunc{const NRVec operator-() const}{Negated copy.} \lafunc{NRVec& negateme()}{$x\leftarrow -x$ in place.} \lafunc{NRVec& conjugateme(); NRVec conjugate() const}{Complex conjugation in place / conjugated copy (no-op for real types).} \lafunc{NRVec& negateconjugateme()}{$x\leftarrow -x^*$ in place (specialized for \code{std::complex} and \code{std::complex}).} \lafunc{const T operator*(const NRVec &rhs) const}{Scalar product $\sum_i x_i^*\, y_i$ (conjugating \code{*this} for complex types; BLAS dot/dotc).} \lafunc{const T dot(const T *a, const int stride = 1, bool conjugate=true) const}{$\sum_i \tilde x_i\, a_{i\cdot\mathrm{stride}}$, where $\tilde x_i=x_i^*$ if \code{conjugate} and \code{T} is complex, else $x_i$; \code{a} must have sufficient length.} \lafunc{const T dot(const NRVec &rhs, bool conjugate=true) const}{Same with a vector (no dimension check).} \lafunc{void axpy(const T alpha, const NRVec &x)}{$\mathtt{this} \leftarrow \mathtt{this} + \alpha\,\mathtt{x}$ (BLAS axpy). Only \code{double} and \code{std::complex}.} \lafunc{void axpy(const T alpha, const T *x, const int stride=1)}{Same with strided raw data; CPU only. Only \code{double} and \code{std::complex}.} \lafunc{void gemv(const T beta, const NRMat &a, const char trans, const T alpha, const NRVec &x)}{$y\leftarrow\alpha\,\mathrm{op}(A)x+\beta y$ with $y=$ \code{*this}; \code{trans} is \code{'n'} ($A$), \code{'t'} ($A\Tr$) or for complex \code{'c'} ($A\Hc$), case insensitive. \code{*this} must already have the correct size (checked in DEBUG builds) and defined contents if $\beta\neq0$.} \lafunc{void gemv(const T beta, const NRSMat &a, const char trans, const T alpha, const NRVec &x)}{Same for a packed symmetric (real) or Hermitian (complex) matrix (BLAS spmv/hpmv); \code{trans}: for complex \code{'t'} gives $a\Tr x = a^* x$, \code{'n'} and \code{'c'} give $a x$; ignored for real matrices.} \lafunc{void gemv(const T beta, const CSRMat &a, const char trans, const T alpha, const NRVec &x)}{The same for a compressed row sparse matrix, \code{trans} \code{'n'}, \code{'t'} or \code{'c'} (section~\ref{sec:sparse:csr}).} \lafunc{void gemv(const T beta, const SparseMat &a, const char trans, const T alpha, const NRVec &x, const bool treat_as_symmetric = false)}{Same for a sparse matrix (defined in \texttt{sparsemat.cc}, see Chapter~\ref{ch:sparse}); with \code{treat_as_symmetric} only one triangle is assumed to be stored.} \lafunc{void gemv(const Component_type beta, const NRMat_Noncomplex_type &a, const char trans, const Component_type alpha, const NRVec &x); void gemv(const Component_type beta, const NRSMat_Noncomplex_type &a, const char trans, const Component_type alpha, const NRVec &x)}{(Types from \code{LA_traits_complex}.) Complex vector times \emph{real} dense or packed-symmetric matrix with real coefficients; real and imaginary parts are processed separately.} \lafunc{const NRVec operator*(const NRMat &mat) const}{Row vector times matrix, $x\Tr A$ (gemv with \code{'t'}; no conjugation). For $A x$ see \code{NRMat::operator*} in Chapter~\ref{ch:mat}.} \lafunc{const NRVec operator*(const NRSMat &mat) const}{Row vector times packed symmetric/hermitian matrix, $x\Tr S$ (for hermitian $S$ computed as $S\Tr x = S^* x$ by \code{gemv} with \code{'t'}).} \lafunc{const NRVec operator*(const SparseMat &mat) const; const NRVec operator*(const CSRMat &mat) const}{Row vector times sparse matrix; CPU only.} \lafunc{const NRMat otimes(const NRVec &rhs, const bool conjugate = false, const T &scale = 1) const}{Outer product $A_{ij}=\mathrm{scale}\cdot x_i\, y_j$, with $y_j^*$ if \code{conjugate} (complex only); BLAS ger/geru/gerc.} \lafunc{const NRMat operator|(const NRVec &rhs) const}{Same as \code{otimes(rhs,true)}, i.e.\ $x y\Hc$.} \lafunc{const NRVec otimes2vec(const NRVec &rhs, const bool conjugate = false, const T &scale = 1) const}{Outer product stored as a vector of length $n_x n_y$ (row-major, index $i n_y + j$).} \end{lareference} The real-matrix \code{gemv}, \code{normalize}, \code{otimes} and \code{otimes2vec} exist only for \code{double} and \code{std::complex}; for the instantiated integer types (and complex integer types) they are defined to raise \code{laerror}. \section{Norms, reductions, extrema}\label{sec:vec:norms} \begin{lareference} \lafunc{const typename LA_traits::normtype norm(int length= -1, int offset=0, int stride=1) const}{Euclidean norm (BLAS nrm2) of \code{length} elements (default all) starting at \code{offset} with \code{stride}. Only \code{double} and \code{std::complex}.} \lafunc{NRVec& normalize(typename LA_traits::normtype* norm = 0)}{Divide by the Euclidean norm, optionally storing the norm in \code{*norm}; DEBUG: error for a zero vector. Only \code{double} and \code{std::complex}.} \lafunc{const NRVec unitvector() const}{Normalized copy.} \lafunc{const typename LA_traits::normtype asum() const}{$\sum_i |x_i|$ (BLAS asum; for complex $\sum_i |\mathrm{Re}\,x_i|+|\mathrm{Im}\,x_i|$). Only \code{double} and \code{std::complex}.} \lafunc{inline int iamax() const}{Zero-based index of the element of largest absolute value (BLAS i?amax; for complex the 1-norm $|\mathrm{Re}|+|\mathrm{Im}|$). Only \code{double} and \code{std::complex}. \code{laerror} for an empty vector.} \lafunc{inline const T amax() const; inline const T amin() const}{The element (with sign) of largest / smallest absolute value (complex: 1-norm). Only \code{double} and \code{std::complex}. \code{laerror} for an empty vector.} \lafunc{const T max() const; const T min() const}{Largest / smallest element (0 for an empty vector). Only real types (instantiated for the integer types, \code{float}, \code{double}).} \lafunc{const T sum() const}{$\sum_i x_i$.} \lafunc{const T sumsqr() const}{$\sum_i x_i^2$, 0 for an empty vector. No conjugation for complex types; use \code{norm()} for $\sqrt{\sum_i|x_i|^2}$.} \lafunc{const T prod() const}{$\prod_i x_i$, 1 for an empty vector.} \lafunc{NRVec::normtype> abs() const}{Vector of $|x_i|$.} \lafunc{NRVec::normtype> diffabs(const NRVec &rhs) const}{Vector of $|x_i|-|y_i|$.} \end{lareference} \section{Other member functions}\label{sec:vec:other} \subsection*{Comparison} \begin{lareference} \lafunc{const bool operator==(const NRVec &rhs) const; const bool operator!=(const NRVec &rhs) const}{Equal size and elements. For plain data the comparison is bytewise (\code{memcmp}), so e.g.\ \code{0.0} and \code{-0.0} differ.} \lafunc{const bool operator<(const NRVec &rhs) const; ... operator>, operator<=, operator>=}{Lexicographic order using \code{LA_traits::smaller/bigger}; a proper prefix is smaller. Raises \code{laerror} for complex elements.} \end{lareference} \subsection*{Sorting and permutations} \begin{lareference} \lafunc{int sort(int direction = 0, int from = 0, int to = -1, int *perm = NULL, bool stable=false)}{Quicksort of elements \code{from}\dots\code{to} (\code{-1}: last) in place, ascending for \code{direction==0}, descending otherwise; returns the parity (0/1) of the applied permutation. If \code{perm} is given, \code{perm[from..to]} (initialized by the caller) is permuted along with the elements. \code{stable} selects a stable variant. Calls copyonwrite.} \lafunc{int sort(int direction, NRPerm &perm, bool stable=false)}{Sort the whole vector; \code{perm} (of the same size) is set to the identity and returned with \code{perm[i]} = original (1-based) position of the element now at position $i$ (1-based).} \lafunc{void printsorted(std::ostream &s, int direction=1, bool absvalue=false, bool stable=false, typename LA_traits::normtype thr=0, int topmax=0, const NRMat *indexmap=NULL) const}{Print lines ``\emph{index value}'' in sorted order (default descending) without modifying the vector. \code{absvalue}: sort by $|x_i|$; \code{thr}: skip elements with $|x_i|<\mathrm{thr}$; \code{topmax}: print at most this many lines (0 = all); \code{indexmap}: print \code{(*indexmap)[i][0]} and \code{(*indexmap)[i][1]} instead of the index $i$.} \lafunc{bool bigger(int i, int j) const; bool smaller(int i, int j) const; void swap(int i, int j)}{Element comparison and exchange used by the sorting templates (\texttt{qsort.h}). \code{swap(i,j)} is element-level access and, like \code{operator[]}, does not call copyonwrite: call it before, outside the loop (Sec.~\ref{sec:vec:storage}).} \lafunc{const NRVec permuted(const NRPerm &p, const bool inverse=false) const}{Permuted copy: \code{r[p[i]-1] = x[i-1]}, or with \code{inverse} \code{r[i-1] = x[p[i]-1]} ($p$ is 1-based, see Chapter~\ref{ch:permutation}).} \lafunc{void permuteme(const NRPerm &p, const bool inverse=false); void permuteme(const CyclePerm &p)}{The same in place; for a cycle $(c_1 \dots c_L)$ the element at $c_{k}$ moves to $c_{k+1}$ and the one at $c_L$ to $c_1$.} \end{lareference} \subsection*{Element-wise function application} \begin{lareference} \lafunc{NRVec& call_on_me(T (*_F)(const T &))}{$x_i\leftarrow F(x_i)$ for a plain function pointer. This non-template overload is kept on purpose: when the name of an \emph{overloaded} function is passed, the fixed parameter type selects the right overload (the template below cannot deduce its argument from an overload set). Note that the function must take \code{const T &}, so e.g.\ \code{std::sqrt} does not match it.} \lafunc{template NRVec& call_on_me(F _F)}{$x_i\leftarrow F(x_i)$ for any callable (functor, lambda, function with another compatible signature). For a single non-overloaded function both overloads match and the non-template one is chosen.} \lafunc{template NRVec& call_on_me(F _F, const NRVec &rhs)}{Binary version $x_i\leftarrow F(x_i, \mathtt{rhs}_i)$; sizes checked in DEBUG.} \end{lareference} All three are CPU only and call copyonwrite. \subsection*{Random numbers} \begin{lareference} \lafunc{void randomize(const typename LA_traits::normtype &x)}{Fill with uniform random numbers from $[-x,x)$ (real and imaginary parts independently for complex), using \code{RANDDOUBLESIGNED} (Chapter~\ref{ch:utilities}). Only \code{double} and \code{std::complex}.} \end{lareference} \subsection*{Input/output} See Sec.~\ref{sec:concepts:io} for the general conventions. \begin{lareference} \lafunc{void put(int fd, bool dimensions=1, bool transp=0, bool orca_format=false) const}{Binary output to file descriptor. With \code{dimensions}: header \code{int n}, then \code{int 1} (padding), or with \code{orca_format} \code{int sizeof(T)}; followed by the elements (\code{LA_traits::multiput}, recursive for nested types). \code{transp} is unused.} \lafunc{void get(int fd, bool dimensions=1, bool transp=0, bool orca_format=false)}{Binary input matching \code{put}; with \code{dimensions} the vector is resized, otherwise the current size is used (and copyonwrite called). \code{orca_format} checks the element size.} \lafunc{void fprintf(FILE *f, const char *format, const int modulo) const}{Formatted output via \code{lawritemat} as a $1\times n$ matrix (Chapter~\ref{ch:nonclass}).} \lafunc{void fscanf(FILE *f, const char *format)}{Read the dimension and then the elements with the given \code{scanf} format (e.g.\ \texttt{"\%lf"} for \code{double}); resizes.} \end{lareference} \subsection*{Miscellaneous} \begin{lareference} \lafunc{GPUID getlocation() const; void moveto(const GPUID dest)}{Memory location (always \code{cpu} without \code{CUDALA}, then \code{moveto} is a no-op); see Sec.~\ref{sec:concepts:gpu}.} \lafunc{void setcoldim(int i); void simplify()}{Dummies for interface compatibility with other classes.} \end{lareference} \section{Related free functions}\label{sec:vec:free} \begin{lareference} \lafunc{std::ostream & operator<<(std::ostream &s, const NRVec &x)}{Text output: the size on one line, then the elements separated by spaces on the next line (converted to \code{LA_traits_io::IOtype}, so e.g.\ \code{char} is printed as a number).} \lafunc{std::istream & operator>>(std::istream &s, NRVec &x)}{Reads the format written by \code{<<}; resizes \code{x}.} \lafunc{template void NRVec_simplify(NRVec &x, const typename LA_traits::normtype thr=0, bool alwayskeepfirst=false)}{For vectors of ``coefficient $\times$ element'' terms (\code{T} must provide sorting traits, \code{operator==} comparing only the element, and \code{LA_traits::coefficient}, \code{abscoefficient}, \code{elementtype}): sort, merge equal elements by adding coefficients, drop terms with zero coefficient or $|\text{coefficient}|<\mathrm{thr}$ (the first term is kept if \code{alwayskeepfirst}), and shrink the vector. Public API; within the library it is presently used by \code{PermutationAlgebra::simplify()}.} \lafunc{template typename LA_traits::normtype MYABS(const T &x)}{\code{std::abs} with pass-through specializations for unsigned integer types; auxiliary.} \end{lareference} \code{complexify} and \code{NRVec_convert} are listed in Sec.~\ref{sec:vec:construct}. The header also defines constants \code{CONE}, \code{CMONE}, \code{CZERO} (complex $1,-1,0$ for CBLAS calls) and the internal macros \code{NRVECMAT_OPER}, \code{NRVECMAT_OPER_NONCOMMUTATIVE}, \code{NRVECMAT_OPER2} generating the binary operators from the compound ones. \section{Vectors indexed from one: NRVec\_from1}\label{sec:vec:from1} \code{NRVec_from1} is derived publicly from \code{NRVec} and differs only in indexing: \code{operator[]} takes $1\le i\le n$ (same DEBUG checks as \code{NRVec}), and \code{iamax()} returns a 1-based index. It is used e.g.\ for permutations (Chapter~\ref{ch:permutation}). Everything else is inherited unchanged and \emph{remains zero-based} (e.g.\ \code{subvector}, \code{find}, \code{sort(direction,from,to,...)}, the raw pointer). \begin{lareference} \lafunc{NRVec_from1(); explicit NRVec_from1(const int n); NRVec_from1(const T &a, const int n); NRVec_from1(const T *a, const int n)}{As for \code{NRVec}.} \lafunc{template NRVec_from1(const T (&a)[SIZE]); explicit NRVec_from1(const std::list l)}{As for \code{NRVec}.} \lafunc{NRVec_from1(const NRVec &rhs)}{Implicit conversion from the base class (shares data).} \lafunc{const T& operator[](const int i) const; T& operator[](const int i)}{Element $i$, 1-based.} \lafunc{int iamax() const}{1-based index of the element of largest absolute value.} \end{lareference} \lawarning{\code{NRVec_from1} does not redeclare \code{operator=(const T&)}; the implicitly declared copy assignment hides it, so \code{f = 0.;} does not compile for \code{NRVec_from1 f}. Use the \code{(value, size)} constructor or assign through a base class reference.} \section{Examples}\label{sec:vec:examples} \begin{lstlisting} #include "la.h" using namespace LA; double sq(const double &a) {return a*a;} float sq(const float &a) {return a*a;} int main() { NRVec x({1.,2.,3.}); NRVec y(x); // shares data with x y *= 2.; // y gets its own copy, x unchanged double d = x*y; // scalar product = 28 NRVec z = x + y*0.5; z.axpy(-1.,x); // z = x std::cout << d << " " << z.norm() << std::endl; NRVec w(0.,5); // five zeros NRVec sel({4,0,2}); w.storesubvector(sel,x); // scatter: w[4]=x[0], w[0]=x[1], w[2]=x[2] NRVec g(3); g.subvector_from(sel,w); // gather: g[i]=w[sel[i]], i.e. g == x std::cout << w << g; x.call_on_me(sq); // overloaded name: non-template overload x.call_on_me([](const double &a){return a+1.;}); // lambda: template overload x.call_on_me([](const double &a, const double &b){return a>b?a:b;}, y); // binary x.copyonwrite(); // needed before writing via operator[] x[0] = -1.; NRVec_from1 f(1.,3); f[3] = 5.; // last element std::cout << f << f.iamax() << std::endl; // prints 3 NRVec > c(x,true); // purely imaginary std::cout << c << complexify(x); } \end{lstlisting} Sorting with the permutation returned: \begin{lstlisting} NRVec v(12); v.randomize(1.); NRPerm p(v.size()); NRVec s(v); s.sort(0,p); // ascending; s copied before sorting, v unchanged // s[i-1] == v[p[i]-1] for i=1..n v.printsorted(std::cout,1,true); // descending by absolute value \end{lstlisting} \section{Pitfalls}\label{sec:vec:pitfalls} \begin{itemize} \item \code{NRVec x(n)} is not initialized; use \code{NRVec x(0.,n)} or \code{x.clear()}. The argument order of the filling constructor is \emph{(value, size)}. \item After \code{y=x} the data are shared: call \code{y.copyonwrite()} before \code{y[i]=...}. In DEBUG builds reading an element of a shared non-const vector via \code{operator[]} also triggers the error; read through a const reference. \item \code{NRVec(const NRMat&)} and \code{NRVec(const NRSMat&)} share the data with the matrix (unless \code{MATPTR}); writing into the vector after \code{copyonwrite()} does not affect the matrix, but the matrix and the vector are not independent before that. \item A skeleton vector \code{NRVec(ptr,n,true)} never writes into the foreign memory through modifying member functions; they silently make a copy. \item \code{x*y} is the (conjugated) scalar product, not an element-wise product; use \code{x*=y} for that. \item \code{a-x} and \code{a/x} with a scalar \code{a} on the left do not compile (deleted); write \code{-x+a}. \item \code{resize()} without \code{preserve} leaves the contents undefined. \item \code{norm}, \code{normalize}, \code{asum}, \code{amax}, \code{amin}, \code{iamax}, \code{axpy}, \code{randomize}, \code{gemv}, \code{otimes} are intended for floating-point types only and are presently available for \code{double} and \code{std::complex} (link error or \code{laerror} otherwise, by design for integer types); \code{max}/\code{min} only for real types. \item \code{NRVec_from1} indexing is 1-based only in \code{operator[]} and \code{iamax()}. \end{itemize}