IT++ Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vec.cpp
Go to the documentation of this file.
1 
29 #ifndef _MSC_VER
30 # include <itpp/config.h>
31 #else
32 # include <itpp/config_msvc.h>
33 #endif
34 
35 #if defined (HAVE_BLAS)
36 # include <itpp/base/blas.h>
37 #endif
38 
39 #include <itpp/base/vec.h>
40 #include <itpp/base/converters.h>
41 #include <cstdio>
42 #include <limits>
43 
45 
46 namespace itpp
47 {
48 
49 
50 template<class Num_T>
51 std::vector<std::string> Vec<Num_T>::tokenize(const std::string &str_in,
52  bool &abc_format) const
53 {
54  std::vector<std::string> vs; // vector for storing parsed tokens
55  std::string s; // currently processed token string
56  bool start = true;
57  bool space = false;
58  bool colon = false;
59  bool comma = false;
60  bool lparen = false;
61  abc_format = false;
62  for (std::string::size_type i = 0; i < str_in.size(); ++i) {
63  char c = str_in[i];
64  switch (c) {
65  case ' ': case '\t':
66  space = true; // set flag for whitespaces
67  break;
68  case ',':
69  if (lparen)
70  comma = true; // set flag for comma in "(re,im)" format
71  else
72  space = true; // otherwise treat comma as separator
73  break;
74  case ')':
75  s.push_back('i'); // replace right paren in "(re,im)" with 'i'
76  break;
77  case ':':
78  colon = true; // set flag for "a:b[:c]" format string
79  space = false; // reset flag for whitespaces
80  abc_format = true; // set external flag for "a:b[:c]" format
81  s.push_back(c);
82  break;
83  case '(':
84  lparen = true; // set flag for complex "(re,im)" format
85  break;
86  default:
87  if (colon) { // reset colon and space flags
88  colon = false; // to get rid of whitespaces around ":"
89  space = false;
90  }
91  else if (lparen && comma) { // support for "(re,im)" format
92  lparen = false;
93  comma = false;
94  space = false;
95  if ((c != '-') && (c != '+')) // if needed
96  s.push_back('+'); // insert '+' between "re" and "im"
97  }
98  else if (space) { // new token detected
99  space = false;
100  if (!start) { // if not at the beginning of the string
101  vs.push_back(s); // store already parsed token
102  s.clear(); // and start parsing the next token
103  }
104  }
105  s.push_back(c); // append next character to the current token
106  start = false; // reset the "beginning of the string" flag
107  break;
108  }
109  }
110  if (!s.empty()) // if the final token is not an empty string
111  vs.push_back(s); // store it in the output vector
112  return vs;
113 }
114 
115 
116 template<>
117 int Vec<int>::parse_token(const std::string &s) const
118 {
119  int out;
120  std::istringstream buffer(s);
121  if (s.find('x', 1) != std::string::npos) {
122  buffer >> std::hex >> out;
123  }
124  else if (((s[0] == '0')
125  || (((s[0] == '-') || (s[0] == '+')) && (s[1] == '0')))
126  && (s.find('8', 1) == std::string::npos)
127  && (s.find('9', 1) == std::string::npos)) {
128  buffer >> std::oct >> out;
129  }
130  else {
131  buffer >> std::dec >> out;
132  }
133  return out;
134 }
135 
136 template<>
137 double Vec<double>::parse_token(const std::string &s) const
138 {
139  double out;
140  if ((s == "NaN") || (s == "nan") || (s == "NAN")) {
141  if (std::numeric_limits<double>::has_quiet_NaN)
142  out = std::numeric_limits<double>::quiet_NaN();
143  else if (std::numeric_limits<double>::has_signaling_NaN)
144  out = std::numeric_limits<double>::signaling_NaN();
145  else
146  it_error("Vec<double>::set(): NaN not supported");
147  }
148  else if ((s =="-Inf") || (s =="-inf") || (s =="-INF")) {
149  out = -std::numeric_limits<double>::infinity();
150  }
151  else if ((s =="Inf") || (s =="inf") || (s =="INF") ||
152  (s =="+Inf") || (s =="+inf") || (s =="+INF")) {
153  out = std::numeric_limits<double>::infinity();
154  }
155  else {
156  std::istringstream buffer(s);
157  buffer >> out;
158  it_assert(!buffer.fail(), "Vec<double>::set(): Stream operation failed "
159  "(buffer >> out)");
160  }
161  return out;
162 }
163 
164 
165 template<>
166 void Vec<bin>::set(const std::string &str)
167 {
168  bool abc_format;
169  std::vector<std::string> tokens = tokenize(str, abc_format);
170  it_assert(!abc_format, "Vec<bin>::set(): \"a:b:c\" format string not "
171  "supported for binary vectors");
172  set_size(tokens.size());
173  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
174  std::istringstream buffer(tokens[i]);
175  buffer >> data[i];
176  it_assert(!buffer.fail(), "Vec<bin>::set(): Stream operation failed "
177  "(buffer >> data)");
178  }
179 }
180 
181 template<>
182 void Vec<short int>::set(const std::string &str)
183 {
184  // parser for "short int" is the same as for "int", so reuse it here
185  ivec iv(str);
186  this->operator=(to_svec(iv));
187 }
188 
189 template<>
190 void Vec<int>::set(const std::string &str)
191 {
192  bool abc_format;
193  std::vector<std::string> tokens = tokenize(str, abc_format);
194  // no "a:b:c" tokens, so the size of output vector is known
195  if (!abc_format) {
196  set_size(tokens.size());
197  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i)
198  data[i] = parse_token(tokens[i]);
199  }
200  else {
201  int pos = 0;
202  set_size((tokens.size() > 20) ? tokens.size() : 20);
203  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
204  // check if the current token is in "a:b[:c]" format
205  if (tokens[i].find(':', 1) == std::string::npos) {
206  if (++pos > datasize) {
207  set_size(2 * datasize, true);
208  }
209  data[pos-1] = parse_token(tokens[i]);
210  }
211  else {
212  int a, b, c;
213  parse_abc_token(tokens[i], a, b, c);
214  if (++pos > datasize) {
215  set_size(2 * datasize, true);
216  }
217  data[pos-1] = a;
218 
219  if ((b > 0) && (c >= a)) {
220  while ((data[pos-1] + b) <= c) {
221  if (++pos > datasize) {
222  set_size(2 * datasize, true);
223  }
224  data[pos-1] = data[pos-2] + b;
225  }
226  }
227  else if ((b < 0) && (c <= a)) {
228  while ((data[pos-1] + b) >= c) {
229  if (++pos > datasize) {
230  set_size(2 * datasize, true);
231  }
232  data[pos-1] = data[pos-2] + b;
233  }
234  }
235  else if (b == 0 && c == a) {
236  break;
237  }
238  else {
239  it_error("Vec<int>::set(): Improper data string (a:b:c)");
240  }
241  }
242  }
243  set_size(pos, true);
244  } // if (!abc_format)
245 }
246 
247 
248 template<>
249 void Vec<double>::set(const std::string &str)
250 {
251  bool abc_format;
252  std::vector<std::string> tokens = tokenize(str, abc_format);
253  // no "a:b:c" tokens, so the size of output vector is known
254  if (!abc_format) {
255  set_size(tokens.size());
256  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i)
257  data[i] = parse_token(tokens[i]);
258  }
259  else {
260  int pos = 0;
261  set_size((tokens.size() > 20) ? tokens.size() : 20);
262  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
263  // check if the current token is in "a:b[:c]" format
264  if (tokens[i].find(':', 1) == std::string::npos) {
265  if (++pos > datasize) {
266  set_size(2 * datasize, true);
267  }
268  data[pos-1] = parse_token(tokens[i]);
269  }
270  else {
271  double a, b, c;
272  parse_abc_token(tokens[i], a, b, c);
273  if (++pos > datasize) {
274  set_size(2 * datasize, true);
275  }
276  data[pos-1] = a;
277  // Adding this margin fixes precision problems in e.g. "0:0.2:3",
278  // where the last value was 2.8 instead of 3.
279  double eps_margin = std::fabs((c - a) / b) * eps;
280  if ((b > 0) && (c >= a)) {
281  while ((data[pos-1] + b) <= (c + eps_margin)) {
282  if (++pos > datasize) {
283  set_size(2 * datasize, true);
284  }
285  data[pos-1] = data[pos-2] + b;
286  }
287  }
288  else if ((b < 0) && (c <= a)) {
289  while ((data[pos-1] + b) >= (c - eps_margin)) {
290  if (++pos > datasize) {
291  set_size(2 * datasize, true);
292  }
293  data[pos-1] = data[pos-2] + b;
294  }
295  }
296  else if (b == 0 && c == a) {
297  break;
298  }
299  else {
300  it_error("Vec<double>::set(): Improper data string (a:b:c)");
301  }
302  }
303  }
304  set_size(pos, true);
305  } // if (!abc_format)
306 }
307 
308 template<>
309 void Vec<std::complex<double> >::set(const std::string &str)
310 {
311  bool abc_format;
312  std::vector<std::string> tokens = tokenize(str, abc_format);
313  it_assert(!abc_format, "Vec<bin>::set(): \"a:b:c\" format string not "
314  "supported for binary vectors");
315  set_size(tokens.size());
316  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
317  std::istringstream buffer(tokens[i]);
318  buffer >> data[i];
319  it_assert(!buffer.fail(), "Vec<complex>::set(): Stream operation failed "
320  "(buffer >> data)");
321  }
322 }
323 
324 
325 #if defined(HAVE_BLAS)
326 template<>
327 double dot(const vec &v1, const vec &v2)
328 {
329  it_assert_debug(v1.datasize == v2.datasize, "vec::dot(): Wrong sizes");
330  int incr = 1;
331  return blas::ddot_(&v1.datasize, v1.data, &incr, v2.data, &incr);
332 }
333 #else
334 template<>
335 double dot(const vec &v1, const vec &v2)
336 {
337  it_assert_debug(v1.datasize == v2.datasize, "Vec::dot(): Wrong sizes");
338  double r = 0.0;
339  for (int i = 0; i < v1.datasize; ++i)
340  r += v1.data[i] * v2.data[i];
341  return r;
342 }
343 #endif // HAVE_BLAS
344 
345 #if defined(HAVE_BLAS)
346 template<>
347 mat outer_product(const vec &v1, const vec &v2, bool)
348 {
349  it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
350  "Vec::outer_product():: Input vector of zero size");
351 
352  mat out(v1.datasize, v2.datasize);
353  out.zeros();
354  double alpha = 1.0;
355  int incr = 1;
356  blas::dger_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
357  v2.data, &incr, out._data(), &v1.datasize);
358  return out;
359 }
360 
361 template<>
362 cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
363 {
364  it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
365  "Vec::outer_product():: Input vector of zero size");
366 
367  cmat out(v1.datasize, v2.datasize);
368  out.zeros();
369  std::complex<double> alpha(1.0);
370  int incr = 1;
371  if (hermitian) {
372  blas::zgerc_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
373  v2.data, &incr, out._data(), &v1.datasize);
374  }
375  else {
376  blas::zgeru_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
377  v2.data, &incr, out._data(), &v1.datasize);
378  }
379  return out;
380 }
381 #else
382 template<>
383 mat outer_product(const vec &v1, const vec &v2, bool)
384 {
385  it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
386  "Vec::outer_product():: Input vector of zero size");
387 
388  mat out(v1.datasize, v2.datasize);
389  for (int i = 0; i < v1.datasize; ++i) {
390  for (int j = 0; j < v2.datasize; ++j) {
391  out(i, j) = v1.data[i] * v2.data[j];
392  }
393  }
394  return out;
395 }
396 
397 template<>
398 cmat outer_product(const cvec &v1, const cvec &v2, bool hermitian)
399 {
400  it_assert_debug((v1.datasize > 0) && (v2.datasize > 0),
401  "Vec::outer_product():: Input vector of zero size");
402 
403  cmat out(v1.datasize, v2.datasize);
404  if (hermitian) {
405  for (int i = 0; i < v1.datasize; ++i) {
406  for (int j = 0; j < v2.datasize; ++j) {
407  out(i, j) = v1.data[i] * conj(v2.data[j]);
408  }
409  }
410  }
411  else {
412  for (int i = 0; i < v1.datasize; ++i) {
413  for (int j = 0; j < v2.datasize; ++j) {
414  out(i, j) = v1.data[i] * v2.data[j];
415  }
416  }
417  }
418  return out;
419 }
420 #endif // HAVE_BLAS
421 
422 
423 template<>
424 bvec Vec<std::complex<double> >::operator<=(std::complex<double>) const
425 {
426  it_error("operator<=: not implemented for complex");
427  bvec temp;
428  return temp;
429 }
430 
431 template<>
432 bvec Vec<std::complex<double> >::operator>(std::complex<double>) const
433 {
434  it_error("operator>: not implemented for complex");
435  bvec temp;
436  return temp;
437 }
438 
439 template<>
440 bvec Vec<std::complex<double> >::operator<(std::complex<double>) const
441 {
442  it_error("operator<: not implemented for complex");
443  bvec temp;
444  return temp;
445 }
446 
447 template<>
448 bvec Vec<std::complex<double> >::operator>=(std::complex<double>) const
449 {
450  it_error("operator>=: not implemented for complex");
451  bvec temp;
452  return temp;
453 }
454 
455 template<>
456 Mat<std::complex<double> > Vec<std::complex<double> >::hermitian_transpose() const
457 {
458  Mat<std::complex<double> > temp(1, datasize);
459  for (int i = 0; i < datasize; i++)
460  temp(i) = std::conj(data[i]);
461 
462  return temp;
463 }
464 
465 
466 //---------------------------------------------------------------------
467 // Instantiations
468 //---------------------------------------------------------------------
469 
470 template class Vec<double>;
471 template class Vec<int>;
472 template class Vec<short int>;
473 template class Vec<std::complex<double> >;
474 template class Vec<bin>;
475 
476 // addition operator
477 
478 template vec operator+(const vec &v1, const vec &v2);
479 template cvec operator+(const cvec &v1, const cvec &v2);
480 template ivec operator+(const ivec &v1, const ivec &v2);
481 template svec operator+(const svec &v1, const svec &v2);
482 template bvec operator+(const bvec &v1, const bvec &v2);
483 
484 template vec operator+(const vec &v1, double t);
485 template cvec operator+(const cvec &v1, std::complex<double> t);
486 template ivec operator+(const ivec &v1, int t);
487 template svec operator+(const svec &v1, short t);
488 template bvec operator+(const bvec &v1, bin t);
489 
490 template vec operator+(double t, const vec &v1);
491 template cvec operator+(std::complex<double> t, const cvec &v1);
492 template ivec operator+(int t, const ivec &v1);
493 template svec operator+(short t, const svec &v1);
494 template bvec operator+(bin t, const bvec &v1);
495 
496 // subraction operator
497 
498 template vec operator-(const vec &v1, const vec &v2);
499 template cvec operator-(const cvec &v1, const cvec &v2);
500 template ivec operator-(const ivec &v1, const ivec &v2);
501 template svec operator-(const svec &v1, const svec &v2);
502 template bvec operator-(const bvec &v1, const bvec &v2);
503 
504 template vec operator-(const vec &v, double t);
505 template cvec operator-(const cvec &v, std::complex<double> t);
506 template ivec operator-(const ivec &v, int t);
507 template svec operator-(const svec &v, short t);
508 template bvec operator-(const bvec &v, bin t);
509 
510 template vec operator-(double t, const vec &v);
511 template cvec operator-(std::complex<double> t, const cvec &v);
512 template ivec operator-(int t, const ivec &v);
513 template svec operator-(short t, const svec &v);
514 template bvec operator-(bin t, const bvec &v);
515 
516 // unary minus
517 
518 template vec operator-(const vec &v);
519 template cvec operator-(const cvec &v);
520 template ivec operator-(const ivec &v);
521 template svec operator-(const svec &v);
522 template bvec operator-(const bvec &v);
523 
524 // multiplication operator
525 
526 #if !defined(HAVE_BLAS)
527 template double dot(const vec &v1, const vec &v2);
528 #endif
529 template std::complex<double> dot(const cvec &v1, const cvec &v2);
530 template int dot(const ivec &v1, const ivec &v2);
531 template short dot(const svec &v1, const svec &v2);
532 template bin dot(const bvec &v1, const bvec &v2);
533 
534 template double operator*(const vec &v1, const vec &v2);
535 template std::complex<double> operator*(const cvec &v1, const cvec &v2);
536 template int operator*(const ivec &v1, const ivec &v2);
537 template short operator*(const svec &v1, const svec &v2);
538 template bin operator*(const bvec &v1, const bvec &v2);
539 
540 #if !defined(HAVE_BLAS)
541 template mat outer_product(const vec &v1, const vec &v2, bool hermitian);
542 #endif
543 template imat outer_product(const ivec &v1, const ivec &v2, bool hermitian);
544 template smat outer_product(const svec &v1, const svec &v2, bool hermitian);
545 template bmat outer_product(const bvec &v1, const bvec &v2, bool hermitian);
546 
547 template vec operator*(const vec &v, double t);
548 template cvec operator*(const cvec &v, std::complex<double> t);
549 template ivec operator*(const ivec &v, int t);
550 template svec operator*(const svec &v, short t);
551 template bvec operator*(const bvec &v, bin t);
552 
553 template vec operator*(double t, const vec &v);
554 template cvec operator*(std::complex<double> t, const cvec &v);
555 template ivec operator*(int t, const ivec &v);
556 template svec operator*(short t, const svec &v);
557 template bvec operator*(bin t, const bvec &v);
558 
559 // elementwise multiplication
560 
561 template vec elem_mult(const vec &a, const vec &b);
562 template cvec elem_mult(const cvec &a, const cvec &b);
563 template ivec elem_mult(const ivec &a, const ivec &b);
564 template svec elem_mult(const svec &a, const svec &b);
565 template bvec elem_mult(const bvec &a, const bvec &b);
566 
567 template void elem_mult_out(const vec &a, const vec &b, vec &out);
568 template void elem_mult_out(const cvec &a, const cvec &b, cvec &out);
569 template void elem_mult_out(const ivec &a, const ivec &b, ivec &out);
570 template void elem_mult_out(const svec &a, const svec &b, svec &out);
571 template void elem_mult_out(const bvec &a, const bvec &b, bvec &out);
572 
573 template vec elem_mult(const vec &a, const vec &b, const vec &c);
574 template cvec elem_mult(const cvec &a, const cvec &b, const cvec &c);
575 template ivec elem_mult(const ivec &a, const ivec &b, const ivec &c);
576 template svec elem_mult(const svec &a, const svec &b, const svec &c);
577 template bvec elem_mult(const bvec &a, const bvec &b, const bvec &c);
578 
579 template void elem_mult_out(const vec &a, const vec &b, const vec &c,
580  vec &out);
581 template void elem_mult_out(const cvec &a, const cvec &b, const cvec &c,
582  cvec &out);
583 template void elem_mult_out(const ivec &a, const ivec &b, const ivec &c,
584  ivec &out);
585 template void elem_mult_out(const svec &a, const svec &b, const svec &c,
586  svec &out);
587 template void elem_mult_out(const bvec &a, const bvec &b, const bvec &c,
588  bvec &out);
589 
590 template vec elem_mult(const vec &a, const vec &b, const vec &c,
591  const vec &d);
592 template cvec elem_mult(const cvec &a, const cvec &b, const cvec &c,
593  const cvec &d);
594 template ivec elem_mult(const ivec &a, const ivec &b, const ivec &c,
595  const ivec &d);
596 template svec elem_mult(const svec &a, const svec &b, const svec &c,
597  const svec &d);
598 template bvec elem_mult(const bvec &a, const bvec &b, const bvec &c,
599  const bvec &d);
600 
601 template void elem_mult_out(const vec &a, const vec &b, const vec &c,
602  const vec &d, vec &out);
603 template void elem_mult_out(const cvec &a, const cvec &b, const cvec &c,
604  const cvec &d, cvec &out);
605 template void elem_mult_out(const ivec &a, const ivec &b, const ivec &c,
606  const ivec &d, ivec &out);
607 template void elem_mult_out(const svec &a, const svec &b, const svec &c,
608  const svec &d, svec &out);
609 template void elem_mult_out(const bvec &a, const bvec &b, const bvec &c,
610  const bvec &d, bvec &out);
611 
612 // in-place elementwise multiplication
613 
614 template void elem_mult_inplace(const vec &a, vec &b);
615 template void elem_mult_inplace(const cvec &a, cvec &b);
616 template void elem_mult_inplace(const ivec &a, ivec &b);
617 template void elem_mult_inplace(const svec &a, svec &b);
618 template void elem_mult_inplace(const bvec &a, bvec &b);
619 
620 // elementwise multiplication followed by summation
621 
622 template double elem_mult_sum(const vec &a, const vec &b);
623 template std::complex<double> elem_mult_sum(const cvec &a, const cvec &b);
624 template int elem_mult_sum(const ivec &a, const ivec &b);
625 template short elem_mult_sum(const svec &a, const svec &b);
626 template bin elem_mult_sum(const bvec &a, const bvec &b);
627 
628 // division operator
629 
630 template vec operator/(const vec &v, double t);
631 template cvec operator/(const cvec &v, std::complex<double> t);
632 template ivec operator/(const ivec &v, int t);
633 template svec operator/(const svec &v, short t);
634 template bvec operator/(const bvec &v, bin t);
635 
636 template vec operator/(double t, const vec &v);
637 template cvec operator/(std::complex<double> t, const cvec &v);
638 template ivec operator/(int t, const ivec &v);
639 template svec operator/(short t, const svec &v);
640 template bvec operator/(bin t, const bvec &v);
641 
642 // elementwise division operator
643 
644 template vec elem_div(const vec &a, const vec &b);
645 template cvec elem_div(const cvec &a, const cvec &b);
646 template ivec elem_div(const ivec &a, const ivec &b);
647 template svec elem_div(const svec &a, const svec &b);
648 template bvec elem_div(const bvec &a, const bvec &b);
649 
650 template vec elem_div(double t, const vec &v);
651 template cvec elem_div(std::complex<double> t, const cvec &v);
652 template ivec elem_div(int t, const ivec &v);
653 template svec elem_div(short t, const svec &v);
654 template bvec elem_div(bin t, const bvec &v);
655 
656 template void elem_div_out(const vec &a, const vec &b, vec &out);
657 template void elem_div_out(const cvec &a, const cvec &b, cvec &out);
658 template void elem_div_out(const ivec &a, const ivec &b, ivec &out);
659 template void elem_div_out(const svec &a, const svec &b, svec &out);
660 template void elem_div_out(const bvec &a, const bvec &b, bvec &out);
661 
662 // elementwise division followed by summation
663 
664 template double elem_div_sum(const vec &a, const vec &b);
665 template std::complex<double> elem_div_sum(const cvec &a, const cvec &b);
666 template int elem_div_sum(const ivec &a, const ivec &b);
667 template short elem_div_sum(const svec &a, const svec &b);
668 template bin elem_div_sum(const bvec &a, const bvec &b);
669 
670 // concat operator
671 
672 template vec concat(const vec &v, double a);
673 template cvec concat(const cvec &v, std::complex<double> a);
674 template ivec concat(const ivec &v, int a);
675 template svec concat(const svec &v, short a);
676 template bvec concat(const bvec &v, bin a);
677 
678 template vec concat(double a, const vec &v);
679 template cvec concat(std::complex<double> a, const cvec &v);
680 template ivec concat(int a, const ivec &v);
681 template svec concat(short a, const svec &v);
682 template bvec concat(bin a, const bvec &v);
683 
684 template vec concat(const vec &v1, const vec &v2);
685 template cvec concat(const cvec &v1, const cvec &v2);
686 template ivec concat(const ivec &v1, const ivec &v2);
687 template svec concat(const svec &v1, const svec &v2);
688 template bvec concat(const bvec &v1, const bvec &v2);
689 
690 template vec concat(const vec &v1, const vec &v2, const vec &v3);
691 template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3);
692 template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3);
693 template svec concat(const svec &v1, const svec &v2, const svec &v3);
694 template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3);
695 
696 template vec concat(const vec &v1, const vec &v2,
697  const vec &v3, const vec &v4);
698 template cvec concat(const cvec &v1, const cvec &v2,
699  const cvec &v3, const cvec &v4);
700 template ivec concat(const ivec &v1, const ivec &v2,
701  const ivec &v3, const ivec &v4);
702 template svec concat(const svec &v1, const svec &v2,
703  const svec &v3, const svec &v4);
704 template bvec concat(const bvec &v1, const bvec &v2,
705  const bvec &v3, const bvec &v4);
706 
707 template vec concat(const vec &v1, const vec &v2, const vec &v3,
708  const vec &v4, const vec &v5);
709 template cvec concat(const cvec &v1, const cvec &v2, const cvec &v3,
710  const cvec &v4, const cvec &v5);
711 template ivec concat(const ivec &v1, const ivec &v2, const ivec &v3,
712  const ivec &v4, const ivec &v5);
713 template svec concat(const svec &v1, const svec &v2, const svec &v3,
714  const svec &v4, const svec &v5);
715 template bvec concat(const bvec &v1, const bvec &v2, const bvec &v3,
716  const bvec &v4, const bvec &v5);
717 
718 // I/O streams
719 
720 template std::ostream &operator<<(std::ostream& os, const vec &vect);
721 template std::ostream &operator<<(std::ostream& os, const cvec &vect);
722 template std::ostream &operator<<(std::ostream& os, const svec &vect);
723 template std::ostream &operator<<(std::ostream& os, const ivec &vect);
724 template std::ostream &operator<<(std::ostream& os, const bvec &vect);
725 template std::istream &operator>>(std::istream& is, vec &vect);
726 template std::istream &operator>>(std::istream& is, cvec &vect);
727 template std::istream &operator>>(std::istream& is, svec &vect);
728 template std::istream &operator>>(std::istream& is, ivec &vect);
729 template std::istream &operator>>(std::istream& is, bvec &vect);
730 
731 } // namespace itpp
732 
SourceForge Logo

Generated on Fri Mar 21 2014 17:14:13 for IT++ by Doxygen 1.8.1.2