casadi_misc.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_MISC_HPP
27 #define CASADI_MISC_HPP
28 
29 #include "exception.hpp"
30 #include "casadi_common.hpp"
31 
39 namespace casadi {
40 
41 #ifndef SWIG
42 
43 template<typename T>
44 class scoped_checkout {
45 public:
46  scoped_checkout(const T& proto) : proto_(proto) {
47  mem = proto_.checkout();
48  }
49 
50  scoped_checkout(scoped_checkout&& that) : mem(that.mem), proto_(that.proto_) {
51  that.mem = -1;
52  }
53 
54  scoped_checkout(const scoped_checkout& that) = delete;
55 
56  ~scoped_checkout() {
57  if (mem!=-1) proto_.release(mem);
58  }
59 
60  operator casadi_int() const {
61  return mem;
62  }
63 
64 private:
65  int mem;
66  const T& proto_;
67 };
68 
80  CASADI_EXPORT std::vector<casadi_int> range(casadi_int start, casadi_int stop, casadi_int step=1,
81  casadi_int len=std::numeric_limits<casadi_int>::max());
82 
86  CASADI_EXPORT bool is_range(const std::vector<casadi_int>& v,
87  casadi_int start, casadi_int stop, casadi_int step=1);
88 
89  CASADI_EXPORT std::string join(const std::vector<std::string>& l, const std::string& delim=",");
90 
92  CASADI_EXPORT bool startswith(const std::string& s, const std::string& p);
93 
95  CASADI_EXPORT std::string replace(const std::string& s,
96  const std::string& p, const std::string& r);
97 
105  CASADI_EXPORT std::vector<casadi_int> range(casadi_int stop);
106 
108  CASADI_EXPORT bool all(const std::vector<bool> &v);
110  CASADI_EXPORT bool any(const std::vector<bool> &v);
112  CASADI_EXPORT std::vector<bool> boolvec_not(const std::vector<bool> &v);
114  CASADI_EXPORT std::vector<bool> boolvec_and(const std::vector<bool> &lhs,
115  const std::vector<bool> &rhs);
117  CASADI_EXPORT std::vector<bool> boolvec_or(const std::vector<bool> &lhs,
118  const std::vector<bool> &rhs);
119 
120  CASADI_EXPORT std::vector<casadi_int> boolvec_to_index(const std::vector<bool> &v);
121 
122  CASADI_EXPORT bool is_equally_spaced(const std::vector<double> &v);
123 
125  CASADI_EXPORT std::vector<casadi_int> tensor_permute_mapping(const std::vector<casadi_int>& dims,
126  const std::vector<casadi_int>& order);
127 
128  CASADI_EXPORT int to_int(casadi_int rhs);
129  CASADI_EXPORT std::vector<int> to_int(const std::vector<casadi_int>& rhs);
130  CASADI_EXPORT std::vector< std::vector<int> > to_int(
131  const std::vector< std::vector<casadi_int> >& rhs);
132 
133  template<typename T, typename S>
134  std::vector<T> vector_static_cast(const std::vector<S>& rhs);
135 
136  CASADI_EXPORT std::string str_bvec(bvec_t v);
137 
144  template<typename T>
145  std::vector<T> vector_slice(const std::vector<T> &v, const std::vector<casadi_int> &i);
146 
150  template<typename T>
151  std::vector<T> vector_tail(const std::vector<T> &v);
152 
156  template<typename T>
157  std::vector<T> reverse(const std::vector<T> &v);
158 
162  template<typename T>
163  std::vector<T> join(const std::vector<T> &a, const std::vector<T> &b);
164 
168  template<typename T>
169  std::vector<T> join(const std::vector<T> &a, const std::vector<T> &b, const std::vector<T> &c);
170 
174  bool is_permutation(const std::vector<casadi_int> &order);
175 
179  template<typename T>
180  std::vector<T> permute(const std::vector<T> &a, const std::vector<casadi_int> &order);
181 
185  std::vector<casadi_int> invert_permutation(const std::vector<casadi_int> &a);
186 
190  template<typename T>
191  std::vector<casadi_int> find(const std::vector<T> &v);
192 
193  #endif // SWIG
194 
196  template<typename T>
197  bool in_range(const std::vector<T> &v, casadi_int upper);
198 
200  template<typename T>
201  bool in_range(const std::vector<T> &v, casadi_int lower, casadi_int upper);
202 
203  // Assert that a indices are in a range
204  #define casadi_assert_in_range(v, lower, upper) \
205  casadi_assert(in_range(v, lower, upper), \
206  "Out of bounds error. Got elements in range [" \
207  + str(*std::min_element(v.begin(), v.end())) + ","\
208  + str(*std::max_element(v.begin(), v.end())) + "], which is outside the range ["\
209  + str(lower) + "," + str(upper) + ").")
210 
211  // Assert that a indices are bounded
212  #define casadi_assert_bounded(v, upper) \
213  casadi_assert(in_range(v, upper), \
214  "Out of bounds error. Got elements in range [" \
215  + str(*std::min_element(v.begin(), v.end())) + ","\
216  + str(*std::max_element(v.begin(), v.end())) + "], which exceeds the upper bound "\
217  + str(upper) + ".")
218 
226  CASADI_EXPORT std::vector<casadi_int> complement(const std::vector<casadi_int> &v,
227  casadi_int size);
228 
237  CASADI_EXPORT std::vector<casadi_int> lookupvector(const std::vector<casadi_int> &v,
238  casadi_int size);
239  CASADI_EXPORT std::vector<casadi_int> lookupvector(const std::vector<casadi_int> &v);
240 
246  template<class T, class S>
247  void flatten_nested_vector(const std::vector< std::vector<T> >& nested,
248  std::vector<S>& flat);
249 
255  template<class T, class S, class I>
256  void flatten_nested_vector(const std::vector< std::vector<T> >& nested,
257  std::vector<S>& flat,
258  std::vector<I>& indices);
259 
261 #ifndef SWIG
265  template<class T>
266  std::vector<T> applymap(T (*f)(const T&), const std::vector<T>& comp);
267 
271  template<class T>
272  void applymap(void (*f)(T&), std::vector<T>& comp);
273 #endif // SWIG
275 
276 
278  template<typename T>
279  bool is_increasing(const std::vector<T> &v);
280 
282  template<typename T>
283  bool is_decreasing(const std::vector<T> &v);
284 
286  template<typename T>
287  bool is_nonincreasing(const std::vector<T> &v);
288 
290  template<typename T>
291  bool is_nondecreasing(const std::vector<T> &v);
292 
294  template<typename T>
295  bool is_monotone(const std::vector<T> &v);
296 
298  template<typename T>
299  bool is_strictly_monotone(const std::vector<T> &v);
300 
302  template<typename T>
303  bool has_negative(const std::vector<T> &v);
304 
306  template<typename T>
307  void write_matlab(std::ostream &stream, const std::vector<T> &v);
308 
310  template<typename T>
311  void write_matlab(std::ostream &stream, const std::vector<std::vector<T> > &v);
312 
314  template<typename T>
315  void read_matlab(std::istream &stream, std::vector<T> &v);
316 
318  template<typename T>
319  void read_matlab(std::ifstream &file, std::vector<std::vector<T> > &v);
320 
321 #ifndef SWIG
323  template<typename T, typename F, typename L>
324  void linspace(std::vector<T> &v, const F& first, const L& last);
325 
328  CASADI_EXPORT bvec_t* get_bvec_t(std::vector<double>& v);
329 
331  CASADI_EXPORT const bvec_t* get_bvec_t(const std::vector<double>& v);
332 
334  CASADI_EXPORT bvec_t bvec_or(const bvec_t* arg, casadi_int n);
335 
337  template<typename T>
338  bvec_t* get_bvec_t(std::vector<T>& v);
339 
341  template<typename T>
342  const bvec_t* get_bvec_t(const std::vector<T>& v);
343 
345  template<typename T>
346  T* get_ptr(std::vector<T> &v);
347 
349  template<typename T>
350  const T* get_ptr(const std::vector<T> &v);
351 
353 
362  template<typename T>
363  void sort(const std::vector<T> &values, std::vector<T> &sorted_values,
364  std::vector<casadi_int> &indices, bool invert_indices =false);
365 
369  template<typename T>
370  T product(const std::vector<T> &values);
371 
375  template<typename T>
376  T sum(const std::vector<T> &values);
377 
381  template<typename T>
382  std::vector<T> cumsum(const std::vector<T> &values);
383 
387  template<typename T>
388  std::vector<T> diff(const std::vector<T> &values);
389 
393  template<typename T>
394  std::vector<T> cumsum0(const std::vector<T> &values);
395 #endif //SWIG
396 
398  template<typename T>
399  bool is_regular(const std::vector<T> &v) {
400  for (auto&& vk : v) {
401  if (vk!=vk || vk==std::numeric_limits<T>::infinity() ||
402  vk==-std::numeric_limits<T>::infinity()) return false;
403  }
404  return true;
405  }
406 
407  // Create a temporary file
408  CASADI_EXPORT std::string temporary_file(const std::string& prefix, const std::string& suffix);
409 
410  CASADI_EXPORT void normalized_setup(std::istream& stream);
411  CASADI_EXPORT void normalized_setup(std::ostream& stream);
412 
413  inline void normalized_out(std::ostream& stream, double val) {
414  if (val==std::numeric_limits<double>::infinity()) {
415  stream << "inf";
416  } else if (val==-std::numeric_limits<double>::infinity()) {
417  stream << "-inf";
418  } else if (val!=val) {
419  stream << "nan";
420  } else {
421  stream << val;
422  }
423  }
424  inline int normalized_in(std::istream& stream, double& ret) {
425  std::streampos start = stream.tellg();
426  stream >> ret;
427  // Failed to interpret as double?
428  if (stream.fail()) {
429  // Clear error flag
430  stream.clear();
431  // Reset stream position
432  // Need to parse e.g "-inf"
433  stream.seekg(start);
434  // Might be a inf/nan
435  std::string non_reg;
436  stream >> non_reg;
437  // Break on trailing whitespace
438  if (stream.fail()) {
439  if (stream.eof()) {
440  ret = std::numeric_limits<double>::quiet_NaN();
441  return -1; // End of stream
442  } else {
443  ret = std::numeric_limits<double>::quiet_NaN();
444  return 1; // Failed to parse to string
445  }
446  }
447  if (non_reg=="inf") {
448  ret = std::numeric_limits<double>::infinity();
449  } else if (non_reg=="-inf") {
450  ret = -std::numeric_limits<double>::infinity();
451  } else if (non_reg=="nan") {
452  ret = std::numeric_limits<double>::quiet_NaN();
453  } else {
454  ret = std::numeric_limits<double>::quiet_NaN();
455  return 2; // Failed to interpret as number
456  }
457  }
458  return 0;
459  }
460 
461 } // namespace casadi
462 
463 #ifndef SWIG
464 // In std namespace
465 namespace std {
466 
468  template<typename T>
469  ostream& operator<<(ostream& stream, const vector<T>& v) {
470  stream << casadi::str(v);
471  return stream;
472  }
473 
475  template<typename T>
476  ostream& operator<<(ostream& stream, const set<T>& v) {
477  stream << casadi::str(v);
478  return stream;
479  }
480 
481  template<typename T1, typename T2>
482  ostream& operator<<(ostream& stream, const pair<T1, T2>& p) {
483  stream << casadi::str(p);
484  return stream;
485  }
486 
487  template<typename T1, typename T2>
488  ostream& operator<<(ostream& stream, const std::map<T1, T2>& p) {
489  stream << casadi::str(p);
490  return stream;
491  }
492 
493  template<typename T2>
494  ostream& operator<<(ostream& stream, const std::map<std::string, T2>& p) {
495  stream << casadi::str(p);
496  return stream;
497  }
498 
499  template<typename T>
500  bool mul_overflows(const T& a, const T& b) {
501  if (a==0 || b==0) return false;
502  return abs(std::numeric_limits<T>::max()/a) < abs(b);
503  }
504 
505 } // namespace std
506 
507 // Implementations
508 namespace casadi {
509 
510  template<typename T, typename S>
511  std::vector<T> vector_static_cast(const std::vector<S>& rhs) {
512  std::vector<T> ret;
513  ret.reserve(rhs.size());
514  for (auto e : rhs) ret.push_back(static_cast<T>(e));
515  return ret;
516  }
517 
518  template<typename T>
519  std::vector<T> vector_slice(const std::vector<T> &v, const std::vector<casadi_int> &i) {
520  std::vector<T> ret;
521  ret.reserve(i.size());
522  for (casadi_int k=0;k<i.size();++k) {
523  casadi_int j = i[k];
524  casadi_assert(j>=0,
525  "vector_slice: Indices should be larger than zero."
526  "You have " + str(j) + " at location " + str(k) + ".");
527  casadi_assert(j<v.size(),
528  "vector_slice: Indices should be larger than zero."
529  "You have " + str(j) + " at location " + str(k) + ".");
530  ret.push_back(v[j]);
531  }
532  return ret;
533  }
534 
535  template<typename T>
536  std::vector<T> vector_tail(const std::vector<T> &v) {
537  std::vector<T> ret;
538  ret.insert(ret.begin(), v.begin()+1, v.end());
539  return ret;
540  }
541 
542  template<typename T>
543  std::vector<T> reverse(const std::vector<T> &v) {
544  std::vector<T> ret(v.size());
545  std::reverse_copy(v.begin(), v.end(), ret.begin());
546  return ret;
547  }
548 
549  template<typename T>
550  std::vector<T> join(const std::vector<T> &a, const std::vector<T> &b) {
551  std::vector<T> ret = a;
552  ret.insert(ret.end(), b.begin(), b.end());
553  return ret;
554  }
555 
556  template<typename T>
557  std::vector<T> join(const std::vector<T> &a, const std::vector<T> &b, const std::vector<T> &c) {
558  std::vector<T> ret = a;
559  ret.insert(ret.end(), b.begin(), b.end());
560  ret.insert(ret.end(), c.begin(), c.end());
561  return ret;
562  }
563 
564  template<typename T>
565  std::vector<T> permute(const std::vector<T> &a, const std::vector<casadi_int> &order) {
566  casadi_assert_dev(order.size()==a.size());
567  casadi_assert_dev(is_permutation(order));
568  return vector_slice(a, order);
569  }
570 
571  template<typename T>
572  std::vector<casadi_int> find(const std::vector<T> &v) {
573  std::vector<casadi_int> ret;
574  for (casadi_int i=0;i<v.size();++i) {
575  if (v[i]) ret.push_back(i);
576  }
577  return ret;
578  }
579 
580 #ifndef SWIG
581  template<class T>
582  std::vector<T> applymap(T (*f)(const T&) , const std::vector<T>& comp) {
583  std::vector<T> ret(comp.size());
584  std::transform(comp.begin(), comp.end(), ret.begin(), f);
585  return ret;
586  }
587 
588  template<class T>
589  void applymap(void (*f)(T &), std::vector<T>& comp) {
590  std::for_each(comp.begin(), comp.end(), f);
591  }
592 
593  template<class S, class D>
594  void copy_vector(const std::vector<S>& s, std::vector<D>& d) {
595  casadi_assert(s.size()==d.size(), "Dimension mismatch.");
596  std::copy(s.begin(), s.end(), d.begin());
597  }
598 
599  template<class S, class D>
600  void assign_vector(const std::vector<S>& s, std::vector<D>& d) {
601  casadi_assert(d.empty(), "Receiving vector must be empty");
602  d.resize(s.size());
603  std::copy(s.begin(), s.end(), d.begin());
604  }
605 
606  template<class S, class D>
607  void copy_vector(const S* s, std::vector<D>& d) {
608  for (casadi_int i=0;i<d.size();++i) {
609  d[i] = static_cast<D>(s[i]);
610  }
611  }
612 
613  template<class S, class D>
614  void init_vector(std::vector<S>& d, const std::vector<D>& s) {
615  d.resize(s.size());
616  std::copy(s.begin(), s.end(), d.begin());
617  }
618 #endif //SWIG
619 
620  template<typename T>
621  bool in_range(const std::vector<T> &v, casadi_int upper) {
622  return in_range(v, 0, upper);
623  }
624 
625  template<typename T>
626  bool in_range(const std::vector<T> &v, casadi_int lower, casadi_int upper) {
627  if (v.empty()) return true;
628  casadi_int max = *std::max_element(v.begin(), v.end());
629  if (max >= upper) return false;
630  casadi_int min = *std::min_element(v.begin(), v.end());
631  return (min >= lower);
632  }
633 
634  template<class T, class S>
635  void flatten_nested_vector(const std::vector< std::vector<T> >& nested,
636  std::vector<S>& flat) {
637  // Count total elements in nested
638  casadi_int N = 0;
639  for (const auto& e : nested) {
640  N += e.size();
641  }
642 
643  // Populate flat, one nested section at a time
644  flat.clear();
645  flat.reserve(N);
646  for (const auto& e : nested) {
647  flat.insert(flat.end(), e.begin(), e.end());
648  }
649  }
650 
651  template<class T, class S, class I>
652  void flatten_nested_vector(const std::vector< std::vector<T> >& nested,
653  std::vector<S>& flat,
654  std::vector<I>& indices) {
655  // Delegate
656  flatten_nested_vector(nested, flat);
657 
658  // Build up indices
659  casadi_int N = nested.size();
660  indices.resize(1, 0);
661  indices.reserve(N+1);
662  casadi_int offset = 0;
663  for (const auto& e : nested) {
664  offset += e.size();
665  indices.push_back(offset);
666  }
667  }
668 
669  template<typename T>
670  bool isUnique(const std::vector<T> &v) {
671  std::set<T> s(v.begin(), v.end());
672  return v.size()==s.size();
673  }
674 
675  template<typename T>
676  bool is_increasing(const std::vector<T> &v) {
677  if (v.empty()) return true;
678  T el = v[0];
679  for (casadi_int i=1;i<v.size();++i) {
680  if (!(v[i] > el)) return false;
681  el = v[i];
682  }
683  return el==el; // nan -> false
684  }
685 
686  template<typename T>
687  bool is_decreasing(const std::vector<T> &v) {
688  if (v.empty()) return true;
689  T el = v[0];
690  for (casadi_int i=1;i<v.size();++i) {
691  if (!(v[i] < el)) return false;
692  el = v[i];
693  }
694  return el==el; // nan -> false
695  }
696 
697  template<typename T>
698  bool is_nonincreasing(const std::vector<T> &v) {
699  if (v.empty()) return true;
700  T el = v[0];
701  for (casadi_int i=1;i<v.size();++i) {
702  if (!(v[i] <= el)) return false;
703  el = v[i];
704  }
705  return el==el; // nan -> false
706  }
707 
708  template<typename T>
709  bool is_nondecreasing(const std::vector<T> &v) {
710  if (v.empty()) return true;
711  T el = v[0];
712  for (casadi_int i=1;i<v.size();++i) {
713  if (!(v[i] >= el)) return false;
714  el = v[i];
715  }
716  return el==el; // nan -> false
717  }
718 
719  template<typename T>
720  bool is_monotone(const std::vector<T> &v) {
721  return is_nondecreasing(v) || is_nonincreasing(v);
722  }
723 
724  template<typename T>
725  bool is_strictly_monotone(const std::vector<T> &v) {
726  return is_decreasing(v) || is_increasing(v);
727  }
728 
729  template<typename T>
730  bool has_negative(const std::vector<T> &v) {
731  for (std::size_t i=0; i<v.size(); ++i) {
732  if (v[i]<0) return true;
733  }
734  return false;
735  }
736 
737  template<typename T>
738  void write_matlab(std::ostream &stream, const std::vector<T> &v) {
739  std::copy(v.begin(), v.end(), std::ostream_iterator<T>(stream, " "));
740  }
741 
742  template<typename T>
743  void write_matlab(std::ostream &stream, const std::vector<std::vector<T> > &v) {
744  for (casadi_uint i=0; i<v.size(); ++i) {
745  std::copy(v[i].begin(), v[i].end(), std::ostream_iterator<T>(stream, " "));
746  stream << std::endl;
747  }
748  }
749 
750  template<typename T>
751  void read_matlab(std::istream &stream, std::vector<T> &v) {
752  v.clear();
753 
754  while (!stream.eof()) {
755  T val;
756  stream >> val;
757  if (stream.fail()) {
758  stream.clear();
759  std::string s;
760  stream >> s;
761  if (s=="inf")
762  val = std::numeric_limits<T>::infinity();
763  else
764  break;
765  }
766  v.push_back(val);
767  }
768  }
769 
770  template<typename T>
771  void read_matlab(std::ifstream &file, std::vector<std::vector<T> > &v) {
772  v.clear();
773  std::string line;
774  while (!getline(file, line, '\n').eof()) {
775  std::istringstream reader(line);
776  std::vector<T> lineData;
777 
778  while (!reader.eof()) {
779  T val;
780  reader >> val;
781  if (reader.fail()) {
782  reader.clear();
783  std::string s;
784  reader >> s;
785  if (s=="inf")
786  val = std::numeric_limits<T>::infinity();
787  else
788  break;
789  }
790  lineData.push_back(val);
791  }
792  v.push_back(lineData);
793  }
794  }
795 
796  template<typename T, typename F, typename L>
797  void linspace(std::vector<T> &v, const F& first, const L& last) {
798  if (v.size()<2)
799  throw CasadiException("std::linspace: vector must contain at least two elements");
800 
801  // Increment
802  T increment = (last-first)/T(v.size()-1);
803 
804  v[0] = first;
805  for (unsigned i=1; i<v.size()-1; ++i)
806  v[i] = v[i-1] + increment;
807  v[v.size()-1] = last;
808  }
809 
810  template<typename T>
811  T* get_ptr(std::vector<T> &v) {
812  if (v.empty())
813  return nullptr;
814  else
815  return &v.front();
816  }
817 
818  template<typename T>
819  const T* get_ptr(const std::vector<T> &v) {
820  if (v.empty())
821  return nullptr;
822  else
823  return &v.front();
824  }
825 
826  // Helper class
827  template<typename T>
828  struct sortCompare {
829  const std::vector<T> &v_;
830  sortCompare(const std::vector<T> &v) : v_(v) {}
831  bool operator() (casadi_int i, casadi_int j) const { return v_[i]<v_[j];}
832  };
833 
834  template<typename T>
835  void sort(const std::vector<T> &values, std::vector<T> &sorted_values,
836  std::vector<casadi_int> &indices, bool invert_indices) {
837  // Call recursively if indices need to be inverted
838  if (invert_indices) {
839  std::vector<casadi_int> inverted;
840  sort(values, sorted_values, inverted, false);
841  indices.resize(inverted.size());
842  for (size_t i=0; i<inverted.size(); ++i) {
843  indices[inverted[i]] = i;
844  }
845  return;
846  }
847 
848  // Create list of indices
849  indices.resize(values.size());
850  for (size_t i=0; i<indices.size(); ++i) indices[i] = i;
851 
852  // Sort this list by the values
853  std::sort(indices.begin(), indices.end(), sortCompare<T>(values));
854 
855  // Sort the values accordingly
856  sorted_values.resize(values.size());
857  for (size_t i=0; i<values.size(); ++i) {
858  sorted_values[i] = values[indices[i]];
859  }
860  }
861 
862  template<typename T>
863  T product(const std::vector<T> &values) {
864  T r = 1;
865  for (casadi_int i=0;i<values.size();++i) r*=values[i];
866  return r;
867  }
868 
869  template<typename T>
870  T sum(const std::vector<T> &values) {
871  T r = 0;
872  for (casadi_int i=0;i<values.size();++i) r+=values[i];
873  return r;
874  }
875 
876  template<typename T>
877  std::vector<T> cumsum(const std::vector<T> &values) {
878  std::vector<T> ret(values.size());
879  T acc = 0;
880  for (casadi_int i=0;i<values.size();++i) {
881  acc+= values[i];
882  ret[i] = acc;
883  }
884  return ret;
885  }
886 
887  template<typename T>
888  std::vector<T> cumsum0(const std::vector<T> &values) {
889  std::vector<T> ret(values.size()+1, 0);
890  T acc = 0;
891  for (casadi_int i=0;i<values.size();++i) {
892  acc+= values[i];
893  ret[i+1] = acc;
894  }
895  return ret;
896  }
897 
898  template<typename T>
899  std::vector<T> diff(const std::vector<T> &values) {
900  casadi_assert(!values.empty(), "Array must be non-empty");
901  std::vector<T> ret(values.size()-1);
902  for (casadi_int i=0;i<values.size()-1;++i) {
903  ret[i] = values[i+1]-values[i];
904  }
905  return ret;
906  }
907 
908  template<typename T>
909  T dot(const std::vector<T>& a, const std::vector<T>& b) {
910  T ret = 0;
911  for (casadi_int k=0; k<a.size(); ++k) {
912  ret += a[k]*b[k];
913  }
914  return ret;
915  }
916 
917  template<typename T>
918  T norm_inf(const std::vector<T>& x) {
919  T ret = 0;
920  for (casadi_int k=0; k<x.size(); ++k) {
921  ret = fmax(ret, fabs(x[k]));
922  }
923  return ret;
924  }
925 
926  template<typename T>
927  T norm_1(const std::vector<T>& x) {
928  T ret = 0;
929  for (casadi_int k=0; k<x.size(); ++k) {
930  ret += fabs(x[k]);
931  }
932  return ret;
933  }
934 
935  template<typename T>
936  T norm_2(const std::vector<T>& x) {
937  T ret = 0;
938  for (casadi_int k=0; k<x.size(); ++k) {
939  ret += x[k]*x[k];
940  }
941  return sqrt(ret);
942  }
943 
944  template<typename T>
945  bvec_t* get_bvec_t(std::vector<T>& v) {
946  casadi_assert(0, "get_bvec_t only supported for double");
947  }
948 
949  template<typename T>
950  const bvec_t* get_bvec_t(const std::vector<T>& v) {
951  casadi_assert(0, "get_bvec_t only supported for double");
952  }
953 
956  typedef std::vector<std::string> StringVector;
958 
959 } // namespace casadi
960 #endif // SWIG
961 
962 #endif // CASADI_MISC_HPP
The casadi namespace.
bool is_decreasing(const std::vector< T > &v)
Check if the vector is strictly decreasing.
CASADI_EXPORT std::string temporary_file(const std::string &prefix, const std::string &suffix)
void flatten_nested_vector(const std::vector< std::vector< T > > &nested, std::vector< S > &flat)
Flatten a nested std::vector tot a single flattened vector.
bool has_negative(const std::vector< T > &v)
Check if the vector has negative entries.
bool is_increasing(const std::vector< T > &v)
Check if the vector is strictly increasing.
bool is_monotone(const std::vector< T > &v)
Check if the vector is monotone.
void write_matlab(std::ostream &stream, const std::vector< T > &v)
Print vector, matlab style.
CASADI_EXPORT void normalized_setup(std::istream &stream)
void read_matlab(std::istream &stream, std::vector< T > &v)
Read vector, matlab style.
bool is_strictly_monotone(const std::vector< T > &v)
Check if the vector is strictly monotone.
CASADI_EXPORT std::vector< casadi_int > complement(const std::vector< casadi_int > &v, casadi_int size)
Returns the list of all i in [0, size[ not found in supplied list.
bool in_range(const std::vector< T > &v, casadi_int upper)
Check if for each element of v holds: v_i < upper.
bool is_nonincreasing(const std::vector< T > &v)
Check if the vector is non-increasing.
bool is_regular(const std::vector< T > &v)
Checks if array does not contain NaN or Inf.
bool is_nondecreasing(const std::vector< T > &v)
Check if the vector is non-decreasing.
int normalized_in(std::istream &stream, double &ret)
CASADI_EXPORT std::vector< casadi_int > lookupvector(const std::vector< casadi_int > &v, casadi_int size)
Returns a vector for quickly looking up entries of supplied list.
void normalized_out(std::ostream &stream, double val)