30 # include <itpp/config.h>
32 # include <itpp/config_msvc.h>
35 #if defined (HAVE_BLAS)
36 # include <itpp/base/blas.h>
51 std::vector<std::string> Vec<Num_T>::tokenize(
const std::string &str_in,
52 bool &abc_format)
const
54 std::vector<std::string> vs;
62 for (std::string::size_type i = 0; i < str_in.size(); ++i) {
91 else if (lparen && comma) {
95 if ((c !=
'-') && (c !=
'+'))
117 int Vec<int>::parse_token(
const std::string &s)
const
120 std::istringstream buffer(s);
121 if (s.find(
'x', 1) != std::string::npos) {
122 buffer >> std::hex >> out;
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;
131 buffer >> std::dec >> out;
137 double Vec<double>::parse_token(
const std::string &s)
const
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();
146 it_error(
"Vec<double>::set(): NaN not supported");
148 else if ((s ==
"-Inf") || (s ==
"-inf") || (s ==
"-INF")) {
149 out = -std::numeric_limits<double>::infinity();
151 else if ((s ==
"Inf") || (s ==
"inf") || (s ==
"INF") ||
152 (s ==
"+Inf") || (s ==
"+inf") || (s ==
"+INF")) {
153 out = std::numeric_limits<double>::infinity();
156 std::istringstream buffer(s);
158 it_assert(!buffer.fail(),
"Vec<double>::set(): Stream operation failed "
166 void Vec<bin>::set(
const std::string &str)
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]);
176 it_assert(!buffer.fail(),
"Vec<bin>::set(): Stream operation failed "
182 void Vec<short int>::set(
const std::string &str)
190 void Vec<int>::set(
const std::string &str)
193 std::vector<std::string> tokens = tokenize(str, 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]);
202 set_size((tokens.size() > 20) ? tokens.size() : 20);
203 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
205 if (tokens[i].
find(
':', 1) == std::string::npos) {
206 if (++pos > datasize) {
207 set_size(2 * datasize,
true);
209 data[pos-1] = parse_token(tokens[i]);
213 parse_abc_token(tokens[i], a, b, c);
214 if (++pos > datasize) {
215 set_size(2 * datasize,
true);
219 if ((b > 0) && (c >= a)) {
220 while ((data[pos-1] + b) <= c) {
221 if (++pos > datasize) {
222 set_size(2 * datasize,
true);
224 data[pos-1] = data[pos-2] + b;
227 else if ((b < 0) && (c <= a)) {
228 while ((data[pos-1] + b) >= c) {
229 if (++pos > datasize) {
230 set_size(2 * datasize,
true);
232 data[pos-1] = data[pos-2] + b;
235 else if (b == 0 && c == a) {
239 it_error(
"Vec<int>::set(): Improper data string (a:b:c)");
249 void Vec<double>::set(
const std::string &str)
252 std::vector<std::string> tokens = tokenize(str, 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]);
261 set_size((tokens.size() > 20) ? tokens.size() : 20);
262 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); ++i) {
264 if (tokens[i].
find(
':', 1) == std::string::npos) {
265 if (++pos > datasize) {
266 set_size(2 * datasize,
true);
268 data[pos-1] = parse_token(tokens[i]);
272 parse_abc_token(tokens[i], a, b, c);
273 if (++pos > datasize) {
274 set_size(2 * datasize,
true);
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);
285 data[pos-1] = data[pos-2] + b;
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);
293 data[pos-1] = data[pos-2] + b;
296 else if (b == 0 && c == a) {
300 it_error(
"Vec<double>::set(): Improper data string (a:b:c)");
309 void Vec<std::complex<double> >::set(
const std::string &str)
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]);
319 it_assert(!buffer.fail(),
"Vec<complex>::set(): Stream operation failed "
325 #if defined(HAVE_BLAS)
329 it_assert_debug(v1.datasize == v2.datasize,
"vec::dot(): Wrong sizes");
331 return blas::ddot_(&v1.datasize, v1.data, &incr, v2.data, &incr);
337 it_assert_debug(v1.datasize == v2.datasize,
"Vec::dot(): Wrong sizes");
339 for (
int i = 0; i < v1.datasize; ++i)
340 r += v1.data[i] * v2.data[i];
345 #if defined(HAVE_BLAS)
350 "Vec::outer_product():: Input vector of zero size");
352 mat out(v1.datasize, v2.datasize);
356 blas::dger_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
357 v2.data, &incr, out._data(), &v1.datasize);
365 "Vec::outer_product():: Input vector of zero size");
367 cmat out(v1.datasize, v2.datasize);
369 std::complex<double> alpha(1.0);
372 blas::zgerc_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
373 v2.data, &incr, out._data(), &v1.datasize);
376 blas::zgeru_(&v1.datasize, &v2.datasize, &alpha, v1.data, &incr,
377 v2.data, &incr, out._data(), &v1.datasize);
386 "Vec::outer_product():: Input vector of zero size");
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];
401 "Vec::outer_product():: Input vector of zero size");
403 cmat out(v1.datasize, v2.datasize);
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]);
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];
424 bvec Vec<std::complex<double> >::operator<=(std::complex<double>)
const
426 it_error(
"operator<=: not implemented for complex");
432 bvec Vec<std::complex<double> >::operator>(std::complex<double>)
const
434 it_error(
"operator>: not implemented for complex");
440 bvec Vec<std::complex<double> >::operator<(std::complex<double>)
const
442 it_error(
"operator<: not implemented for complex");
448 bvec Vec<std::complex<double> >::operator>=(std::complex<double>)
const
450 it_error(
"operator>=: not implemented for complex");
458 Mat<std::complex<double> > temp(1, datasize);
459 for (
int i = 0; i < datasize; i++)
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>;
526 #if !defined(HAVE_BLAS)
527 template double dot(
const vec &v1,
const vec &v2);
529 template std::complex<double>
dot(
const cvec &v1,
const cvec &v2);
531 template short dot(
const svec &v1,
const svec &v2);
540 #if !defined(HAVE_BLAS)
697 const vec &v3,
const vec &v4);
708 const vec &v4,
const vec &v5);
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);