26 #ifndef CASADI_MISC_HPP
27 #define CASADI_MISC_HPP
29 #include "exception.hpp"
30 #include "casadi_common.hpp"
48 mem = proto_.checkout();
58 if (mem!=-1) proto_.release(mem);
61 operator casadi_int()
const {
81 CASADI_EXPORT std::vector<casadi_int>
range(casadi_int start, casadi_int stop, casadi_int step=1,
82 casadi_int len=std::numeric_limits<casadi_int>::max());
87 CASADI_EXPORT
bool is_range(
const std::vector<casadi_int>& v,
88 casadi_int start, casadi_int stop, casadi_int step=1);
91 CASADI_EXPORT
void check_offset(
const std::vector<casadi_int>& offset, casadi_int n,
92 const std::string& fname);
94 CASADI_EXPORT std::string
join(
const std::vector<std::string>& l,
const std::string& delim=
",");
97 CASADI_EXPORT
bool startswith(
const std::string& s,
const std::string& p);
100 CASADI_EXPORT std::string
replace(
const std::string& s,
101 const std::string& p,
const std::string& r);
104 CASADI_EXPORT
bool version_gt(
const std::string& version_left,
105 const std::string& version_right);
108 CASADI_EXPORT
bool version_ge(
const std::string& version_left,
109 const std::string& version_right);
112 CASADI_EXPORT
bool version_lt(
const std::string& version_left,
113 const std::string& version_right);
116 CASADI_EXPORT
bool version_le(
const std::string& version_left,
117 const std::string& version_right);
126 CASADI_EXPORT std::vector<casadi_int>
range(casadi_int stop);
129 CASADI_EXPORT
bool all(
const std::vector<bool> &v);
131 CASADI_EXPORT
bool any(
const std::vector<bool> &v);
133 CASADI_EXPORT std::vector<bool>
boolvec_not(
const std::vector<bool> &v);
135 CASADI_EXPORT std::vector<bool>
boolvec_and(
const std::vector<bool> &lhs,
136 const std::vector<bool> &rhs);
138 CASADI_EXPORT std::vector<bool>
boolvec_or(
const std::vector<bool> &lhs,
139 const std::vector<bool> &rhs);
141 CASADI_EXPORT std::vector<casadi_int>
boolvec_to_index(
const std::vector<bool> &v);
145 CASADI_EXPORT
int to_int(casadi_int rhs);
146 CASADI_EXPORT std::vector<int>
to_int(
const std::vector<casadi_int>& rhs);
147 CASADI_EXPORT std::vector< std::vector<int> >
to_int(
148 const std::vector< std::vector<casadi_int> >& rhs);
150 template<
typename T,
typename S>
162 std::vector<T>
vector_slice(
const std::vector<T> &v,
const std::vector<casadi_int> &i);
171 std::vector<T>
vector_select(
const std::vector<T> &v,
const std::vector<bool> &s,
178 std::vector<T>
vector_tail(
const std::vector<T> &v);
184 std::vector<T>
vector_init(
const std::vector<T> &v);
190 std::vector<T>
reverse(
const std::vector<T> &v);
196 std::vector<T>
join(
const std::vector<T> &a,
const std::vector<T> &b);
202 std::vector<T>
join(
const std::vector<T> &a,
const std::vector<T> &b,
const std::vector<T> &c);
213 std::vector<T>
permute(
const std::vector<T> &a,
const std::vector<casadi_int> &order);
224 std::vector<casadi_int>
find(
const std::vector<T> &v);
230 bool in_range(
const std::vector<T> &v, casadi_int upper);
234 bool in_range(
const std::vector<T> &v, casadi_int lower, casadi_int upper);
237 #define casadi_assert_in_range(v, lower, upper) \
238 casadi_assert(in_range(v, lower, upper), \
239 "Out of bounds error. Got elements in range [" \
240 + str(*std::min_element(v.begin(), v.end())) + ","\
241 + str(*std::max_element(v.begin(), v.end())) + "], which is outside the range ["\
242 + str(lower) + "," + str(upper) + ").")
245 #define casadi_assert_bounded(v, upper) \
246 casadi_assert(in_range(v, upper), \
247 "Out of bounds error. Got elements in range [" \
248 + str(*std::min_element(v.begin(), v.end())) + ","\
249 + str(*std::max_element(v.begin(), v.end())) + "], which exceeds the upper bound "\
259 CASADI_EXPORT std::vector<casadi_int>
complement(
const std::vector<casadi_int> &v,
270 CASADI_EXPORT std::vector<casadi_int>
lookupvector(
const std::vector<casadi_int> &v,
272 CASADI_EXPORT std::vector<casadi_int>
lookupvector(
const std::vector<casadi_int> &v);
279 template<
class T,
class S>
281 std::vector<S>& flat);
288 template<
class T,
class S,
class I>
290 std::vector<S>& flat,
291 std::vector<I>& indices);
299 std::vector<T>
applymap(T (*f)(
const T&),
const std::vector<T>& comp);
305 void applymap(
void (*f)(T&), std::vector<T>& comp);
340 void write_matlab(std::ostream &stream,
const std::vector<T> &v);
344 void write_matlab(std::ostream &stream,
const std::vector<std::vector<T> > &v);
348 void read_matlab(std::istream &stream, std::vector<T> &v);
352 void read_matlab(std::ifstream &file, std::vector<std::vector<T> > &v);
356 template<
typename T,
typename F,
typename L>
357 void linspace(std::vector<T> &v,
const F& first,
const L& last);
383 const T*
get_ptr(
const std::vector<T> &v);
396 void sort(
const std::vector<T> &values, std::vector<T> &sorted_values,
397 std::vector<casadi_int> &indices,
bool invert_indices =
false);
403 T
product(
const std::vector<T> &values);
409 T
sum(
const std::vector<T> &values);
415 std::vector<T>
cumsum(
const std::vector<T> &values);
421 std::vector<T>
diff(
const std::vector<T> &values);
427 std::vector<T>
cumsum0(
const std::vector<T> &values);
433 for (
auto&& vk : v) {
434 if (vk!=vk || vk==std::numeric_limits<T>::infinity() ||
435 vk==-std::numeric_limits<T>::infinity())
return false;
441 CASADI_EXPORT std::string
temporary_file(
const std::string& prefix,
442 const std::string& suffix,
443 const std::string& directory=
"");
455 std::ostream& stream_;
456 std::ios::fmtflags flags_;
457 std::streamsize precision_;
458 std::streamsize width_;
463 if (val==std::numeric_limits<double>::infinity()) {
465 }
else if (val==-std::numeric_limits<double>::infinity()) {
467 }
else if (val!=val) {
474 std::streampos start = stream.tellg();
489 ret = std::numeric_limits<double>::quiet_NaN();
492 ret = std::numeric_limits<double>::quiet_NaN();
496 if (non_reg==
"inf") {
497 ret = std::numeric_limits<double>::infinity();
498 }
else if (non_reg==
"-inf") {
499 ret = -std::numeric_limits<double>::infinity();
500 }
else if (non_reg==
"nan" || non_reg==
"-nan") {
501 ret = std::numeric_limits<double>::quiet_NaN();
503 ret = std::numeric_limits<double>::quiet_NaN();
519 std::ostream&
operator<<(std::ostream& stream,
const std::vector<T>& v) {
525 template<
typename T,
size_t N>
526 std::ostream&
operator<<(std::ostream& stream,
const std::array<T, N>& v) {
533 std::ostream&
operator<<(std::ostream& stream,
const std::set<T>& v) {
538 template<
typename T1,
typename T2>
539 std::ostream&
operator<<(std::ostream& stream,
const std::pair<T1, T2>& p) {
544 template<
typename T1,
typename T2>
545 std::ostream&
operator<<(std::ostream& stream,
const std::map<T1, T2>& p) {
550 template<
typename T2>
551 std::ostream&
operator<<(std::ostream& stream,
const std::map<std::string, T2>& p) {
558 if (a==0 || b==0)
return false;
559 return std::abs(std::numeric_limits<T>::max()/a) < std::abs(b);
562 template<
typename T,
typename S>
565 ret.reserve(rhs.size());
566 for (
auto e : rhs) ret.push_back(
static_cast<T>(e));
571 std::vector<T>
vector_slice(
const std::vector<T> &v,
const std::vector<casadi_int> &i) {
573 ret.reserve(i.size());
574 for (casadi_int k=0;k<i.size();++k) {
577 "vector_slice: Indices should be larger than zero."
578 "You have " +
str(j) +
" at location " +
str(k) +
".");
579 casadi_assert(j<v.size(),
580 "vector_slice: Indices should be larger than zero."
581 "You have " +
str(j) +
" at location " +
str(k) +
".");
588 std::vector<T>
vector_select(
const std::vector<T> &v,
const std::vector<bool> &s,
bool invert) {
590 casadi_assert(v.size()==s.size(),
"Dimension mismatch.");
592 for (casadi_int k=0;k<s.size();++k) {
593 if (!s[k]) ret.push_back(v[k]);
596 for (casadi_int k=0;k<s.size();++k) {
597 if (s[k]) ret.push_back(v[k]);
606 ret.insert(ret.begin(), v.begin()+1, v.end());
613 ret.insert(ret.begin(), v.begin(), v.begin()+v.size()-1);
618 std::vector<T>
reverse(
const std::vector<T> &v) {
619 std::vector<T> ret(v.size());
620 std::reverse_copy(v.begin(), v.end(), ret.begin());
625 std::vector<T>
join(
const std::vector<T> &a,
const std::vector<T> &b) {
626 std::vector<T> ret = a;
627 ret.insert(ret.end(), b.begin(), b.end());
632 std::vector<T>
join(
const std::vector<T> &a,
const std::vector<T> &b,
const std::vector<T> &c) {
633 std::vector<T> ret = a;
634 ret.insert(ret.end(), b.begin(), b.end());
635 ret.insert(ret.end(), c.begin(), c.end());
640 std::vector<T>
permute(
const std::vector<T> &a,
const std::vector<casadi_int> &order) {
641 casadi_assert_dev(order.size()==a.size());
647 std::vector<casadi_int>
find(
const std::vector<T> &v) {
648 std::vector<casadi_int> ret;
649 for (casadi_int i=0;i<v.size();++i) {
650 if (v[i]) ret.push_back(i);
657 std::vector<T>
applymap(T (*f)(
const T&) ,
const std::vector<T>& comp) {
658 std::vector<T> ret(comp.size());
659 std::transform(comp.begin(), comp.end(), ret.begin(), f);
664 void applymap(
void (*f)(T &), std::vector<T>& comp) {
665 std::for_each(comp.begin(), comp.end(), f);
668 template<
class S,
class D>
670 casadi_assert(s.size()==d.size(),
"Dimension mismatch.");
671 std::copy(s.begin(), s.end(), d.begin());
674 template<
class S,
class D>
676 casadi_assert(d.empty(),
"Receiving vector must be empty");
678 std::copy(s.begin(), s.end(), d.begin());
681 template<
class S,
class D>
683 for (casadi_int i=0;i<d.size();++i) {
684 d[i] =
static_cast<D>(s[i]);
688 template<
class S,
class D>
691 std::copy(s.begin(), s.end(), d.begin());
696 bool in_range(
const std::vector<T> &v, casadi_int upper) {
701 bool in_range(
const std::vector<T> &v, casadi_int lower, casadi_int upper) {
702 if (v.empty())
return true;
703 casadi_int max = *std::max_element(v.begin(), v.end());
704 if (max >= upper)
return false;
705 casadi_int min = *std::min_element(v.begin(), v.end());
706 return (min >= lower);
709 template<
class T,
class S>
711 std::vector<S>& flat) {
714 for (
const auto& e : nested) {
721 for (
const auto& e : nested) {
722 flat.insert(flat.end(), e.begin(), e.end());
726 template<
class T,
class S,
class I>
728 std::vector<S>& flat,
729 std::vector<I>& indices) {
734 casadi_int N = nested.size();
735 indices.resize(1, 0);
736 indices.reserve(N+1);
737 casadi_int offset = 0;
738 for (
const auto& e : nested) {
740 indices.push_back(offset);
746 std::set<T> s(v.begin(), v.end());
747 return v.size()==s.size();
752 if (v.empty())
return true;
754 for (casadi_int i=1;i<v.size();++i) {
755 if (!(v[i] > el))
return false;
763 if (v.empty())
return true;
765 for (casadi_int i=1;i<v.size();++i) {
766 if (!(v[i] < el))
return false;
774 if (v.empty())
return true;
776 for (casadi_int i=1;i<v.size();++i) {
777 if (!(v[i] <= el))
return false;
785 if (v.empty())
return true;
787 for (casadi_int i=1;i<v.size();++i) {
788 if (!(v[i] >= el))
return false;
806 for (std::size_t i=0; i<v.size(); ++i) {
807 if (v[i]<0)
return true;
814 std::copy(v.begin(), v.end(), std::ostream_iterator<T>(stream,
" "));
818 void write_matlab(std::ostream &stream,
const std::vector<std::vector<T> > &v) {
819 for (casadi_uint i=0; i<v.size(); ++i) {
820 std::copy(v[i].begin(), v[i].end(), std::ostream_iterator<T>(stream,
" "));
829 while (!stream.eof()) {
837 val = std::numeric_limits<T>::infinity();
846 void read_matlab(std::ifstream &file, std::vector<std::vector<T> > &v) {
849 while (!getline(file, line,
'\n').eof()) {
850 std::istringstream reader(line);
851 std::vector<T> lineData;
853 while (!reader.eof()) {
861 val = std::numeric_limits<T>::infinity();
865 lineData.push_back(val);
867 v.push_back(lineData);
871 template<
typename T,
typename F,
typename L>
872 void linspace(std::vector<T> &v,
const F& first,
const L& last) {
874 throw CasadiException(
"std::linspace: vector must contain at least two elements");
877 T increment = (last-first)/
T(v.size()-1);
880 for (
unsigned i=1; i<v.size()-1; ++i)
881 v[i] = v[i-1] + increment;
882 v[v.size()-1] = last;
904 const std::vector<T> &
v_;
910 void sort(
const std::vector<T> &values, std::vector<T> &sorted_values,
911 std::vector<casadi_int> &indices,
bool invert_indices) {
913 if (invert_indices) {
914 std::vector<casadi_int> inverted;
915 sort(values, sorted_values, inverted,
false);
916 indices.resize(inverted.size());
917 for (
size_t i=0; i<inverted.size(); ++i) {
918 indices[inverted[i]] = i;
924 indices.resize(values.size());
925 for (
size_t i=0; i<indices.size(); ++i) indices[i] = i;
928 std::sort(indices.begin(), indices.end(),
sortCompare<T>(values));
931 sorted_values.resize(values.size());
932 for (
size_t i=0; i<values.size(); ++i) {
933 sorted_values[i] = values[indices[i]];
940 for (casadi_int i=0;i<values.size();++i) r*=values[i];
945 T sum(
const std::vector<T> &values) {
947 for (casadi_int i=0;i<values.size();++i) r+=values[i];
952 std::vector<T>
cumsum(
const std::vector<T> &values) {
953 std::vector<T> ret(values.size());
955 for (casadi_int i=0;i<values.size();++i) {
963 std::vector<T>
cumsum0(
const std::vector<T> &values) {
964 std::vector<T> ret(values.size()+1, 0);
966 for (casadi_int i=0;i<values.size();++i) {
974 std::vector<T>
diff(
const std::vector<T> &values) {
975 casadi_assert(!values.empty(),
"Array must be non-empty");
976 std::vector<T> ret(values.size()-1);
977 for (casadi_int i=0;i<values.size()-1;++i) {
978 ret[i] = values[i+1]-values[i];
984 T dot(
const std::vector<T>& a,
const std::vector<T>& b) {
986 for (casadi_int k=0; k<a.size(); ++k) {
995 for (casadi_int k=0; k<x.size(); ++k) {
996 ret = fmax(ret, fabs(x[k]));
1001 template<
typename T>
1004 for (casadi_int k=0; k<x.size(); ++k) {
1010 template<
typename T>
1013 for (casadi_int k=0; k<x.size(); ++k) {
1019 template<
typename T>
1021 casadi_assert(0,
"get_bvec_t only supported for double");
1024 template<
typename T>
1026 casadi_assert(0,
"get_bvec_t only supported for double");
1037 template<
typename T>
1043 template<
typename T>
1045 seed ^=
hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1051 template<
typename T>
1053 for (casadi_int i=0; i<sz; ++i)
hash_combine(seed, v[i]);
1059 template<
typename T>
1077 std::memcpy(&u, &v,
sizeof(
double));
1079 if (
sizeof(
size_t) == 8) {
1081 return static_cast<size_t>(u);
1086 hash_combine(seed,
static_cast<std::uint32_t
>(u >> 32));
scoped_checkout(scoped_checkout &&that)
scoped_checkout(const T &proto)
scoped_checkout(const scoped_checkout &that)=delete
bool mul_overflows(const T &a, const T &b)
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
bvec_t * get_bvec_t(std::vector< double > &v)
bool is_equally_spaced(const std::vector< double > &v)
T product(const std::vector< T > &values)
product
std::vector< T > vector_tail(const std::vector< T > &v)
Return all but the first element of a vector.
std::string join(const std::vector< std::string > &l, const std::string &delim)
bool is_decreasing(const std::vector< T > &v)
Check if the vector is strictly decreasing.
std::vector< casadi_int > invert_permutation(const std::vector< casadi_int > &a)
inverse a permutation vector
void assign_vector(const std::vector< S > &s, std::vector< D > &d)
T norm_1(const std::vector< T > &x)
unsigned long long bvec_t
void init_vector(std::vector< S > &d, const std::vector< D > &s)
T norm_inf(const std::vector< T > &x)
bool version_le(const std::string &version_left, const std::string &version_right)
Compare versions: returns true if version_left <= version_right.
void copy_vector(const std::vector< S > &s, std::vector< D > &d)
bool is_range(const std::vector< casadi_int > &v, casadi_int start, casadi_int stop, casadi_int step)
Check if a vector matches a range.
bool startswith(const std::string &s, const std::string &p)
Checks if s starts with p.
int to_int(casadi_int rhs)
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 isUnique(const std::vector< T > &v)
bool version_gt(const std::string &version_left, const std::string &version_right)
Compare versions: returns true if version_left > version_right.
bool is_increasing(const std::vector< T > &v)
Check if the vector is strictly increasing.
CASADI_EXPORT std::string replace(const std::string &s, const std::string &p, const std::string &r)
Replace all occurences of p with r in s.
void sort(const std::vector< T > &values, std::vector< T > &sorted_values, std::vector< casadi_int > &indices, bool invert_indices=false)
Sort the data in a vector.
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros
void check_offset(const std::vector< casadi_int > &offset, casadi_int n, const std::string &fname)
Assert that offset starts at 0, is nondecreasing and ends at n.
bool is_monotone(const std::vector< T > &v)
Check if the vector is monotone.
std::string str_bvec(bvec_t v)
std::vector< bool > boolvec_or(const std::vector< bool > &lhs, const std::vector< bool > &rhs)
Or operation on boolean vector.
bool version_lt(const std::string &version_left, const std::string &version_right)
Compare versions: returns true if version_left < version_right.
void linspace(std::vector< T > &v, const F &first, const L &last)
Matlab's linspace.
std::string str(const T &v)
String representation, any type.
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 write_matlab(std::ostream &stream, const std::vector< T > &v)
Print vector, matlab style.
std::vector< T > vector_static_cast(const std::vector< S > &rhs)
std::vector< bool > boolvec_not(const std::vector< bool > &v)
Invert all entries.
void hash_combine(std::size_t &seed, T v)
Generate a hash value incrementally (function taken from boost)
std::vector< std::string > StringVector
std::vector< T > cumsum(const std::vector< T > &values)
cumulative sum
std::vector< bool > boolvec_and(const std::vector< bool > &lhs, const std::vector< bool > &rhs)
And operation on boolean vector.
size_t hash_value(T v)
Hash value of an integer.
bool any(const std::vector< bool > &v)
Check if any arguments are true.
void normalized_setup(std::istream &stream)
void read_matlab(std::istream &stream, std::vector< T > &v)
Read vector, matlab style.
T dot(const std::vector< T > &a, const std::vector< T > &b)
bool all(const std::vector< bool > &v)
Check if all arguments are true.
std::ostream & operator<<(std::ostream &stream, const std::vector< T > &v)
Enables flushing an std::vector to a stream (prints representation)
bool is_strictly_monotone(const std::vector< T > &v)
Check if the vector is strictly monotone.
std::vector< T > diff(const std::vector< T > &values)
diff
std::vector< T > vector_select(const std::vector< T > &v, const std::vector< bool > &s, bool invert=false)
Select subset of vector.
std::vector< T > vector_slice(const std::vector< T > &v, const std::vector< casadi_int > &i)
Slicing vector.
std::vector< T > vector_init(const std::vector< T > &v)
Return all but the last element of a vector.
std::vector< T > applymap(T(*f)(const T &), const std::vector< T > &comp)
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
T norm_2(const std::vector< T > &x)
std::vector< T > cumsum0(const std::vector< T > &values)
cumulative sum, starting with zero
bool in_range(const std::vector< T > &v, casadi_int upper)
Check if for each element of v holds: v_i < upper.
bool is_permutation(const std::vector< casadi_int > &order)
Does the list represent a permutation?
bool is_nonincreasing(const std::vector< T > &v)
Check if the vector is non-increasing.
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.
std::vector< T > permute(const std::vector< T > &a, const std::vector< casadi_int > &order)
permute a list
T sum(const std::vector< T > &values)
sum
std::vector< T > reverse(const std::vector< T > &v)
Reverse a list.
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.
bool version_ge(const std::string &version_left, const std::string &version_right)
Compare versions: returns true if version_left >= version_right.
bvec_t bvec_or(const bvec_t *arg, casadi_int n)
Bit-wise or operation on bvec_t array.
int normalized_in(std::istream &stream, double &ret)
std::string temporary_file(const std::string &prefix, const std::string &suffix, const std::string &directory)
void normalized_out(std::ostream &stream, double val)
std::vector< casadi_int > boolvec_to_index(const std::vector< bool > &v)
bool operator()(casadi_int i, casadi_int j) const
const std::vector< T > & v_
sortCompare(const std::vector< T > &v)