root/win32/itpp-4.0.1/itpp/base/vec.h @ 44

Revision 35, 69.9 kB (checked in by mido, 16 years ago)

zasadni zmeny ve /win32

Line 
1/*!
2 * \file
3 * \brief Templated Vector Class Definitions
4 * \author Tony Ottosson, Tobias Ringstrom, Adam Piatyszek and Conrad Sanderson
5 *
6 * -------------------------------------------------------------------------
7 *
8 * IT++ - C++ library of mathematical, signal processing, speech processing,
9 *        and communications classes and functions
10 *
11 * Copyright (C) 1995-2007  (see AUTHORS file for a list of contributors)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 *
27 * -------------------------------------------------------------------------
28 */
29
30#ifndef VEC_H
31#define VEC_H
32
33#ifndef _MSC_VER
34#  include <itpp/config.h>
35#else
36#  include <itpp/config_msvc.h>
37#endif
38
39#include <itpp/base/itassert.h>
40#include <itpp/base/math/misc.h>
41#include <itpp/base/copy_vector.h>
42#include <itpp/base/factory.h>
43
44
45namespace itpp {
46
47  // Declaration of Vec
48  template<class Num_T> class Vec;
49  // Declaration of Mat
50  template<class Num_T> class Mat;
51  // Declaration of bin
52  class bin;
53
54  //-----------------------------------------------------------------------------------
55  // Declaration of Vec Friends
56  //-----------------------------------------------------------------------------------
57
58  //! Addition of two vectors
59  template<class Num_T> const Vec<Num_T> operator+(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
60  //! Addition of a vector and a scalar
61  template<class Num_T> const Vec<Num_T> operator+(const Vec<Num_T> &v, const Num_T t);
62  //! Addition of a scalar and a vector
63  template<class Num_T> const Vec<Num_T> operator+(const Num_T t, const Vec<Num_T> &v);
64
65  //! Subtraction of a vector from a vector
66  template<class Num_T> const Vec<Num_T> operator-(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
67  //! Subtraction of a scalar from a vector
68  template<class Num_T> const Vec<Num_T> operator-(const Vec<Num_T> &v, const Num_T t);
69  //! Subtraction of vector from scalar. Results in a vector
70  template<class Num_T> const Vec<Num_T> operator-(const Num_T t, const Vec<Num_T> &v);
71  //! Negation of vector
72  template<class Num_T> const Vec<Num_T> operator-(const Vec<Num_T> &v);
73
74  //! Inner (dot) product of two vectors v1 and v2
75  template<class Num_T> Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
76  //! Inner (dot) product of two vectors v1 and v2
77  template<class Num_T> Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
78  /*!
79   * \brief Outer product of two vectors v1 and v2
80   *
81   * When \a v1 and \a v2 are complex vectors (cvec), the third boolean
82   * argument \a hermitian can be set to \a true to conjugate \a v2
83   * (Matlab's v1 * v2' operation). This parameter is ignored for types
84   * other then cvec.
85   */
86  template<class Num_T>
87  const Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
88                                 bool hermitian = false);
89  //! Multiplication of a vector and a scalar
90  template<class Num_T> const Vec<Num_T> operator*(const Vec<Num_T> &v, const Num_T t);
91  //! Multiplication of a scalar and a vector. Results in a vector
92  template<class Num_T> const Vec<Num_T> operator*(const Num_T t, const Vec<Num_T> &v);
93
94  //! Element-wise multiplication of the two vectors.  Same functionality as Matlab/Octave expression a .* b
95  template<class Num_T> const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b);
96  //! Element-wise multiplication of the three vectors
97  template<class Num_T> const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c);
98  //! Element-wise multiplication of the four vectors
99  template<class Num_T> const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d);
100
101  //! Element-wise multiplication of the two vectors, storing the result in vector \c out (which is re-sized if necessary)
102  template<class Num_T> void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out);
103  //! Element-wise multiplication of the three vectors, storing the result in vector \c out (which is re-sized if necessary)
104  template<class Num_T> void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, Vec<Num_T> &out);
105  //! Element-wise multiplication of the four vectors, storing the result in vector \c out (which is re-sized if necessary)
106  template<class Num_T> void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d, Vec<Num_T> &out);
107
108  //! In-place element-wise multiplication of two vectors. Fast version of b = elem_mult(a,b)
109  template<class Num_T> void elem_mult_inplace(const Vec<Num_T> &a, Vec<Num_T> &b);
110  //! Element-wise multiplication of two vectors, followed by summation of the resultant elements. Fast version of sum(elem_mult(a,b))
111  template<class Num_T> Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
112
113  //! Division of all elements in \c v with \c t
114  template<class Num_T> const Vec<Num_T> operator/(const Vec<Num_T> &v, const Num_T t);
115  //! Division of \c t with all elements in \c v
116  template<class Num_T> const Vec<Num_T> operator/(const Num_T t, const Vec<Num_T> &v);
117
118  //! Elementwise division of two vectors. Same functionality as Matlab/Octave expression a ./ b
119  template<class Num_T> const Vec<Num_T> elem_div(const Vec<Num_T> &a, const Vec<Num_T> &b);
120  //! Elementwise division of scalar \c t and vector \c v
121  template<class Num_T> const Vec<Num_T> elem_div(const Num_T t, const Vec<Num_T> &v);
122  //! Elementwise division of two vectors, storing the result in vector \c out (which is re-sized if necessary)
123  template<class Num_T> void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out);
124  //! Elementwise division of two vectors, followed by summation of the resultant elements. Fast version of sum(elem_div(a,b))
125  template<class Num_T> Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b);
126
127  //! Append element \c a to the end of the vector \c v
128  template<class Num_T> const Vec<Num_T> concat(const Vec<Num_T> &v, const Num_T a);
129  //! Concat element \c a to the beginning of the vector \c v
130  template<class Num_T> const Vec<Num_T> concat(const Num_T a, const Vec<Num_T> &v);
131  //! Concat vectors \c v1 and \c v2
132  template<class Num_T> const Vec<Num_T> concat(const Vec<Num_T> &v1,const Vec<Num_T> &v2);
133  //! Concat vectors \c v1, \c v2 and \c v3
134  template<class Num_T> const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2, const Vec<Num_T> &v3);
135  //! Concat vectors \c v1, \c v2, \c v3 and \c v4
136  template<class Num_T> const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2, const Vec<Num_T> &v3, const Vec<Num_T> &v4);
137  //! Concat vectors \c v1, \c v2 \c v3, \c v4 and \c v5
138  template<class Num_T> const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2, const Vec<Num_T> &v3, const Vec<Num_T> &v4, const Vec<Num_T> &v5);
139
140  //-----------------------------------------------------------------------------------
141  // Declaration of Vec
142  //-----------------------------------------------------------------------------------
143
144  /*!
145    \ingroup arr_vec_mat
146    \brief Vector Class (Templated)
147    \author Tony Ottosson, Tobias Ringstrom, Adam Piatyszek and Conrad Sanderson
148
149    Vectors can be of arbitrarily types, but conversions and functions are
150    prepared for \c bin, \c short, \c int, \c double, and \c complex<double>
151    vectors and these are predefined as: \c bvec, \c svec, \c ivec, \c vec,
152    and \c cvec. \c double and \c complex<double> are \c double and
153    \c complex<double> respectively.
154
155    Examples:
156
157    Vector Constructors:
158    When constructing a vector without a length (memory) use
159    \code vec temp; \endcode
160    For construction of a vector of a given length use
161    \code vec temp(length); \endcode
162    It is also possible to assign the constructed vector the value and size
163    of another vector by
164    \code vec temp(invector); \endcode
165    If you have explicit values you would like to assign to the vector it is
166    possible to do this using strings as:
167    \code
168    vec a("0 0.7 5 9.3"); // that is a = [0, 0.7, 5, 9.3]
169    vec a="0 0.7 5 9.3";  // the constructor are called implicitly
170    ivec b="0:5";  // that is b = [0, 1, 2, 3, 4, 5]
171    vec c="3:2.5:13";  // that is c = [3, 5.5, 8, 10.5, 13]
172    \endcode
173    It is also possible to change length by
174    \code temp.set_size(new_length, false); \endcode
175    where \c false is used to indicate that the old values in \c temp
176    is not copied. If you like to preserve the values use \c true.
177
178    There are a number of methods to access parts of a vector. Examples are
179    \code
180    a(5);     // Element number 5
181    a(5,9);  // Elements 5, 6, 7, 8, and 9
182    a.left(10);  // The 10 most left elements (the first)
183    a.right(10); // The 10 most right elements (the last)
184    a.mid(5, 7); // 7 elements starting from element 5
185    \endcode
186
187    It is also possible to modify parts of a vector as e.g. in
188    \code
189    a.del(5);    // deletes element number 5
190    a.ins(3.4, 9); // inserts the element 3.4 at position 9
191    a.replace_mid(12, b); // replaces elements from 12 with the vector b
192    \endcode
193
194    It is of course also possible to perform the common linear algebra
195    methods such as addition, subtraction, and scalar product (*). Observe
196    though, that vectors are assumed to be column-vectors in operations with
197    matrices.
198
199    Most elementary functions such as sin(), cosh(), log(), abs(), ..., are
200    available as operations on the individual elements of the vectors. Please
201    see the individual functions for more details.
202
203    By default, the Vec elements are created using the default constructor for
204    the element type. This can be changed by specifying a suitable Factory in
205    the Vec constructor call; see Detailed Description for Factory.
206  */
207  template<class Num_T>
208  class Vec {
209  public:
210    //! The type of the vector values
211    typedef Num_T value_type;
212
213    //! Default constructor. An element factory \c f can be specified.
214    explicit Vec(const Factory &f = DEFAULT_FACTORY);
215    //! Constructor with size parameter. An element factory \c f can be specified.
216    explicit Vec(int size, const Factory &f = DEFAULT_FACTORY);
217    //! Copy constructor
218    Vec(const Vec<Num_T> &v);
219    //! Copy constructor, which takes an element factory \c f as an additional argument.
220    Vec(const Vec<Num_T> &v, const Factory &f);
221    //! Constructor taking a char string as input. An element factory \c f can be specified.
222    Vec(const char *values, const Factory &f = DEFAULT_FACTORY);
223    //! Constructor taking a string as input. An element factory \c f can be specified.
224    Vec(const std::string &values, const Factory &f = DEFAULT_FACTORY);
225    //! Constructor taking a C-array as input. Copies all data. An element factory \c f can be specified.
226    Vec(const Num_T *c_array, int size, const Factory &f = DEFAULT_FACTORY);
227
228    //! Destructor
229    ~Vec();
230
231    //! The size of the vector
232    int length() const { return datasize; }
233    //! The size of the vector
234    int size() const { return datasize; }
235
236    //! Set length of vector. if copy = true then keeping the old values
237    void set_size(int size, const bool copy=false);
238    //! Set length of vector. if copy = true then keeping the old values
239    void set_length(int size, const bool copy=false) { set_size(size, copy); }
240    //! Set the vector to the all zero vector
241    void zeros();
242    //! Set the vector to the all zero vector
243    void clear() { zeros(); }
244    //! Set the vector to the all one vector
245    void ones();
246    //! Set the vector equal to the values in the \c str string
247    void set(const char *str);
248    //! Set the vector equal to the values in the \c str string
249    void set(const std::string &str);
250
251    //! C-style index operator. First element is 0
252    const Num_T &operator[](int i) const;
253    //! Index operator. First element is 0
254    const Num_T &operator()(int i) const;
255    //! C-style index operator. First element is 0
256    Num_T &operator[](int i);
257    //! Index operator. First element is 0
258    Num_T &operator()(int i);
259    //! Sub-vector with elements from \c i1 to \c i2. Index -1 indicates the last element.
260    const Vec<Num_T> operator()(int i1, int i2) const;
261    //! Sub-vector where the elements are given by the list \c indexlist
262    const Vec<Num_T> operator()(const Vec<int> &indexlist) const;
263
264    //! Accessor-style method. First element is 0
265    const Num_T &get(int i) const;
266    //! Sub-vector with elements from \c i1 to \c i2. Index -1 indicates the last element.
267    const Vec<Num_T> get(int i1, int i2) const;
268    //! Modifier-style method. First element is 0
269    void set(int i, const Num_T &v);
270
271    //! Matrix transpose. Converts to a matrix with the vector in the first row
272    Mat<Num_T> transpose() const;
273    //! Matrix transpose. Converts to a matrix with the vector in the first row
274    Mat<Num_T> T() const { return this->transpose(); }
275    //! Hermitian matrix transpose. Converts to a matrix with the conjugate of the vector in the first row
276    Mat<Num_T> hermitian_transpose() const;
277    //! Hermitian matrix transpose. Converts to a matrix with the conjugate of the vector in the first row
278    Mat<Num_T> H() const { return this->hermitian_transpose(); }
279
280    //! Addition of vector
281    Vec<Num_T>& operator+=(const Vec<Num_T> &v);
282    //! Addition of scalar
283    Vec<Num_T>& operator+=(const Num_T t);
284    //! Addition of two vectors
285    friend const Vec<Num_T> operator+<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
286    //! Addition of a vector and a scalar
287    friend const Vec<Num_T> operator+<>(const Vec<Num_T> &v, const Num_T t);
288    //! Addition of a scalar and a vector
289    friend const Vec<Num_T> operator+<>(const Num_T t, const Vec<Num_T> &v);
290
291    //! Subtraction of vector
292    Vec<Num_T>& operator-=(const Vec<Num_T> &v);
293    //! Subtraction of scalar
294    Vec<Num_T>& operator-=(const Num_T t);
295    //! Subtraction of \c v2 from \c v1
296    friend const Vec<Num_T> operator-<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
297    //! Subtraction of scalar from vector
298    friend const Vec<Num_T> operator-<>(const Vec<Num_T> &v, const Num_T t);
299    //! Sutraction of vector from scalar
300    friend const Vec<Num_T> operator-<>(const Num_T t, const Vec<Num_T> &v);
301    //! Negation of vector
302    friend const Vec<Num_T> operator-<>(const Vec<Num_T> &v);
303
304    //! Multiply with a scalar
305    Vec<Num_T>& operator*=(const Num_T t);
306    //! Inner (dot) product
307    friend Num_T operator*<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
308    //! Inner (dot) product
309    friend Num_T dot <>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
310    //! Outer product of two vectors v1 and v2
311    friend const Mat<Num_T> outer_product <>(const Vec<Num_T> &v1,
312                                             const Vec<Num_T> &v2,
313                                             bool hermitian);
314    //! Elementwise multiplication of vector and scalar
315    friend const Vec<Num_T> operator*<>(const Vec<Num_T> &v, const Num_T t);
316    //! Elementwise multiplication of vector and scalar
317    friend const Vec<Num_T> operator*<>(const Num_T t, const Vec<Num_T> &v);
318
319    //! Elementwise multiplication
320    friend const Vec<Num_T> elem_mult <>(const Vec<Num_T> &a, const Vec<Num_T> &b);
321    //! Elementwise multiplication of three vectors
322    friend const Vec<Num_T> elem_mult <>(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c);
323    //! Elementwise multiplication of four vectors
324    friend const Vec<Num_T> elem_mult <>(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d);
325
326    //! Elementwise multiplication, storing the result in vector \c out (which is re-sized if necessary)
327    friend void elem_mult_out <>(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out);
328    //! Elementwise multiplication of three vectors, storing the result in vector \c out (which is re-sized if necessary)
329    friend void elem_mult_out <>(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, Vec<Num_T> &out);
330    //! Elementwise multiplication of four vectors, storing the result in vector \c out (which is re-sized if necessary)
331    friend void elem_mult_out <>(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d, Vec<Num_T> &out);
332
333    //! In-place element-wise multiplication of two vectors. Fast version of b = elem_mult(a,b)
334    friend void elem_mult_inplace <>(const Vec<Num_T> &a, Vec<Num_T> &b);
335    //! Element-wise multiplication of two vectors, followed by summation of the resultant elements. Fast version of sum(elem_mult(a,b))
336    friend Num_T elem_mult_sum <>(const Vec<Num_T> &a, const Vec<Num_T> &b);
337
338    //! Elementwise division
339    Vec<Num_T>& operator/=(const Num_T t);
340    //! Elementwise division
341    Vec<Num_T>& operator/=(const Vec<Num_T> &v);
342
343    //! Elementwise division
344    friend const Vec<Num_T> operator/<>(const Vec<Num_T> &v, const Num_T t);
345    //! Elementwise division
346    friend const Vec<Num_T> operator/<>(const Num_T t, const Vec<Num_T> &v);
347
348    //! Elementwise division
349    friend const Vec<Num_T> elem_div <>(const Vec<Num_T> &v1, const Vec<Num_T> &v2);
350    //! Elementwise division
351    friend const Vec<Num_T> elem_div <>(const Num_T t, const Vec<Num_T> &v);
352    //! Elementwise division
353    friend void elem_div_out <>(const Vec<Num_T> &v1, const Vec<Num_T> &v2, Vec<Num_T> &out);
354    //! Elementwise division, followed by summation of the resultant elements. Fast version of sum(elem_mult(a,b))
355    friend Num_T elem_div_sum <>(const Vec<Num_T> &a, const Vec<Num_T> &b);
356
357    //! Get the elements in the vector where \c binlist is \c 1
358    Vec<Num_T> get(const Vec<bin> &binlist) const;
359    //! Get the right \c nr elements from the vector
360    Vec<Num_T> right(int nr) const;
361    //! Get the left \c nr elements from the vector
362    Vec<Num_T> left(int nr) const;
363    //! Get the middle part of vector from \c start including \c nr elements
364    Vec<Num_T> mid(int start, int nr) const;
365    //! Split the vector into two parts at element \c pos. Return the first part and keep the second.
366    Vec<Num_T> split(int pos);
367    //! Shift in element \c In at position 0 \c n times
368    void shift_right(const Num_T In, int n=1);
369    //! Shift in vector \c In at position 0
370    void shift_right(const Vec<Num_T> &In);
371    //! Shift out the \c n left elements and a the same time shift in the element \c at last position \c n times
372    void shift_left(const Num_T In, int n=1);
373    //! Shift in vector \c In at last position
374    void shift_left(const Vec<Num_T> &In);
375
376    //! Append element \c a to the end of the vector \c v
377    friend const Vec<Num_T> concat<>(const Vec<Num_T> &v, const Num_T a);
378    //! Concat element \c a to the beginning of the vector \c v
379    friend const Vec<Num_T> concat<>(const Num_T a, const Vec<Num_T> &v);
380    //! Concat vectors \c v1 and \c v2
381    friend const Vec<Num_T> concat<>(const Vec<Num_T> &v1,const Vec<Num_T> &v2);
382    //! Concat vectors \c v1, \c v2 and \c v3
383    friend const Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
384                                     const Vec<Num_T> &v3);
385    //! Concat vectors \c v1, \c v2, \c v3 and \c v4
386    friend const Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
387                                     const Vec<Num_T> &v3, const Vec<Num_T> &v4);
388    //! Concat vectors \c v1, \c v2, \c v3, \c v4 and \c v5
389    friend const Vec<Num_T> concat<>(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
390                                     const Vec<Num_T> &v3, const Vec<Num_T> &v4,
391                                     const Vec<Num_T> &v5);
392
393    //! Set subvector defined by indicies \c i1 to \c i2 to vector \c v
394    void set_subvector(int i1, int i2, const Vec<Num_T> &v);
395    //! Set subvector defined by first index \c i and size of vector \c v to \c v
396    void set_subvector(int i, const Vec<Num_T> &v);
397    //! Set subvector defined by indicies i1 to i2 to constant t
398    void set_subvector(int i1, int i2, const Num_T t);
399    //! Replace the elements from \c pos by the vector \c v
400    void replace_mid(int pos, const Vec<Num_T> &v);
401    //! Delete element number \c index
402    void del(int index);
403    //! Delete elements from \c i1 to \c i2
404    void del(int i1, int i2);
405    //! Insert element \c in at \c index
406    void ins(int index, const Num_T in);
407    //! Insert vector \c in at \c index
408    void ins(int index, const Vec<Num_T> &in);
409
410    //! Assign all elements in vector to \c t
411    Vec<Num_T>& operator=(const Num_T t);
412    //! Assign vector the value and length of \c v
413    Vec<Num_T>& operator=(const Vec<Num_T> &v);
414    //! Assign vector equal to the 1-dimensional matrix \c m
415    Vec<Num_T>& operator=(const Mat<Num_T> &m);
416    //! Assign vector the values in the string \c values
417    Vec<Num_T>& operator=(const char *values);
418
419    //! Elementwise equal to the scalar
420    Vec<bin> operator==(const Num_T value) const;
421    //! Elementwise not-equal to the scalar
422    Vec<bin> operator!=(const Num_T value) const;
423    //! Elementwise less than the scalar
424    Vec<bin> operator<(const Num_T value) const;
425    //! Elementwise less than and equal to the scalar
426    Vec<bin> operator<=(const Num_T value) const;
427    //! Elementwise greater than the scalar
428    Vec<bin> operator>(const Num_T value) const;
429    //! Elementwise greater than and equal to the scalar
430    Vec<bin> operator>=(const Num_T value) const;
431
432    //! Compare two vectors. False if wrong sizes or different values
433    bool operator==(const Vec<Num_T> &v) const;
434    //! Compare two vectors. True if different
435    bool operator!=(const Vec<Num_T> &v) const;
436
437    //! Index operator without boundary check. Not recommended to use.
438    Num_T &_elem(int i) { return data[i]; }
439    //! Index operator without boundary check. Not recommended to use.
440    const Num_T &_elem(int i) const { return data[i]; }
441
442    //! Get the pointer to the internal structure. Not recommended to use.
443    Num_T *_data() { return data; }
444    //! Get the pointer to the internal structure. Not recommended to use.
445    const Num_T *_data() const { return data; }
446
447  protected:
448    //! Allocate storage for a vector of length \c size.
449    void alloc(int size);
450    //! Free the storage space allocated by the vector
451    void free();
452
453    //! The current number of elements in the vector
454    int datasize;
455    //! A pointer to the data area
456    Num_T *data;
457    //! Element factory (set to DEFAULT_FACTORY to use Num_T default constructors only)
458    const Factory &factory;
459  private:
460    // This function is used in set() methods to replace commas with spaces
461    std::string replace_commas(const std::string &str);
462  };
463
464  //-----------------------------------------------------------------------------------
465  // Type definitions of vec, cvec, ivec, svec, and bvec
466  //-----------------------------------------------------------------------------------
467
468  /*!
469    \relates Vec
470    \brief Definition of double vector type
471  */
472  typedef Vec<double> vec;
473
474  /*!
475    \relates Vec
476    \brief Definition of complex<double> vector type
477  */
478  typedef Vec<std::complex<double> > cvec;
479
480  /*!
481    \relates Vec
482    \brief Definition of integer vector type
483  */
484  typedef Vec<int> ivec;
485
486  /*!
487    \relates Vec
488    \brief Definition of short vector type
489  */
490  typedef Vec<short int> svec;
491
492  /*!
493    \relates Vec
494    \brief Definition of binary vector type
495  */
496  typedef Vec<bin> bvec;
497
498} //namespace itpp
499
500
501#include <itpp/base/mat.h>
502
503namespace itpp {
504
505  //-----------------------------------------------------------------------------------
506  // Declaration of input and output streams for Vec
507  //-----------------------------------------------------------------------------------
508
509  /*!
510    \relates Vec
511    \brief Stream output of vector
512  */
513  template<class Num_T>
514  std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v);
515
516  /*!
517    \relates Vec
518    \brief Stream input of vector
519
520    The input can be on the form "1 2 3" or "[1 2 3]", i.e. with or without
521    brackets. The first form is compatible with the set method, while the
522    second form is compatible with the ostream operator. The elements can be
523    separated by blank space or commas. "[]" means an empty vector. "1:4"
524    means "1 2 3 4". "1:3:10" means every third integer from 1 to 10, i.e.
525    "1 4 7 10".
526  */
527  template<class Num_T>
528  std::istream &operator>>(std::istream &is, Vec<Num_T> &v);
529
530  //-----------------------------------------------------------------------------------
531  // Implementation of templated Vec members and friends
532  //-----------------------------------------------------------------------------------
533
534  template<class Num_T> inline
535  void Vec<Num_T>::alloc(int size)
536  {
537    if (size > 0) {
538      create_elements(data, size, factory);
539      datasize = size;
540    }
541    else {
542      data = 0;
543      datasize = 0;
544    }
545  }
546
547  template<class Num_T> inline
548  void Vec<Num_T>::free()
549  {
550    destroy_elements(data, datasize);
551    datasize = 0;
552  }
553
554
555  template<class Num_T> inline
556  Vec<Num_T>::Vec(const Factory &f) : datasize(0), data(0), factory(f) {}
557
558  template<class Num_T> inline
559  Vec<Num_T>::Vec(int size, const Factory &f) : datasize(0), data(0), factory(f)
560  {
561    it_assert_debug(size>=0, "Negative size in Vec::Vec(int)");
562    alloc(size);
563  }
564
565  template<class Num_T> inline
566  Vec<Num_T>::Vec(const Vec<Num_T> &v) : datasize(0), data(0), factory(v.factory)
567  {
568    alloc(v.datasize);
569    copy_vector(datasize, v.data, data);
570  }
571
572  template<class Num_T> inline
573  Vec<Num_T>::Vec(const Vec<Num_T> &v, const Factory &f) : datasize(0), data(0), factory(f)
574  {
575    alloc(v.datasize);
576    copy_vector(datasize, v.data, data);
577  }
578
579  template<class Num_T> inline
580  Vec<Num_T>::Vec(const char *values, const Factory &f) : datasize(0), data(0), factory(f)
581  {
582    set(values);
583  }
584
585  template<class Num_T> inline
586  Vec<Num_T>::Vec(const std::string &values, const Factory &f) : datasize(0), data(0), factory(f)
587  {
588    set(values);
589  }
590
591  template<class Num_T> inline
592  Vec<Num_T>::Vec(const Num_T *c_array, int size, const Factory &f) : datasize(0), data(0), factory(f)
593  {
594    alloc(size);
595    copy_vector(size, c_array, data);
596  }
597
598  template<class Num_T> inline
599  Vec<Num_T>::~Vec()
600  {
601    free();
602  }
603
604  template<class Num_T>
605  void Vec<Num_T>::set_size(int size, bool copy)
606  {
607    it_assert_debug(size >= 0, "Vec::set_size(): New size must not be negative");
608    if (datasize == size)
609      return;
610    if (copy) {
611      // create a temporary pointer to the allocated data
612      Num_T* tmp = data;
613      // store the current number of elements
614      int old_datasize = datasize;
615      // check how many elements we need to copy
616      int min = datasize < size ? datasize : size;
617      // allocate new memory
618      alloc(size);
619      // copy old elements into a new memory region
620      copy_vector(min, tmp, data);
621      // initialize the rest of resized vector
622      for (int i = min; i < size; ++i)
623        data[i] = Num_T(0);
624      // delete old elements
625      destroy_elements(tmp, old_datasize);
626    }
627    else {
628      free();
629      alloc(size);
630    }
631  }
632
633  template<class Num_T> inline
634  const Num_T& Vec<Num_T>::operator[](int i) const
635  {
636    it_assert_debug((i >= 0) && (i < datasize), "Vec::operator[]: Index out of range");
637    return data[i];
638  }
639
640  template<class Num_T> inline
641  const Num_T& Vec<Num_T>::operator()(int i) const
642  {
643    it_assert_debug((i >= 0) && (i < datasize), "Vec::operator(): Index out of range");
644    return data[i];
645  }
646
647  template<class Num_T> inline
648  Num_T& Vec<Num_T>::operator[](int i)
649  {
650    it_assert_debug((i >= 0) && (i < datasize), "Vec::operator[]: Index out of range");
651    return data[i];
652  }
653
654  template<class Num_T> inline
655  Num_T& Vec<Num_T>::operator()(int i)
656  {
657    it_assert_debug((i >= 0) && (i < datasize), "Vec::operator(): Index out of range");
658    return data[i];
659  }
660
661  template<class Num_T> inline
662  const Vec<Num_T> Vec<Num_T>::operator()(int i1, int i2) const
663  {
664    int ii1=i1, ii2=i2;
665
666    if (ii1 == -1) ii1 = datasize-1;
667    if (ii2 == -1) ii2 = datasize-1;
668
669    it_assert_debug(ii1>=0 && ii2>=0 && ii1<datasize && ii2<datasize, "Vec::operator()(i1,i2): indicies out of range");
670    it_assert_debug(ii2>=ii1, "Vec::op(i1,i2): i2 >= i1 necessary");
671
672    Vec<Num_T> s(ii2-ii1+1);
673    copy_vector(s.datasize, data+ii1, s.data);
674
675    return s;
676  }
677
678  template<class Num_T>
679  const Vec<Num_T> Vec<Num_T>::operator()(const Vec<int> &indexlist) const
680  {
681    Vec<Num_T> temp(indexlist.length());
682    for (int i=0;i<indexlist.length();i++) {
683      it_assert((indexlist(i)>=0) && (indexlist(i) < datasize), "Vec::operator()(ivec &): index outside range");
684      temp(i)=data[indexlist(i)];
685    }
686    return temp;
687  }
688
689
690  template<class Num_T> inline
691  const Num_T& Vec<Num_T>::get(int i) const
692  {
693    it_assert_debug((i >= 0) && (i < datasize), "method get()");
694    return data[i];
695  }
696
697  template<class Num_T> inline
698  const Vec<Num_T> Vec<Num_T>::get(int i1, int i2) const
699  {
700    return (*this)(i1, i2);
701  }
702
703
704  template<class Num_T> inline
705  void Vec<Num_T>::zeros()
706  {
707    for (int i = 0; i < datasize; i++)
708      data[i] = Num_T(0);
709  }
710
711  template<class Num_T> inline
712  void Vec<Num_T>::ones()
713  {
714    for (int i = 0; i < datasize; i++)
715      data[i] = Num_T(1);
716  }
717
718  template<class Num_T> inline
719  void Vec<Num_T>::set(int i, const Num_T &v)
720  {
721    it_assert_debug((i >= 0) && (i < datasize), "method set()");
722    data[i] = v;
723  }
724
725  //! \cond
726  template<>
727  void Vec<double>::set(const std::string &str);
728  template<>
729  void Vec<std::complex<double> >::set(const std::string &str);
730  template<>
731  void Vec<int>::set(const std::string &str);
732  template<>
733  void Vec<short int>::set(const std::string &str);
734  template<>
735  void Vec<bin>::set(const std::string &str);
736  //! \endcond
737
738  template<class Num_T>
739  void Vec<Num_T>::set(const std::string &str)
740  {
741    it_error("Vec::set(): Only `double', `complex<double>', `int', "
742             "`short int' and `bin' types supported");
743  }
744
745  template<class Num_T>
746  void Vec<Num_T>::set(const char *str)
747  {
748    set(std::string(str));
749  }
750
751
752  template<class Num_T>
753  Mat<Num_T> Vec<Num_T>::transpose() const
754  {
755    Mat<Num_T> temp(1, datasize);
756    copy_vector(datasize, data, temp._data());
757    return temp;
758  }
759
760  template<>
761  Mat<std::complex<double> > Vec<std::complex<double> >::hermitian_transpose() const;
762
763  template<class Num_T>
764  Mat<Num_T> Vec<Num_T>::hermitian_transpose() const
765  {
766    Mat<Num_T> temp(1, datasize);
767    copy_vector(datasize, data, temp._data());
768    return temp;
769  }
770
771  template<class Num_T> inline
772  Vec<Num_T>& Vec<Num_T>::operator+=(const Vec<Num_T> &v)
773  {
774    if (datasize == 0) { // if not assigned a size.
775      if (this != &v) { // check for self addition
776        alloc(v.datasize);
777        copy_vector(datasize, v.data, data);
778      }
779    } else {
780      it_assert_debug(datasize == v.datasize, "Vec::operator+=: Wrong sizes");
781      for (int i = 0; i < datasize; i++)
782        data[i] += v.data[i];
783    }
784    return *this;
785  }
786
787  template<class Num_T> inline
788  Vec<Num_T>& Vec<Num_T>::operator+=(const Num_T t)
789  {
790    for (int i=0;i<datasize;i++)
791      data[i]+=t;
792    return *this;
793  }
794
795  template<class Num_T> inline
796  const Vec<Num_T> operator+(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
797  {
798    int i;
799    Vec<Num_T> r(v1.datasize);
800
801    it_assert_debug(v1.datasize==v2.datasize, "Vec::operator+: wrong sizes");
802    for (i=0; i<v1.datasize; i++)
803      r.data[i] = v1.data[i] + v2.data[i];
804
805    return r;
806  }
807
808  template<class Num_T> inline
809  const Vec<Num_T> operator+(const Vec<Num_T> &v, const Num_T t)
810  {
811    int i;
812    Vec<Num_T> r(v.datasize);
813
814    for (i=0; i<v.datasize; i++)
815      r.data[i] = v.data[i] + t;
816
817    return r;
818  }
819
820  template<class Num_T> inline
821  const Vec<Num_T> operator+(const Num_T t, const Vec<Num_T> &v)
822  {
823    int i;
824    Vec<Num_T> r(v.datasize);
825
826    for (i=0; i<v.datasize; i++)
827      r.data[i] = t + v.data[i];
828
829    return r;
830  }
831
832  template<class Num_T> inline
833  Vec<Num_T>& Vec<Num_T>::operator-=(const Vec<Num_T> &v)
834  {
835    if (datasize == 0) { // if not assigned a size.
836      if (this != &v) { // check for self decrementation
837        alloc(v.datasize);
838        for (int i = 0; i < v.datasize; i++)
839          data[i] = -v.data[i];
840      }
841    } else {
842      it_assert_debug(datasize == v.datasize, "Vec::operator-=: Wrong sizes");
843      for (int i = 0; i < datasize; i++)
844        data[i] -= v.data[i];
845    }
846    return *this;
847  }
848
849  template<class Num_T> inline
850  Vec<Num_T>& Vec<Num_T>::operator-=(const Num_T t)
851  {
852    for (int i=0;i<datasize;i++)
853      data[i]-=t;
854    return *this;
855  }
856
857  template<class Num_T> inline
858  const Vec<Num_T> operator-(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
859  {
860    int i;
861    Vec<Num_T> r(v1.datasize);
862
863    it_assert_debug(v1.datasize==v2.datasize, "Vec::operator-: wrong sizes");
864    for (i=0; i<v1.datasize; i++)
865      r.data[i] = v1.data[i] - v2.data[i];
866
867    return r;
868  }
869
870  template<class Num_T> inline
871  const Vec<Num_T> operator-(const Vec<Num_T> &v, const Num_T t)
872  {
873    int i;
874    Vec<Num_T> r(v.datasize);
875
876    for (i=0; i<v.datasize; i++)
877      r.data[i] = v.data[i] - t;
878
879    return r;
880  }
881
882  template<class Num_T> inline
883  const Vec<Num_T> operator-(const Num_T t, const Vec<Num_T> &v)
884  {
885    int i;
886    Vec<Num_T> r(v.datasize);
887
888    for (i=0; i<v.datasize; i++)
889      r.data[i] = t - v.data[i];
890
891    return r;
892  }
893
894  template<class Num_T> inline
895  const Vec<Num_T> operator-(const Vec<Num_T> &v)
896  {
897    int i;
898    Vec<Num_T> r(v.datasize);
899
900    for (i=0; i<v.datasize; i++)
901      r.data[i] = -v.data[i];
902
903    return r;
904  }
905
906  template<class Num_T> inline
907  Vec<Num_T>& Vec<Num_T>::operator*=(const Num_T t)
908  {
909    scal_vector(datasize, t, data);
910    return *this;
911  }
912
913#if defined(HAVE_BLAS)
914  template<> inline
915  double dot(const vec &v1, const vec &v2)
916  {
917    it_assert_debug(v1.datasize == v2.datasize, "vec::dot: wrong sizes");
918    int incr = 1;
919    return blas::ddot_(&v1.datasize, v1.data, &incr, v2.data, &incr);
920  }
921
922  template<> inline
923  std::complex<double> dot(const cvec &v1, const cvec &v2)
924  {
925    it_assert_debug(v1.datasize == v2.datasize, "cvec::dot: wrong sizes");
926    int incr = 1;
927    std::complex<double> output;
928#if defined(HAVE_ZDOTU_RETURN)
929    output = blas::zdotu_(&v1.datasize, v1.data, &incr, v2.data, &incr);
930#elif defined(HAVE_ZDOTU_VOID)
931    blas::zdotu_(&output, &v1.datasize, v1.data, &incr, v2.data, &incr);
932#else
933    blas::zdotusub_(&output, &v1.datasize, v1.data, &incr, v2.data, &incr);
934#endif // HAVE_ZDOTU_RETURN
935    return output;
936  }
937#endif // HAVE_BLAS
938
939  template<class Num_T> inline
940  Num_T dot(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
941  {
942    int i;
943    Num_T r=Num_T(0);
944
945    it_assert_debug(v1.datasize==v2.datasize, "Vec::dot: wrong sizes");
946    for (i=0; i<v1.datasize; i++)
947      r += v1.data[i] * v2.data[i];
948
949    return r;
950  }
951
952  template<class Num_T> inline
953  Num_T operator*(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
954  {
955    return dot(v1, v2);
956  }
957
958
959#if defined(HAVE_BLAS)
960  template<> inline
961  const mat outer_product(const vec &v1, const vec &v2, bool hermitian)
962  {
963    it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
964                    "Vec::outer_product():: Input vector of zero size");
965
966    mat out(v1.datasize, v2.datasize);
967    out.zeros();
968    double alpha = 1.0;
969    int incr = 1;
970    blas::dger_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
971                v2.data, &incr, out._data(), &v1.datasize);
972    return out;
973  }
974
975  template<> inline
976  const cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
977  {
978    it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
979                    "Vec::outer_product():: Input vector of zero size");
980
981    cmat out(v1.datasize, v2.datasize);
982    out.zeros();
983    std::complex<double> alpha(1.0);
984    int incr = 1;
985    if (hermitian) {
986      blas::zgerc_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
987                   v2.data, &incr, out._data(), &v1.datasize);
988    }
989    else {
990      blas::zgeru_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
991                   v2.data, &incr, out._data(), &v1.datasize);
992    }
993    return out;
994  }
995#else
996  //! Outer product of two vectors v1 and v2
997  template<> inline
998  const cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
999  {
1000    it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
1001                    "Vec::outer_product():: Input vector of zero size");
1002
1003    cmat out(v1.datasize, v2.datasize);
1004    if (hermitian) {
1005      for (int i = 0; i < v1.datasize; ++i) {
1006        for (int j = 0; j < v2.datasize; ++j) {
1007          out(i, j) = v1.data[i] * conj(v2.data[j]);
1008        }
1009      }
1010    }
1011    else {
1012      for (int i = 0; i < v1.datasize; ++i) {
1013        for (int j = 0; j < v2.datasize; ++j) {
1014          out(i, j) = v1.data[i] * v2.data[j];
1015        }
1016      }
1017    }
1018    return out;
1019  }
1020#endif // HAVE_BLAS
1021
1022  template<class Num_T> inline
1023  const Mat<Num_T> outer_product(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
1024                                 bool hermitian)
1025  {
1026    int i, j;
1027
1028    it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
1029                    "Vec::outer_product:: Input vector of zero size");
1030
1031    Mat<Num_T> r(v1.datasize, v2.datasize);
1032    for (i=0; i<v1.datasize; i++) {
1033      for (j=0; j<v2.datasize; j++) {
1034        r(i,j) = v1.data[i] * v2.data[j];
1035      }
1036    }
1037
1038    return r;
1039  }
1040
1041  template<class Num_T> inline
1042  const Vec<Num_T> operator*(const Vec<Num_T> &v, const Num_T t)
1043  {
1044    int i;
1045    Vec<Num_T> r(v.datasize);
1046    for (i=0; i<v.datasize; i++)
1047      r.data[i] = v.data[i] * t;
1048
1049    return r;
1050  }
1051
1052  template<class Num_T> inline
1053  const Vec<Num_T> operator*(const Num_T t, const Vec<Num_T> &v)
1054  {
1055    return operator*(v, t);
1056  }
1057
1058  template<class Num_T> inline
1059  const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b)
1060  {
1061    Vec<Num_T> out;
1062    elem_mult_out(a,b,out);
1063    return out;
1064  }
1065
1066  template<class Num_T> inline
1067  const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c)
1068  {
1069    Vec<Num_T> out;
1070    elem_mult_out(a,b,c,out);
1071    return out;
1072  }
1073
1074  template<class Num_T> inline
1075  const Vec<Num_T> elem_mult(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d)
1076  {
1077    Vec<Num_T> out;
1078    elem_mult_out(a,b,c,d,out);
1079    return out;
1080  }
1081
1082  template<class Num_T> inline
1083  void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
1084  {
1085    it_assert_debug(a.datasize==b.datasize, "Vec::elem_mult_out: wrong sizes");
1086
1087    if(out.datasize != a.datasize)
1088      out.set_size(a.size());
1089
1090    for(int i=0; i<a.datasize; i++)
1091      out.data[i] = a.data[i] * b.data[i];
1092  }
1093
1094  template<class Num_T> inline
1095  void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, Vec<Num_T> &out)
1096  {
1097    it_assert_debug(a.datasize==b.datasize==c.datasize, "Vec::elem_mult_out: wrong sizes");
1098
1099    if(out.datasize != a.datasize)
1100      out.set_size(a.size());
1101
1102    for(int i=0; i<a.datasize; i++)
1103      out.data[i] = a.data[i] * b.data[i] * c.data[i];
1104  }
1105
1106  template<class Num_T> inline
1107  void elem_mult_out(const Vec<Num_T> &a, const Vec<Num_T> &b, const Vec<Num_T> &c, const Vec<Num_T> &d, Vec<Num_T> &out)
1108  {
1109    it_assert_debug(a.datasize==b.datasize==c.datasize==d.datasize, "Vec::elem_mult_out: wrong sizes");
1110
1111    if(out.datasize != a.datasize)
1112      out.set_size(a.size());
1113
1114    for(int i=0; i<a.datasize; i++)
1115      out.data[i] = a.data[i] * b.data[i] * c.data[i] * d.data[i];
1116  }
1117
1118  template<class Num_T> inline
1119  void elem_mult_inplace(const Vec<Num_T> &a, Vec<Num_T> &b)
1120  {
1121    it_assert_debug(a.datasize==b.datasize, "Vec::elem_mult_inplace: wrong sizes");
1122
1123    for(int i=0; i<a.datasize; i++)
1124      b.data[i] *= a.data[i];
1125  }
1126
1127  template<class Num_T> inline
1128  Num_T elem_mult_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
1129  {
1130    it_assert_debug(a.datasize==b.datasize, "Vec::elem_mult_sum: wrong sizes");
1131
1132    Num_T acc = 0;
1133
1134    for(int i=0; i<a.datasize; i++)
1135      acc += a.data[i] * b.data[i];
1136
1137    return acc;
1138  }
1139
1140  template<class Num_T> inline
1141  const Vec<Num_T> operator/(const Vec<Num_T> &v, const Num_T t)
1142  {
1143    int i;
1144    Vec<Num_T> r(v.datasize);
1145
1146    for (i=0; i<v.datasize; i++)
1147      r.data[i] = v.data[i] / t;
1148
1149    return r;
1150  }
1151
1152  template<class Num_T> inline
1153  const Vec<Num_T> operator/(const Num_T t, const Vec<Num_T> &v)
1154  {
1155    int i;
1156    Vec<Num_T> r(v.datasize);
1157
1158    for (i=0; i<v.datasize; i++)
1159      r.data[i] = t / v.data[i];
1160
1161    return r;
1162  }
1163
1164  template<class Num_T> inline
1165  Vec<Num_T>& Vec<Num_T>::operator/=(const Num_T t)
1166  {
1167    for (int i = 0; i < datasize; ++i) {
1168      data[i] /= t;
1169    }
1170    return *this;
1171  }
1172
1173  template<class Num_T> inline
1174  Vec<Num_T>& Vec<Num_T>::operator/=(const Vec<Num_T> &v)
1175  {
1176    it_assert_debug(datasize == v.datasize, "Vec::operator/=(): wrong sizes");
1177    for (int i = 0; i < datasize; ++i) {
1178      data[i] /= v.data[i];
1179    }
1180    return *this;
1181  }
1182
1183  template<class Num_T> inline
1184  const Vec<Num_T> elem_div(const Vec<Num_T> &a, const Vec<Num_T> &b)
1185  {
1186    Vec<Num_T> out;
1187    elem_div_out(a,b,out);
1188    return out;
1189  }
1190
1191  template<class Num_T> inline
1192  const Vec<Num_T> elem_div(const Num_T t, const Vec<Num_T> &v)
1193  {
1194    int i;
1195    Vec<Num_T> r(v.datasize);
1196
1197    for (i=0; i<v.datasize; i++)
1198      r.data[i] = t / v.data[i];
1199
1200    return r;
1201  }
1202
1203  template<class Num_T> inline
1204  void elem_div_out(const Vec<Num_T> &a, const Vec<Num_T> &b, Vec<Num_T> &out)
1205  {
1206    it_assert_debug(a.datasize==b.datasize, "Vecelem_div_out: wrong sizes");
1207
1208    if(out.datasize != a.datasize)
1209      out.set_size(a.size());
1210
1211    for(int i=0; i<a.datasize; i++)
1212      out.data[i] = a.data[i] / b.data[i];
1213  }
1214
1215  template<class Num_T> inline
1216  Num_T elem_div_sum(const Vec<Num_T> &a, const Vec<Num_T> &b)
1217  {
1218    it_assert_debug(a.datasize==b.datasize, "Vec::elem_div_sum: wrong sizes");
1219
1220    Num_T acc = 0;
1221
1222    for(int i=0; i<a.datasize; i++)
1223      acc += a.data[i] / b.data[i];
1224
1225    return acc;
1226  }
1227
1228  template<class Num_T>
1229  Vec<Num_T> Vec<Num_T>::get(const Vec<bin> &binlist) const
1230  {
1231    int size = binlist.size();
1232    it_assert_debug(datasize == size, "Vec::get(bvec &): wrong sizes");
1233    Vec<Num_T> temp(size);
1234    int j = 0;
1235    for (int i = 0; i < size; ++i) {
1236      if (binlist(i) == bin(1)) {
1237        temp(j) = data[i];
1238        j++;
1239      }
1240    }
1241    temp.set_size(j, true);
1242    return temp;
1243  }
1244
1245  template<class Num_T> inline
1246  Vec<Num_T> Vec<Num_T>::right(int nr) const
1247  {
1248    it_assert_debug(nr <= datasize, "Vec::right(): index out of range");
1249    Vec<Num_T> temp(nr);
1250    if (nr > 0) {
1251      copy_vector(nr, &data[datasize-nr], temp.data);
1252    }
1253    return temp;
1254  }
1255
1256  template<class Num_T> inline
1257  Vec<Num_T> Vec<Num_T>::left(int nr) const
1258  {
1259    it_assert_debug(nr <= datasize, "Vec::left(): index out of range");
1260    Vec<Num_T> temp(nr);
1261    if (nr > 0) {
1262      copy_vector(nr, data, temp.data);
1263    }
1264    return temp;
1265  }
1266
1267  template<class Num_T> inline
1268  Vec<Num_T> Vec<Num_T>::mid(int start, int nr) const
1269  {
1270    it_assert_debug((start >= 0) && ((start+nr) <= datasize),
1271                    "Vec::mid(): indexing out of range");
1272    Vec<Num_T> temp(nr);
1273    if (nr > 0) {
1274      copy_vector(nr, &data[start], temp.data);
1275    }
1276    return temp;
1277  }
1278
1279  template<class Num_T>
1280  Vec<Num_T> Vec<Num_T>::split(int pos)
1281  {
1282    it_assert_debug((pos >= 0) && (pos <= datasize), "Vec::split(): index out of range");
1283    Vec<Num_T> temp1(pos);
1284    Vec<Num_T> temp2(datasize-pos);
1285    copy_vector(pos, data, temp1.data);
1286    copy_vector(datasize-pos, &data[pos], temp2.data);
1287    (*this) = temp2;
1288    return temp1;
1289  }
1290
1291  template<class Num_T>
1292  void Vec<Num_T>::shift_right(const Num_T In, int n)
1293  {
1294    int i=datasize;
1295
1296    it_assert_debug(n>=0, "Vec::shift_right: index out of range");
1297    while (--i >= n)
1298      data[i] = data[i-n];
1299    while (i >= 0)
1300      data[i--] = In;
1301  }
1302
1303  template<class Num_T>
1304  void Vec<Num_T>::shift_right(const Vec<Num_T> &In)
1305  {
1306    int i;
1307
1308    for (i=datasize-1; i>=In.datasize; i--)
1309      data[i]=data[i-In.datasize];
1310    for (i=0; i<In.datasize; i++)
1311      data[i]=In[i];
1312  }
1313
1314  template<class Num_T>
1315  void Vec<Num_T>::shift_left(const Num_T In, int n)
1316  {
1317    int i;
1318
1319    it_assert_debug(n>=0, "Vec::shift_left: index out of range");
1320    for (i=0; i<datasize-n; i++)
1321      data[i] = data[i+n];
1322    while (i < datasize)
1323      data[i++] = In;
1324  }
1325
1326  template<class Num_T>
1327  void Vec<Num_T>::shift_left(const Vec<Num_T> &In)
1328  {
1329    int i;
1330
1331    for (i=0; i<datasize-In.datasize; i++)
1332      data[i]=data[i+In.datasize];
1333    for (i=datasize-In.datasize; i<datasize; i++)
1334      data[i]=In[i-datasize+In.datasize];
1335  }
1336
1337  template<class Num_T>
1338  const Vec<Num_T> concat(const Vec<Num_T> &v, const Num_T a)
1339  {
1340    int size = v.size();
1341    Vec<Num_T> temp(size+1);
1342    copy_vector(size, v.data, temp.data);
1343    temp(size) = a;
1344    return temp;
1345  }
1346
1347  template<class Num_T>
1348  const Vec<Num_T> concat(const Num_T a, const Vec<Num_T> &v)
1349  {
1350    int size = v.size();
1351    Vec<Num_T> temp(size+1);
1352    temp(0) = a;
1353    copy_vector(size, v.data, &temp.data[1]);
1354    return temp;
1355  }
1356
1357  template<class Num_T>
1358  const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2)
1359  {
1360    int size1 = v1.size();
1361    int size2 = v2.size();
1362    Vec<Num_T> temp(size1+size2);
1363    copy_vector(size1, v1.data, temp.data);
1364    copy_vector(size2, v2.data, &temp.data[size1]);
1365    return temp;
1366  }
1367
1368  template<class Num_T>
1369  const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
1370                          const Vec<Num_T> &v3)
1371  {
1372    int size1 = v1.size();
1373    int size2 = v2.size();
1374    int size3 = v3.size();
1375    Vec<Num_T> temp(size1+size2+size3);
1376    copy_vector(size1, v1.data, temp.data);
1377    copy_vector(size2, v2.data, &temp.data[size1]);
1378    copy_vector(size3, v3.data, &temp.data[size1+size2]);
1379    return temp;
1380  }
1381
1382  template<class Num_T>
1383  const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
1384                          const Vec<Num_T> &v3, const Vec<Num_T> &v4)
1385  {
1386    int size1 = v1.size();
1387    int size2 = v2.size();
1388    int size3 = v3.size();
1389    int size4 = v4.size();
1390    Vec<Num_T> temp(size1+size2+size3+size4);
1391    copy_vector(size1, v1.data, temp.data);
1392    copy_vector(size2, v2.data, &temp.data[size1]);
1393    copy_vector(size3, v3.data, &temp.data[size1+size2]);
1394    copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
1395    return temp;
1396  }
1397
1398  template<class Num_T>
1399  const Vec<Num_T> concat(const Vec<Num_T> &v1, const Vec<Num_T> &v2,
1400                          const Vec<Num_T> &v3, const Vec<Num_T> &v4,
1401                          const Vec<Num_T> &v5)
1402  {
1403    int size1 = v1.size();
1404    int size2 = v2.size();
1405    int size3 = v3.size();
1406    int size4 = v4.size();
1407    int size5 = v5.size();
1408    Vec<Num_T> temp(size1+size2+size3+size4+size5);
1409    copy_vector(size1, v1.data, temp.data);
1410    copy_vector(size2, v2.data, &temp.data[size1]);
1411    copy_vector(size3, v3.data, &temp.data[size1+size2]);
1412    copy_vector(size4, v4.data, &temp.data[size1+size2+size3]);
1413    copy_vector(size5, v5.data, &temp.data[size1+size2+size3+size4]);
1414    return temp;
1415  }
1416
1417  template<class Num_T> inline
1418  void Vec<Num_T>::set_subvector(int i1, int i2, const Vec<Num_T> &v)
1419  {
1420    if (i1 == -1) i1 = datasize-1;
1421    if (i2 == -1) i2 = datasize-1;
1422
1423    it_assert_debug(i1>=0 && i2>=0 && i1<datasize && i2<datasize, "Vec::set_subvector(): indicies out of range");
1424    it_assert_debug(i2>=i1, "Vec::set_subvector(): i2 >= i1 necessary");
1425    it_assert_debug(i2-i1+1 == v.datasize, "Vec::set_subvector(): wrong sizes");
1426
1427    copy_vector(v.datasize, v.data, data+i1);
1428  }
1429
1430  template<class Num_T> inline
1431  void Vec<Num_T>:: set_subvector(int i, const Vec<Num_T> &v)
1432  {
1433    it_assert_debug(i>=0, "Vec::set_subvector(): index out of range");
1434    it_assert_debug(i+v.datasize <= datasize, "Vec::set_subvector(): too long input vector");
1435    copy_vector(v.datasize, v.data, data+i);
1436  }
1437
1438  template<class Num_T>
1439  void Vec<Num_T>::set_subvector(int i1, int i2, const Num_T t)
1440  {
1441    if (i1 == -1) i1 = datasize-1;
1442    if (i2 == -1) i2 = datasize-1;
1443
1444    it_assert_debug(i1>=0 && i2>=0 && i1<datasize && i2<datasize, "Vec::set_subvector(): indicies out of range");
1445    it_assert_debug(i2>=i1, "Vec::set_subvector(): i2 >= i1 necessary");
1446
1447    for (int i=i1;i<=i2;i++)
1448      data[i] = t;
1449  }
1450
1451  template<class Num_T>
1452  void Vec<Num_T>::replace_mid(int pos, const Vec<Num_T> &v)
1453  {
1454    it_assert_debug((pos>=0) && ((pos+v.length())<=datasize), "Vec::replace_mid: indexing out of range");
1455    copy_vector(v.datasize, v.data, &data[pos]);
1456  }
1457
1458  template<class Num_T>
1459  void Vec<Num_T>::del(int index)
1460  {
1461    it_assert_debug((index >= 0) && (index < datasize),
1462                    "Vec::del(): index out of range");
1463    Vec<Num_T> temp(*this);
1464    set_size(datasize-1, false);
1465    copy_vector(index, temp.data, data);
1466    copy_vector(datasize-index, &temp.data[index+1], &data[index]);
1467  }
1468
1469  template<class Num_T>
1470  void  Vec<Num_T>::del(int i1, int i2)
1471  {
1472    it_assert_debug((i1 >= 0) && (i2 < datasize) && (i1 < i2),
1473                    "Vec::del(): index out of range");
1474    Vec<Num_T> temp(*this);
1475    int new_size = datasize-(i2-i1+1);
1476    set_size(new_size, false);
1477    copy_vector(i1, temp.data, data);
1478    copy_vector(datasize-i1, &temp.data[i2+1], &data[i1]);
1479  }
1480
1481  template<class Num_T>
1482  void Vec<Num_T>::ins(int index, const Num_T in)
1483  {
1484    it_assert_debug((index>=0) && (index<=datasize), "Vec::ins: index out of range");
1485    Vec<Num_T> Temp(*this);
1486
1487    set_size(datasize+1, false);
1488    copy_vector(index, Temp.data, data);
1489    data[index]=in;
1490    copy_vector(Temp.datasize-index, Temp.data+index, data+index+1);
1491  }
1492
1493  template<class Num_T>
1494  void Vec<Num_T>::ins(int index, const Vec<Num_T> &in)
1495  {
1496    it_assert_debug((index>=0) && (index<=datasize), "Vec::ins: index out of range");
1497    Vec<Num_T> Temp(*this);
1498
1499    set_size(datasize+in.length(), false);
1500    copy_vector(index, Temp.data, data);
1501    copy_vector(in.size(), in.data, &data[index]);
1502    copy_vector(Temp.datasize-index, Temp.data+index, data+index+in.size());
1503  }
1504
1505  template<class Num_T> inline
1506  Vec<Num_T>& Vec<Num_T>::operator=(const Num_T t)
1507  {
1508    for (int i=0;i<datasize;i++)
1509      data[i] = t;
1510    return *this;
1511  }
1512
1513  template<class Num_T> inline
1514  Vec<Num_T>& Vec<Num_T>::operator=(const Vec<Num_T> &v)
1515  {
1516    if (this != &v) {
1517      set_size(v.datasize, false);
1518      copy_vector(datasize, v.data, data);
1519    }
1520    return *this;
1521  }
1522
1523  template<class Num_T> inline
1524  Vec<Num_T>& Vec<Num_T>::operator=(const Mat<Num_T> &m)
1525  {
1526    it_assert_debug( (m.cols() == 1 && datasize == m.rows()) ||
1527                (m.rows() == 1 && datasize == m.cols()), "Vec::operator=(Mat<Num_T>): wrong size");
1528
1529    if (m.cols() == 1) {
1530      set_size(m.rows(), false);
1531      copy_vector(m.rows(), m._data(), data);
1532    } else if (m.rows() == 1) {
1533      set_size(m.cols(), false);
1534      copy_vector(m.cols(), m._data(), m.rows(), data, 1);
1535    } else
1536      it_error("Vec::operator=(Mat<Num_T>): wrong size");
1537    return *this;
1538  }
1539
1540  template<class Num_T> inline
1541  Vec<Num_T>& Vec<Num_T>::operator=(const char *values)
1542  {
1543    set(values);
1544    return *this;
1545  }
1546
1547  template<>
1548  bvec Vec<std::complex<double> >::operator==(std::complex<double>) const;
1549
1550  template<class Num_T>
1551  bvec Vec<Num_T>::operator==(const Num_T value) const
1552  {
1553    it_assert(datasize > 0, "Vec::operator==: vector must have size > 0");
1554    Vec<Num_T> invector(*this);
1555    bvec temp(invector.length());
1556
1557    for (int i=0;i<invector.length();i++)
1558      temp(i)=(invector(i)==value);
1559
1560    return temp;
1561  }
1562
1563  template<>
1564  bvec Vec<std::complex<double> >::operator!=(std::complex<double>) const;
1565
1566  template<class Num_T>
1567  bvec Vec<Num_T>::operator!=(const Num_T value) const
1568  {
1569    it_assert(datasize > 0, "Vec::operator!=: vector must have size > 0");
1570    Vec<Num_T> invector(*this);
1571    bvec temp(invector.length());
1572
1573    for (int i=0;i<invector.length();i++)
1574      temp(i)=(invector(i)!=value);
1575
1576    return temp;
1577  }
1578
1579  template<>
1580  bvec Vec<std::complex<double> >::operator<(std::complex<double>) const;
1581
1582  template<class Num_T>
1583  bvec Vec<Num_T>::operator<(const Num_T value) const
1584  {
1585    it_assert(datasize > 0, "Vec::operator<: vector must have size > 0");
1586    Vec<Num_T> invector(*this);
1587    bvec temp(invector.length());
1588
1589    for (int i=0;i<invector.length();i++)
1590      temp(i)=(invector(i)<value);
1591
1592    return temp;
1593  }
1594
1595  template<>
1596  bvec Vec<std::complex<double> >::operator<=(std::complex<double>) const;
1597
1598  template<class Num_T>
1599  bvec Vec<Num_T>::operator<=(const Num_T value) const
1600  {
1601    it_assert(datasize > 0, "Vec::operator<=: vector must have size > 0");
1602    Vec<Num_T> invector(*this);
1603    bvec temp(invector.length());
1604
1605    for (int i=0;i<invector.length();i++)
1606      temp(i)=(invector(i)<=value);
1607
1608    return temp;
1609  }
1610
1611  template<>
1612  bvec Vec<std::complex<double> >::operator>(std::complex<double>) const;
1613
1614  template<class Num_T>
1615  bvec Vec<Num_T>::operator>(const Num_T value) const
1616  {
1617    it_assert(datasize > 0, "Vec::operator>: vector must have size > 0");
1618    Vec<Num_T> invector(*this);
1619    bvec temp(invector.length());
1620
1621    for (int i=0;i<invector.length();i++)
1622      temp(i)=(invector(i)>value);
1623
1624    return temp;
1625  }
1626
1627  template<>
1628  bvec Vec<std::complex<double> >::operator>=(std::complex<double>) const;
1629
1630  template<class Num_T>
1631  bvec Vec<Num_T>::operator>=(const Num_T value) const
1632  {
1633    it_assert(datasize > 0, "Vec::operator>=: vector must have size > 0");
1634    Vec<Num_T> invector(*this);
1635    bvec temp(invector.length());
1636
1637    for (int i=0;i<invector.length();i++)
1638      temp(i)=(invector(i)>=value);
1639
1640    return temp;
1641  }
1642
1643  template<class Num_T>
1644  bool Vec<Num_T>::operator==(const Vec<Num_T> &invector) const
1645  {
1646    // OBS ! if wrong size, return false
1647    if (datasize!=invector.datasize) return false;
1648    for (int i=0;i<datasize;i++) {
1649      if (data[i]!=invector.data[i]) return false;
1650    }
1651    return true;
1652  }
1653
1654  template<class Num_T>
1655  bool Vec<Num_T>::operator!=(const Vec<Num_T> &invector) const
1656  {
1657    if (datasize!=invector.datasize) return true;
1658    for (int i=0;i<datasize;i++) {
1659      if (data[i]!=invector.data[i]) return true;
1660    }
1661    return false;
1662  }
1663
1664  //! Output stream operator of a vector \c v
1665  template<class Num_T>
1666  std::ostream &operator<<(std::ostream &os, const Vec<Num_T> &v)
1667  {
1668    int i, sz=v.length();
1669
1670    os << "[" ;
1671    for (i=0; i<sz; i++) {
1672      os << v(i) ;
1673      if (i < sz-1)
1674        os << " ";
1675    }
1676    os << "]" ;
1677
1678    return os;
1679  }
1680
1681  //! Input stream operator to read a vector
1682  template<class Num_T>
1683  std::istream &operator>>(std::istream &is, Vec<Num_T> &v)
1684  {
1685    std::ostringstream buffer;
1686    bool started = false;
1687    bool finished = false;
1688    bool brackets = false;
1689    char c;
1690
1691    while (!finished) {
1692      if (is.eof()) {
1693        finished = true;
1694      } else {
1695        c = is.get();
1696
1697        if (is.eof() || (c == '\n')) {
1698          if (brackets) {
1699            // Right bracket missing
1700            is.setstate(std::ios_base::failbit);
1701            finished = true;
1702          } else if (!((c == '\n') && !started)) {
1703            finished = true;
1704          }
1705        } else if ((c == ' ') || (c == '\t')) {
1706          if (started) {
1707            buffer << ' ';
1708          }
1709        } else if (c == '[') {
1710          if (started) {
1711            // Unexpected left bracket
1712            is.setstate(std::ios_base::failbit);
1713            finished = true;
1714          } else {
1715            started = true;
1716            brackets = true;
1717          }
1718        } else if (c == ']') {
1719          if (!started || !brackets) {
1720            // Unexpected right bracket
1721            is.setstate(std::ios_base::failbit);
1722            finished = true;
1723          } else {
1724            finished = true;
1725          }
1726          while (!is.eof() && (((c = is.peek()) == ' ') || (c == '\t'))) {
1727            is.get();
1728          }
1729          if (!is.eof() && (c == '\n')) {
1730            is.get();
1731          }
1732        } else {
1733          started = true;
1734          buffer << c;
1735        }
1736      }
1737    }
1738
1739    if (!started) {
1740      v.set_size(0, false);
1741    } else {
1742      v.set(buffer.str());
1743    }
1744
1745    return is;
1746  }
1747
1748  //! \cond
1749
1750  // ----------------------------------------------------------------------
1751  // Instantiations
1752  // ----------------------------------------------------------------------
1753
1754#ifdef HAVE_EXTERN_TEMPLATE
1755
1756  extern template class Vec<double>;
1757  extern template class Vec<int>;
1758  extern template class Vec<short int>;
1759  extern template class Vec<std::complex<double> >;
1760  extern template class Vec<bin>;
1761
1762  // addition operator
1763
1764  extern template const vec operator+(const vec &v1, const vec &v2);
1765  extern template const cvec operator+(const cvec &v1, const cvec &v2);
1766  extern template const ivec operator+(const ivec &v1, const ivec &v2);
1767  extern template const svec operator+(const svec &v1, const svec &v2);
1768  extern template const bvec operator+(const bvec &v1, const bvec &v2);
1769
1770  extern template const vec operator+(const vec &v1, double t);
1771  extern template const cvec operator+(const cvec &v1, std::complex<double> t);
1772  extern template const ivec operator+(const ivec &v1, int t);
1773  extern template const svec operator+(const svec &v1, short t);
1774  extern template const bvec operator+(const bvec &v1, bin t);
1775
1776  extern template const vec operator+(double t, const vec &v1);
1777  extern template const cvec operator+(std::complex<double> t, const cvec &v1);
1778  extern template const ivec operator+(int t, const ivec &v1);
1779  extern template const svec operator+(short t, const svec &v1);
1780  extern template const bvec operator+(bin t, const bvec &v1);
1781
1782  // subraction operator
1783
1784  extern template const vec operator-(const vec &v1, const vec &v2);
1785  extern template const cvec operator-(const cvec &v1, const cvec &v2);
1786  extern template const ivec operator-(const ivec &v1, const ivec &v2);
1787  extern template const svec operator-(const svec &v1, const svec &v2);
1788  extern template const bvec operator-(const bvec &v1, const bvec &v2);
1789
1790  extern template const vec operator-(const vec &v, double t);
1791  extern template const cvec operator-(const cvec &v, std::complex<double> t);
1792  extern template const ivec operator-(const ivec &v, int t);
1793  extern template const svec operator-(const svec &v, short t);
1794  extern template const bvec operator-(const bvec &v, bin t);
1795
1796  extern template const vec operator-(double t, const vec &v);
1797  extern template const cvec operator-(std::complex<double> t, const cvec &v);
1798  extern template const ivec operator-(int t, const ivec &v);
1799  extern template const svec operator-(short t, const svec &v);
1800  extern template const bvec operator-(bin t, const bvec &v);
1801
1802  // unary minus
1803
1804  extern template const vec operator-(const vec &v);
1805  extern template const cvec operator-(const cvec &v);
1806  extern template const ivec operator-(const ivec &v);
1807  extern template const svec operator-(const svec &v);
1808  extern template const bvec operator-(const bvec &v);
1809
1810  // multiplication operator
1811
1812#if !defined(HAVE_BLAS)
1813  extern template double dot(const vec &v1, const vec &v2);
1814  extern template std::complex<double> dot(const cvec &v1, const cvec &v2);
1815#endif
1816  extern template int dot(const ivec &v1, const ivec &v2);
1817  extern template short dot(const svec &v1, const svec &v2);
1818  extern template bin dot(const bvec &v1, const bvec &v2);
1819
1820#if !defined(HAVE_BLAS)
1821  extern template double operator*(const vec &v1, const vec &v2);
1822  extern template std::complex<double> operator*(const cvec &v1,
1823                                                 const cvec &v2);
1824#endif
1825  extern template int operator*(const ivec &v1, const ivec &v2);
1826  extern template short operator*(const svec &v1, const svec &v2);
1827  extern template bin operator*(const bvec &v1, const bvec &v2);
1828
1829#if !defined(HAVE_BLAS)
1830  extern template const mat outer_product(const vec &v1, const vec &v2,
1831                                          bool hermitian);
1832#endif
1833  extern template const imat outer_product(const ivec &v1, const ivec &v2,
1834                                           bool hermitian);
1835  extern template const smat outer_product(const svec &v1, const svec &v2,
1836                                           bool hermitian);
1837  extern template const bmat outer_product(const bvec &v1, const bvec &v2,
1838                                           bool hermitian);
1839
1840  extern template const vec operator*(const vec &v, double t);
1841  extern template const cvec operator*(const cvec &v, std::complex<double> t);
1842  extern template const ivec operator*(const ivec &v, int t);
1843  extern template const svec operator*(const svec &v, short t);
1844  extern template const bvec operator*(const bvec &v, bin t);
1845
1846  extern template const vec operator*(double t, const vec &v);
1847  extern template const cvec operator*(std::complex<double> t, const cvec &v);
1848  extern template const ivec operator*(int t, const ivec &v);
1849  extern template const svec operator*(short t, const svec &v);
1850  extern template const bvec operator*(bin t, const bvec &v);
1851
1852  // elementwise multiplication
1853
1854  extern template const vec elem_mult(const vec &a, const vec &b);
1855  extern template const cvec elem_mult(const cvec &a, const cvec &b);
1856  extern template const ivec elem_mult(const ivec &a, const ivec &b);
1857  extern template const svec elem_mult(const svec &a, const svec &b);
1858  extern template const bvec elem_mult(const bvec &a, const bvec &b);
1859
1860  extern template void elem_mult_out(const vec &a, const vec &b, vec &out);
1861  extern template void elem_mult_out(const cvec &a, const cvec &b, cvec &out);
1862  extern template void elem_mult_out(const ivec &a, const ivec &b, ivec &out);
1863  extern template void elem_mult_out(const svec &a, const svec &b, svec &out);
1864  extern template void elem_mult_out(const bvec &a, const bvec &b, bvec &out);
1865
1866  extern template const vec elem_mult(const vec &a, const vec &b,
1867                                      const vec &c);
1868  extern template const cvec elem_mult(const cvec &a, const cvec &b,
1869                                       const cvec &c);
1870  extern template const ivec elem_mult(const ivec &a, const ivec &b,
1871                                       const ivec &c);
1872  extern template const svec elem_mult(const svec &a, const svec &b,
1873                                       const svec &c);
1874  extern template const bvec elem_mult(const bvec &a, const bvec &b,
1875                                       const bvec &c);
1876
1877  extern template void elem_mult_out(const vec &a, const vec &b, const vec &c,
1878                                     vec &out);
1879  extern template void elem_mult_out(const cvec &a, const cvec &b,
1880                                     const cvec &c, cvec &out);
1881  extern template void elem_mult_out(const ivec &a, const ivec &b,
1882                                     const ivec &c, ivec &out);
1883  extern template void elem_mult_out(const svec &a, const svec &b,
1884                                     const svec &c, svec &out);
1885  extern template void elem_mult_out(const bvec &a, const bvec &b,
1886                                     const bvec &c, bvec &out);
1887
1888  extern template const vec elem_mult(const vec &a, const vec &b, const vec &c,
1889                                      const vec &d);
1890  extern template const cvec elem_mult(const cvec &a, const cvec &b,
1891                                       const cvec &c, const cvec &d);
1892  extern template const ivec elem_mult(const ivec &a, const ivec &b,
1893                                       const ivec &c, const ivec &d);
1894  extern template const svec elem_mult(const svec &a, const svec &b,
1895                                       const svec &c, const svec &d);
1896  extern template const bvec elem_mult(const bvec &a, const bvec &b,
1897                                       const bvec &c, const bvec &d);
1898
1899  extern template void elem_mult_out(const vec &a, const vec &b, const vec &c,
1900                                     const vec &d, vec &out);
1901  extern template void elem_mult_out(const cvec &a, const cvec &b,
1902                                     const cvec &c, const cvec &d, cvec &out);
1903  extern template void elem_mult_out(const ivec &a, const ivec &b,
1904                                     const ivec &c, const ivec &d, ivec &out);
1905  extern template void elem_mult_out(const svec &a, const svec &b,
1906                                     const svec &c, const svec &d, svec &out);
1907  extern template void elem_mult_out(const bvec &a, const bvec &b,
1908                                     const bvec &c, const bvec &d, bvec &out);
1909
1910  // in-place elementwise multiplication
1911
1912  extern template void elem_mult_inplace(const vec &a, vec &b);
1913  extern template void elem_mult_inplace(const cvec &a, cvec &b);
1914  extern template void elem_mult_inplace(const ivec &a, ivec &b);
1915  extern template void elem_mult_inplace(const svec &a, svec &b);
1916  extern template void elem_mult_inplace(const bvec &a, bvec &b);
1917
1918  // elementwise multiplication followed by summation
1919
1920  extern template double elem_mult_sum(const vec &a, const vec &b);
1921  extern template std::complex<double> elem_mult_sum(const cvec &a,
1922                                                     const cvec &b);
1923  extern template int elem_mult_sum(const ivec &a, const ivec &b);
1924  extern template short elem_mult_sum(const svec &a, const svec &b);
1925  extern template bin elem_mult_sum(const bvec &a, const bvec &b);
1926
1927  // division operator
1928
1929  extern template const vec operator/(const vec &v, double t);
1930  extern template const cvec operator/(const cvec &v, std::complex<double> t);
1931  extern template const ivec operator/(const ivec &v, int t);
1932  extern template const svec operator/(const svec &v, short t);
1933  extern template const bvec operator/(const bvec &v, bin t);
1934
1935  extern template const vec operator/(double t, const vec &v);
1936  extern template const cvec operator/(std::complex<double> t, const cvec &v);
1937  extern template const ivec operator/(int t, const ivec &v);
1938  extern template const svec operator/(short t, const svec &v);
1939  extern template const bvec operator/(bin t, const bvec &v);
1940
1941  // elementwise division operator
1942
1943  extern template const vec elem_div(const vec &a, const vec &b);
1944  extern template const cvec elem_div(const cvec &a, const cvec &b);
1945  extern template const ivec elem_div(const ivec &a, const ivec &b);
1946  extern template const svec elem_div(const svec &a, const svec &b);
1947  extern template const bvec elem_div(const bvec &a, const bvec &b);
1948
1949  extern template const vec elem_div(double t, const vec &v);
1950  extern template const cvec elem_div(std::complex<double> t, const cvec &v);
1951  extern template const ivec elem_div(int t, const ivec &v);
1952  extern template const svec elem_div(short t, const svec &v);
1953  extern template const bvec elem_div(bin t, const bvec &v);
1954
1955  extern template void elem_div_out(const vec &a, const vec &b, vec &out);
1956  extern template void elem_div_out(const cvec &a, const cvec &b, cvec &out);
1957  extern template void elem_div_out(const ivec &a, const ivec &b, ivec &out);
1958  extern template void elem_div_out(const svec &a, const svec &b, svec &out);
1959  extern template void elem_div_out(const bvec &a, const bvec &b, bvec &out);
1960
1961  // elementwise division followed by summation
1962
1963  extern template double elem_div_sum(const vec &a, const vec &b);
1964  extern template std::complex<double> elem_div_sum(const cvec &a,
1965                                                    const cvec &b);
1966  extern template int elem_div_sum(const ivec &a, const ivec &b);
1967  extern template short elem_div_sum(const svec &a, const svec &b);
1968  extern template bin elem_div_sum(const bvec &a, const bvec &b);
1969
1970  // concat operator
1971
1972  extern template const vec concat(const vec &v, double a);
1973  extern template const cvec concat(const cvec &v, std::complex<double> a);
1974  extern template const ivec concat(const ivec &v, int a);
1975  extern template const svec concat(const svec &v, short a);
1976  extern template const bvec concat(const bvec &v, bin a);
1977
1978  extern template const vec concat(double a, const vec &v);
1979  extern template const cvec concat(std::complex<double> a, const cvec &v);
1980  extern template const ivec concat(int a, const ivec &v);
1981  extern template const svec concat(short a, const svec &v);
1982  extern template const bvec concat(bin a, const bvec &v);
1983
1984  extern template const vec concat(const vec &v1, const vec &v2);
1985  extern template const cvec concat(const cvec &v1, const cvec &v2);
1986  extern template const ivec concat(const ivec &v1, const ivec &v2);
1987  extern template const svec concat(const svec &v1, const svec &v2);
1988  extern template const bvec concat(const bvec &v1, const bvec &v2);
1989
1990  extern template const vec concat(const vec &v1, const vec &v2,
1991                                   const vec &v3);
1992  extern template const cvec concat(const cvec &v1, const cvec &v2,
1993                                    const cvec &v3);
1994  extern template const ivec concat(const ivec &v1, const ivec &v2,
1995                                    const ivec &v3);
1996  extern template const svec concat(const svec &v1, const svec &v2,
1997                                    const svec &v3);
1998  extern template const bvec concat(const bvec &v1, const bvec &v2,
1999                                    const bvec &v3);
2000
2001  extern template const vec concat(const vec &v1, const vec &v2, const vec &v3,
2002                                   const vec &v4);
2003  extern template const cvec concat(const cvec &v1, const cvec &v2,
2004                                    const cvec &v3, const cvec &v4);
2005  extern template const ivec concat(const ivec &v1, const ivec &v2,
2006                                    const ivec &v3, const ivec &v4);
2007  extern template const svec concat(const svec &v1, const svec &v2,
2008                                    const svec &v3, const svec &v4);
2009  extern template const bvec concat(const bvec &v1, const bvec &v2,
2010                                    const bvec &v3, const bvec &v4);
2011
2012  extern template const vec concat(const vec &v1, const vec &v2, const vec &v3,
2013                                   const vec &v4, const vec &v5);
2014  extern template const cvec concat(const cvec &v1, const cvec &v2,
2015                                    const cvec &v3, const cvec &v4,
2016                                    const cvec &v5);
2017  extern template const ivec concat(const ivec &v1, const ivec &v2,
2018                                    const ivec &v3, const ivec &v4,
2019                                    const ivec &v5);
2020  extern template const svec concat(const svec &v1, const svec &v2,
2021                                    const svec &v3, const svec &v4,
2022                                    const svec &v5);
2023  extern template const bvec concat(const bvec &v1, const bvec &v2,
2024                                    const bvec &v3, const bvec &v4,
2025                                    const bvec &v5);
2026
2027  // I/O streams
2028
2029  extern template std::ostream &operator<<(std::ostream& os, const vec &vect);
2030  extern template std::ostream &operator<<(std::ostream& os, const cvec &vect);
2031  extern template std::ostream &operator<<(std::ostream& os, const svec &vect);
2032  extern template std::ostream &operator<<(std::ostream& os, const ivec &vect);
2033  extern template std::ostream &operator<<(std::ostream& os, const bvec &vect);
2034  extern template std::istream &operator>>(std::istream& is, vec &vect);
2035  extern template std::istream &operator>>(std::istream& is, cvec &vect);
2036  extern template std::istream &operator>>(std::istream& is, svec &vect);
2037  extern template std::istream &operator>>(std::istream& is, ivec &vect);
2038  extern template std::istream &operator>>(std::istream& is, bvec &vect);
2039
2040#endif // HAVE_EXTERN_TEMPLATE
2041
2042  //! \endcond
2043
2044} // namespace itpp
2045
2046#endif // #ifndef VEC_H
Note: See TracBrowser for help on using the browser.