diff --git a/pub/lib/plot.cpp b/pub/lib/plot.cpp index 51f1343026e0e3c9e02a6bca03dba76ddc660da0..318c7e2ccce8a52092e769f907b89d1ed57bfb29 100644 --- a/pub/lib/plot.cpp +++ b/pub/lib/plot.cpp @@ -555,8 +555,8 @@ namespace { plot->X.set_limits(xinf, xsup); if (!plot->Z.finite()) plot->Z.set_limits(zlim.front(), zlim.back()); - if (plot->Y.logflag && !(std::isfinite(yinf) && std::isfinite(ysup))) - throw "No nonzero y values"; + if (!(std::isfinite(yinf) && std::isfinite(ysup))) + throw "No valid y values"; if (!plot->Y.finite()) plot->Y.set_limits(yinf-1e-4*std::abs(yinf), ysup+1e-4*std::abs(ysup)); // plot diff --git a/pub/plot/axis.cpp b/pub/plot/axis.cpp index 01a50438a7f894c204bbd94d4f634c87480eb7c1..d85e1fb581a0db9b9cee114d7e8c897a1cdb6636 100644 --- a/pub/plot/axis.cpp +++ b/pub/plot/axis.cpp @@ -11,6 +11,7 @@ #include <iomanip> #include <iostream> #include <vector> +#include <boost/format.hpp> #include "../readplus/macro.hpp" #include "../trivia/math.hpp" @@ -21,6 +22,7 @@ using std::string; using std::vector; using std::cout; +using boost::format; #define S(a) triv::strg((a)) @@ -62,7 +64,7 @@ void CAxis::ask_and_set(const string& quest) { for (;;) { double inf_in, sup_in; - string resp1 = NMacro::readwd(quest + " [" + str() + "] ? "); + string resp1 = NMacro::readwd(quest + " [" + to_s() + "] ? "); if (resp1 == "\\q") { throw S("user escape to main menu"); } else if (resp1 == "") { @@ -82,7 +84,7 @@ void CAxis::ask_and_set(const string& quest) " 0.1 \\ let upper bound unchanged\n" " * redetermine bounds from data\n" "just press ENTER to let present range unchanged [" - << str() << "]\n"; + << to_s() << "]\n"; continue; } if (logflag && inf_in <= 0) { @@ -277,7 +279,7 @@ void CAxis::set_xgrid(vector<double>& x, int n) const //! Returns string representation of plot range. -string CAxis::str() const +string CAxis::to_s() const { if (inf == -INFINITY || sup == +INFINITY) return "*"; @@ -369,7 +371,8 @@ void CAxis::calc_lintacks(vector<double>& Tacks, int& ntpt, double& dtack) const double drange = dhig-dlow; int nTacks = drange/dtack + 1.5; if (nTacks<2) - throw "BUG: calc_lintacks -> nTacks<2"; + throw str(format("BUG in calc_lintacks: nTacks<2 for inf=%g sup=%g dtack=%g low=%g hig=%g") + % inf % sup % dtack % dlow % dhig); for (int i=0; i<nTacks; ++i) { double d = (i*dhig + (nTacks-1-i)*dlow)/(nTacks-1); if (std::abs(d)<1e-15*drange) diff --git a/pub/plot/axis.hpp b/pub/plot/axis.hpp index e01fbc45c71b8deff4a01396d168f81b6276b9d9..e4422be3b4567adc0167d6308263555e77475fc3 100644 --- a/pub/plot/axis.hpp +++ b/pub/plot/axis.hpp @@ -33,7 +33,7 @@ public: void set_rounded_limits(double _inf, double _sup); void ask_and_set(const std::string& quest); - std::string str() const; + std::string to_s() const; std::string info() const; bool finite() const; bool contains(double val) const; diff --git a/pub/plot/ps_plotter.cpp b/pub/plot/ps_plotter.cpp index caf204fa120e8cef35256f161fccbe4c916da932..1e63ea0ecd605644059d2aa233a7ec95f7820d92 100644 --- a/pub/plot/ps_plotter.cpp +++ b/pub/plot/ps_plotter.cpp @@ -205,7 +205,7 @@ namespace { { string ret = "% " + A->name + " axis:\n"; if (A->logflag && A->inf <= 0) - throw "BUG: log incompatible with limits " + A->str(); + throw "BUG: log incompatible with limits " + A->to_s(); ret += ps_ticktack(A); return ret; } diff --git a/pub/trivia/vector_ops.cpp b/pub/trivia/vector_ops.cpp index 49a0d6b6c27a962b103c798dff63a23286debdcd..ed77e9efc9ab24e7003cf3bf8010a46b8622b4d0 100644 --- a/pub/trivia/vector_ops.cpp +++ b/pub/trivia/vector_ops.cpp @@ -168,14 +168,32 @@ std::string triv::indices_to_s(const vector<int>& v) return ret; } +//! Determines minimal and maximal value in vector v. +//! Results must be tested for finiteness. +void triv::getMinMax(const std::vector<double>& v, double& minval, double&maxval) +{ + if (v.size()==0) + throw "BUG: attempt to determine min and max of empty vector"; + minval = +INFINITY; + maxval = -INFINITY; + for (auto t = v.begin(); t<v.end(); ++t) { + if (!std::isfinite(*t)) + continue; + minval = std::min(minval, *t); + maxval = std::max(maxval, *t); + } +} + //! Determines minimal positive value and maximal value in vector v. //! Results must be tested for finiteness. void triv::getPosminMax(const std::vector<double>& v, double& minval, double&maxval) { + if (v.size()==0) + throw "BUG: attempt to determine min and max of empty vector"; minval = +INFINITY; maxval = -INFINITY; for (auto t = v.begin(); t<v.end(); ++t) { - if (*t<=0) + if (!std::isfinite(*t) || *t<=0) continue; minval = std::min(minval, *t); maxval = std::max(maxval, *t); diff --git a/pub/trivia/vector_ops.hpp b/pub/trivia/vector_ops.hpp index b47e28bb9b59d5d8dc138ec66e04e334ed9b89c4..c3f2e2df6250337bc7b17cb07667f5e5c35bf03a 100644 --- a/pub/trivia/vector_ops.hpp +++ b/pub/trivia/vector_ops.hpp @@ -25,7 +25,7 @@ namespace triv void increment_indices(std::vector<int>& v, int incr, int siz); std::string indices_to_s(const std::vector<int>& v); - template <class T> void getMinMax(const std::vector<T>& v, T& minval, T&maxval); + void getMinMax(const std::vector<double>& v, double& minval, double&maxval); void getPosminMax(const std::vector<double>& v, double& minval, double&maxval); template <class T> bool contains(const std::vector<T>& v, const T e); template <class T, class Pred> std::vector<T> merge_sorted( @@ -35,19 +35,6 @@ namespace triv // Template implementation //************************************************************************************************** - template <class T> - void getMinMax(const std::vector<T>& v, T& minval, T&maxval) - { - if (v.size()==0) - throw "BUG: attempt to determine min and max of empty vector"; - minval = v.front(); - maxval = v.front(); - for (auto t = v.begin()+1; t<v.end(); ++t) { - minval = std::min(minval, *t); - maxval = std::max(maxval, *t); - } - } - template <class T> bool contains(const std::vector<T>& v, const T e) {