1 /** @file eval_helper.cpp
2 @package snark14Display
3 @author Bruno M. Carvalho and Deniz Sarioz
4 licensed under (open-source) QPL v1.0
5 which accompanies this distribution in the file QPL
8 /** @name eval_helper.hpp
11 @package snark14Display
12 @purpose to help snark14Display in the interpretation of eval files, broadly speaking.
13 @author deniz, who realizes after 1200 lines that a lot of space and (programmer) time
14 could have been saved by enumerated-typing of global resolution measure field names
16 @description this header file contains the implementation of classes, starting with:
17 phantomeas: phantom measurement structure
18 globmeas : global resolution measurement structure
19 PBPmeas : point-by-point error measurement structure
20 (1-line measurements in eval: glorified structures with constructors that take "measline_t" (char*))
22 phantomeas globmeas PBPmeas
24 | globmeaset PBPmeaset (info from a single execution of a single algorithm in a call to EVALUATE)
26 | eval_execution (info from a single call to EVALUATE, that includes calls like "EVALUATE BOTH")
29 eval_exec_set (info from all EVALUATE calls of a snark14 run)
31 You can read "is member of" relationships if you go top down, very intuitive up to abbreviation.
33 Attempted improvements to Bruno's version (which was < 1.0):
34 - no more segmentation faults due to eval
35 - dynamic parsing and allocation for 'residual', an optional field of a globmeas, that can vary WITHIN a globmeaset
36 - variable number of fields in a point-by-point measurement structure (PBPmeas)
37 - support for multiple EVALUATE calls in snark14
38 - extrema calculated dynamically, "recursively"
41 - the number of fields of all PBPmeas structures is uniquely determined by the snark14 produced eval file
42 deniz thinks it is proportional to the logarithm of phantom/reconstruction images' number-of-pixels-on-side
43 - phantomeas can be tied to eval_exec_set due to multiplicity, since there is exactly one phantom in each snark run,
44 but it can occur with OR without residual, in the same.
47 - plot phantomeas with globals.
62 #include "eval_helper.hpp"
63 #include "displaylines.hpp"
64 #include "chooseRanges.hpp"
66 #include "line_real_t.hpp"
69 // typedef char* measline_t;
70 // typedef char* execname_t;
72 // global (resolution) measurements go into global measurement sets
73 // point-by-point resolution measurements go into PBP measurement sets
74 // an evaluation can have
76 /** each phantomeas corresponds to a line of phantom stats in the eval file */
88 /** phantomeas 1-arg constructor */
89 phantomeas(measline_t line) {
90 //0 625 0.3622 0.1860 0.4312
91 //1 4225 0.3574 0.2795 0.5287 1216.8134
95 std::sscanf(line, "%d %d %lg %lg %lg %lg %lg",
96 ®ion, &area, &average, &variance, &stddev, &resid, &kullback);
97 if (numthingsread < 5)
98 throw std::invalid_argument("line in phantomeas constructor must have at least 5 numeric fields");
99 if (numthingsread == 5) {
102 } else if (numthingsread == 6) {
104 residualp = new double;
106 } else if (numthingsread == 7) {
107 residualp = new double;
109 kullbackp = new double;
110 *kullbackp = kullback;
111 } else throw std::logic_error("Something very interesting is wrong in phantomeas constructor");
112 } // --phantomeas 1-arg ctor
114 /** phantomeas ("deep") copy ctor */
115 phantomeas(const phantomeas& p) {
118 variance = p. variance;
121 residualp = new double;
122 *residualp = *(p.residualp);
123 } else residualp = 0;
125 kullbackp = new double;
126 *kullbackp = *(p.kullbackp);
127 } else kullbackp = 0;
128 } // --phantomeas::operator=
130 /** phantomeas deep-copying assignment operator */
131 phantomeas & operator=(const phantomeas& p) {
132 std::cout << "in phantomeas deep assignment operator!" << std::endl;
133 if (this == &p) return *this; // Gracefully handle self assignment
136 variance = p. variance;
139 residualp = new double;
140 *residualp = *(p.residualp);
141 } else residualp = 0;
143 kullbackp = new double;
144 *kullbackp = *(p.kullbackp);
145 } else kullbackp = 0;
147 } // --phantomeas::operator=
149 int getRegion() const {
152 // int getArea() const { return area; }
154 double getAverage() const {
158 double getVariance() const {
162 double getStddev() const {
166 bool hasResidual() const {
167 return (0 != residualp);
170 bool hasKullback() const {
171 return (0 != kullbackp);
174 /** getResidual() should not be called without calling hasResidual() */
175 double getResidual() { // defensive programming
177 throw std::logic_error("called phantomeas::getResidual() without calling hasResidual() where there is no residual");
182 /** getKullback() should not be called without calling hasKullback() */
183 double getKullback() { // defensive programming
185 throw std::logic_error("called phantomeas::getKullback() without calling hasKullback() where there is no KL distance");
190 void setNewResidual(double res) {
191 residualp = new double;
195 void setNewKullback(double kld) {
196 kullbackp = new double;
200 double get(globalYVar_t globalYVar) {
201 switch (globalYVar) {
213 return getResidual();
216 return getKullback();
218 // it is likely for this to be called with, say, distance, which phantom has none
220 // negative value ought to be be ignored by callee
222 } // phantomeas::get()
224 /** show routine for phantom, for debug */
226 std::cout << "> Phantom:" << std::endl;
227 std::cout << "region average variance stddev";
228 if (hasResidual()) std::cout << " residual";
229 if (hasKullback()) std::cout << " KL distance";
230 std::cout << std::endl;
231 std::cout << region << " " << average << " " << variance << " " << stddev;
232 if (hasResidual()) std::cout << " " << getResidual();
233 if (hasKullback()) std::cout << " " << getKullback();
234 std::cout << std::endl;
235 std::cout << "< done showing phantom" << std::endl;
239 // std::cout << "in phantomeas destructor!" << std::endl;
240 if (residualp) delete residualp;
241 if (kullbackp) delete kullbackp;
243 }; // --class phantomeas
245 /** a globmeas corresponds to one line of global resolution stats in the eval file */
247 // algname now in globmeaset
248 int iter; // some iterations might be missing from eval file => not always 1..n
255 double* residualp; // uninitialized if no residual
256 double* kullbackp; // uninitialized if no kl distance
257 static unsigned NEXT_GMID;
259 // setfields(int iter, int area, double average, double distance
262 globmeas(measline_t line) {
264 // 1 4225 0.3850 0.8711 0.8927 0.0122 0.1104 9756.9313
265 // char *line2 = " 1 4225 0.3850 0.8711 0.8927 0.0122 0.1104 9756.9313";
266 // char *line2 = " 1 4225 0.3850 0.8711 0.8927 0.0122 0.1104 ";
270 std::sscanf(line, "%d %d %lg %lg %lg %lg %lg %lg %lg",
271 &iter, &area, &average, &distance, &relerr, &variance, &stddev, &resid, &kldis);
272 if (numthingsread < 7)
273 throw std::invalid_argument("line in globmeas constructor must have at least 7 numeric fields");
274 if (numthingsread == 7) {
277 } else if (numthingsread == 8) {
278 residualp = new double;
281 } else if (numthingsread == 9) {
282 residualp = new double;
284 kullbackp = new double;
286 } else throw std::logic_error("Something very interesting is wrong in globmeas constructor");
287 } // --globmeas 1-arg ctor
289 /** globmeas deep copy constructor */
290 globmeas(const globmeas& g) {
291 if (std::verbose >= 5) std::cout << "In deep copy constructor with rhs GMID " << g.getGMID() << std::endl;
296 distance = g.distance;
298 variance = g. variance;
301 residualp = new double;
302 *residualp = *(g.residualp);
303 } else residualp = 0;
305 kullbackp = new double;
306 *kullbackp = *(g.kullbackp);
307 } else kullbackp = 0;
308 } // --globmeas copy ctor
310 unsigned getGMID() const {
311 return static_cast<unsigned> (GMID);
314 /** globmeas deep-copying assignment operator */
315 globmeas & operator=(const globmeas& g) {
316 if (std::verbose >= 5) std::cout << "In globmeas operator= with rhs GMID " << g.getGMID() << std::endl;
317 if (this == &g) return *this; // Gracefully handle self assignment
322 distance = g.distance;
324 variance = g. variance;
327 residualp = new double;
328 *residualp = *(g.residualp);
329 } else residualp = 0;
331 kullbackp = new double;
332 *kullbackp = *(g.kullbackp);
333 } else kullbackp = 0;
335 } // --globmeas::operator=
337 /** globmeas functions that 'get' fields */
338 int getIter() const {
341 // int getArea() const { return area; }
343 double getAverage() const {
347 double getDistance() const {
351 double getRelerr() const {
355 double getVariance() const {
359 double getStddev() const {
363 bool hasResidual() const {
364 return (0 != residualp);
367 bool hasKullback() const {
368 return (0 != kullbackp);
371 double getResidual() const {
373 throw std::logic_error("called getResidual without calling hasResidual() where there is no residual");
378 double getKullback() const {
380 throw std::logic_error("called getKullback without calling hasKullback() where there is no kl distance");
385 /** globmeas::show_all() is a debug routine to show all fields of a single global measurement of an iteration */
391 std::cout << average;
393 std::cout << distance;
397 std::cout << variance;
402 std::cout << getResidual();
406 std::cout << getKullback();
408 std::cout << std::endl;
409 } // globmeas::show_all()
412 if (0 != residualp) {
413 if (std::verbose >= 5) std::cout << "Residualp was nonzero, residual " << (*residualp) << " ";
416 if (0 != kullbackp) {
417 if (std::verbose >= 5) std::cout << "Kullbackp was nonzero, kl distance " << (*kullbackp) << " ";
420 if (std::verbose >= 5) std::cout << "In globmeas " << GMID << " Dtor" << std::endl;
422 }; // --class globmeas
424 // unsigned globmeas::NEXT_GMID = 0; // class variable initialization
426 /** a globmeaset is the set of global resolution statistics for one execution of an algorithm */
429 // QString execname; // name of the execution
430 // note that the same algorithm can have several executions
431 char algname[5]; // name of the algorithm (3 or 4 letters followed by null terminator)
432 std::deque<globmeas> measurements;
433 // why a deque and not a vector?
434 // --all access is sequential
435 // --regular queue does not allow iterator (i think)
436 // --when you push_back something new, it does not destruct all existing elements, ensuring linear runtime
437 // --can be used a lot like a vector (.size() etc are available)
438 double minAverage, maxAverage, minDistance, maxDistance, minRelerr, maxRelerr;
439 double minVariance, maxVariance, minStddev, maxStddev;
440 double minResidual, maxResidual; // both -1 if no line with residual in the set
441 double minKullback, maxKullback; // both -1 if no line with kl distance in the set
442 // int minArea, maxArea;
443 int minIter, maxIter; // minIter is not necessarily 1
444 static unsigned NEXT_GMSID; // one for all global measurement sets
445 unsigned GMSID; // unique ID for this set
447 bool extrema_calculated;
451 globmeaset(execname_t line) {
452 GMSID = NEXT_GMSID++;
454 extrema_calculated = false;
455 memset(name, 0, 512);
460 static const char *needle = "xecution name:";
461 p = strstr(p, needle);
464 while ((' ' == *p) || ('\t' == *p)) p++;
465 for (int i = 0; (i < 490) && (*p) && ('\n' != *p) && ('\r' != *p); i++) {
469 *q = '\0'; // just to be sure
470 /// std::cout << "exec name in globmeaset is: `" << name << "'" << std::endl;
471 if (std::verbose >= 4) std::cout << "globmeaset " << GMSID << " ctor" << std::endl;
472 } // --globmeaset ctor
474 unsigned getGMSID() const {
478 execname_t getName() {
482 /* void addMeasurement(globmeas& g) { measurements.push_back(g); } */
484 /** globmeaset::addMeasurement() */
485 void addMeasurement(measline_t line) {
487 throw std::logic_error("Must NOT add to globmeaset once complete() is signalled");
489 if (std::verbose >= 6) std::cout << "++ globmeaset::addMeasurement(line)" << std::endl;
491 if (std::verbose >= 6) std::cout << " globmeaset::addMeasurement(line): before push" << std::endl;
492 measurements.push_back(g); // pass by reference, and a copy is made using copy constructor
493 if (std::verbose >= 6) std::cout << "-- globmeaset::addMeasurement(line)" << std::endl;
494 } // --globmeaset::addMeasurement(line)
496 unsigned get_num_measurements() const {
497 return (static_cast<unsigned> (measurements.size()));
500 void addGlobVarLine(line_real_set_t& LRS, globalYVar_t globalYVar) {
501 line_real_t LR(getName());
502 for (std::deque<globmeas>::iterator it = measurements.begin();
503 it != measurements.end(); it++) {
504 switch (globalYVar) {
506 LR.add(it->getIter(), it->getAverage());
509 LR.add(it->getIter(), it->getDistance());
512 LR.add(it->getIter(), it->getRelerr());
515 LR.add(it->getIter(), it->getVariance());
518 LR.add(it->getIter(), it->getStddev());
521 if (it->hasResidual()) {
522 LR.add(it->getIter(), it->getResidual());
525 if (it->hasKullback()) {
526 LR.add(it->getIter(), it->getKullback());
530 std::cerr << "Invalid globalYVar in globmeaset::addGlobVarLine()" << std::endl;
533 if (!LR.empty()) LRS.add(LR);
534 } // --globmeaset::addGlobVarLine()
536 /** globmeaset::complete() invoke to indicate that all elements have been added to this globmeaset */
538 if (std::verbose >= 4)
539 std::cout << "Executing globmeaset::complete()" << std::endl;
540 if (measurements.empty()) {
541 throw std::logic_error("empty globmeaset refused to complete() itself");
544 throw std::logic_error("complete() already signalled for this globmeaset, must NOT signal again.");
546 if (std::verbose >= 5)
547 std::cout << "completed is so far false" << std::endl;
549 if (std::verbose >= 5)
550 std::cout << "completed is now set to true" << std::endl;
551 } // globmeaset::complete()
553 /** globmeaset::isComplete() whether or not this global measurement set has been completed */
554 bool isComplete() const {
556 } // globmeaset::isComplete()
558 /** globmeaset::calculate_extrema() calculates extrema of all measurments by field
559 assumes that 'iter' field is strictly increasing in the order they were added.
560 should be called as either 0-arg or 3-arg */
561 bool calculate_extrema(bool restrict_domain = false, int min_it_arg = 0, int max_it_arg = 0) {
563 throw std::logic_error("Must NOT calculate extrema of globmeaset before complete() is signalled");
565 if (0 == get_num_measurements())
566 throw std::logic_error("Must NOT calculate extrema of empty globmeaset"); // else
568 double curAverage, curDistance, curRelerr, curVariance, curStddev, curResidual, curKullback;
569 minAverage = maxAverage = minDistance = maxDistance = minRelerr = maxRelerr = -1.0;
570 minVariance = maxVariance = minStddev = maxStddev = minResidual = maxResidual = minKullback = maxKullback = -1.0;
571 extrema_calculated = true; // this is intentionally true even if return value is false
573 std::deque<globmeas>::const_iterator it = measurements.begin();
575 if (restrict_domain) {
576 if (min_it_arg > max_it_arg)
577 throw std::invalid_argument("globmeaset::calculate_extrema() called with arguments min>max");
578 while ((it != measurements.end()) && (min_it_arg > (*it).getIter()))
580 if (it == measurements.end())
581 return false; // iterations of this globmeaset are out of requested range
582 maxIter = minIter = (*it).getIter();
584 minIter = (*it).getIter();
585 maxIter = measurements.back().getIter(); // and that's that.
587 // curArea = minArea = maxArea = (*it).getArea();
588 curAverage = minAverage = maxAverage = (*it).getAverage();
589 curDistance = minDistance = maxDistance = (*it).getDistance();
590 curRelerr = minRelerr = maxRelerr = (*it).getRelerr();
591 curVariance = minVariance = maxVariance = (*it).getVariance();
592 curStddev = minStddev = maxStddev = (*it).getStddev();
593 if ((*it).hasResidual()) { // not necessarily true
594 curResidual = minResidual = maxResidual = (*it).getResidual();
596 if ((*it).hasKullback()) { // not necessarily true
597 curKullback = minKullback = maxKullback = (*it).getKullback();
600 for (; it != measurements.end(); it++) {
601 if (restrict_domain) {
602 if (max_it_arg < (*it).getIter())
604 else maxIter = (*it).getIter();
606 // curArea = (*it).getArea();
607 curAverage = (*it).getAverage();
608 curDistance = (*it).getDistance();
609 curRelerr = (*it).getRelerr();
610 curVariance = (*it).getVariance();
611 curStddev = (*it).getStddev();
612 // if(curArea < minArea) minArea = curArea;
613 if (curAverage < minAverage) minAverage = curAverage;
614 if (curDistance < minDistance) minDistance = curDistance;
615 if (curRelerr < minRelerr) minRelerr = curRelerr;
616 if (curVariance < minVariance) minVariance = curVariance;
617 if (curStddev < minStddev) minStddev = curStddev;
619 // if(curArea > maxArea) maxArea = curArea;
620 if (curAverage > maxAverage) maxAverage = curAverage;
621 if (curDistance > maxDistance) maxDistance = curDistance;
622 if (curRelerr > maxRelerr) maxRelerr = curRelerr;
623 if (curVariance > maxVariance) maxVariance = curVariance;
624 if (curStddev > maxStddev) maxStddev = curStddev;
626 if ((*it).hasResidual()) {
627 curResidual = (*it).getResidual();
628 if (minResidual < 0) { // this is the first residual in measurements
629 minResidual = maxResidual = curResidual;
631 if (curResidual < minResidual) minResidual = curResidual;
632 if (curResidual > maxResidual) maxResidual = curResidual;
635 if ((*it).hasKullback()) {
636 curKullback = (*it).getKullback();
637 if (minKullback < 0) { // this is the first kl distance in measurements
638 minKullback = maxKullback = curKullback;
640 if (curKullback < minKullback) minKullback = curKullback;
641 if (curKullback > maxKullback) maxKullback = curKullback;
644 } // --foreach measurement
646 } // --globmeaset::calculate_extrema()
648 /** these functions return appropriate domain extrema from a single execution of an algorithm */
650 if (!extrema_calculated)
653 } // globmeaset::getMinIter()
656 if (!extrema_calculated)
659 } // globmeaset::getMaxIter()
661 /** these functions return appropriate range extrema from a single execution of an algorithm
662 All will calculate_extrema() with no-args (entire domain) if
663 it has never been called (with any set of arguments, and for a valid set)
665 double getMinAverage() {
666 if (!extrema_calculated)
669 } // globmeaset::getMinAvarage()
671 double getMaxAverage() {
672 if (!extrema_calculated)
677 double getMinDistance() {
678 if (extrema_calculated || calculate_extrema())
683 double getMaxDistance() {
684 if (extrema_calculated || calculate_extrema())
689 double getMinRelerr() {
690 if (extrema_calculated || calculate_extrema())
695 double getMaxRelerr() {
696 if (extrema_calculated || calculate_extrema())
701 double getMinVariance() {
702 if (extrema_calculated || calculate_extrema())
707 double getMaxVariance() {
708 if (extrema_calculated || calculate_extrema())
713 double getMinStddev() {
714 if (extrema_calculated || calculate_extrema())
719 double getMaxStddev() {
720 if (extrema_calculated || calculate_extrema())
725 /* both of these return -1.0 if no residual */
726 double getMinResidual() {
727 if (extrema_calculated || calculate_extrema())
732 double getMinKullback() {
733 if (extrema_calculated || calculate_extrema())
738 double getMaxResidual() {
739 if (extrema_calculated || calculate_extrema())
744 double getMaxKullback() {
745 if (extrema_calculated || calculate_extrema())
750 bool hasResidual() { // hack: think about whether this actually works
751 if (extrema_calculated || calculate_extrema())
752 return (-0.1 < minResidual);
756 bool hasKullback() { // hack: think about whether this actually works
757 if (extrema_calculated || calculate_extrema())
758 return (-0.1 < minKullback);
762 /** globmeaset::show_all() shows all members of this global measurement set */
765 throw std::logic_error("Must NOT show_all globmeaset before complete() is signalled");
767 for (std::deque<globmeas>::iterator mit = measurements.begin();
768 mit != measurements.end(); mit++) {
771 } // --globmeaset::show_all()
774 if (std::verbose >= 4)
775 std::cout << "globmeaset " << GMSID << " Dtor" << std::endl;
777 }; // --class globmeaset
779 // unsigned globmeas::NEXT_GMID = 0; // class variable initialization
781 /** a PBPmeas corresponds to one line of point-by-point statistics in the eval file */
783 // the fields are such that there is no reason for deep copies:
784 // default assignment and copy constructors are fine.
785 // algname now in PBPmeaset
787 std::vector<double> e; // it's imperative that this is something variable
789 static unsigned NEXT_PMID;
791 // pre: line starts with whitespace after algname
792 // pre: line points to a (non-static) buffer
794 PBPmeas(measline_t line) {
795 // read line into iter and the e vector:
796 /// if(std::verbose>=5) std::cout << "In PBPmeas " << (PMID+1) << " ctor" << std::endl;
799 if (std::verbose >= 6) std::cout << "++ PBPmeas ctor(line)" << std::endl;
800 // std::cout << "PBPmeas beginning--Line is:" << std::endl << line << std::endl;
802 while (((*p) == ' ') || ((*p) == '\t')) p++; // death to strtok!
803 if (1 != std::sscanf(p, "%d", &iter))
804 throw std::invalid_argument("line in PBPmeas ctor must start with \
806 while ((*p) && ((*p) != ' ') && ((*p) != '\t')) p++; // skip iter
807 while (((*p) == ' ') || ((*p) == '\t')) p++; // skip whitespace after iter
808 while ((*p) && ((*p) != '\n') && ((*p) != '\r')) { // read in each double (might have to find out EOF symbol)
809 if (1 == std::sscanf(p, "%lg", &myDouble)) {
810 e.push_back(myDouble);
812 while ((*p) && ((*p) != ' ') && ((*p) != '\t')) p++; // skip double
813 while (((*p) == ' ') || ((*p) == '\t')) p++; // skip whitespace after double
816 std::cout << "e is empty... Line is:" << std::endl << line << std::endl;
817 throw std::invalid_argument("line arg to PBPmeas ctor must have \
818 at least 1 floating point measurement");
821 if (std::verbose >= 6) std::cout << "-- PBPmeas ctor(line)" << std::endl;
824 int getIter() const {
828 unsigned get_num_Es() const {
829 return ( static_cast<unsigned> (e.size()));
830 } // --PBPmeas::get_num_Es()
832 double get_E(unsigned ind) {
834 throw std::invalid_argument("Bad index to PBPmeas::get_E()");
837 } // PBPmeas::get_E()
840 std::cout << getIter() << " ";
841 for (std::vector<double>::const_iterator it = e.begin();
842 it != e.end(); it++) {
843 std::cout << (*it) << " ";
845 std::cout << std::endl;
846 } // --PBPmeas::show_all()
849 if (std::verbose >= 5) std::cout << "In PBPmeas " << PMID << " Dtor" << std::endl;
851 }; // --class PBPmeas
853 // unsigned PBPmeas::NEXT_PMID = 0; // class variable initialization
855 /** a PBPmeaset is the set of point-by-point statistics for one execution of an algorithm */
857 char algname[5]; // name of the algorithm (4 letters) (not even necessary)
858 char name[512]; // description of the algorithm
860 // QString execname; // name of the execution:
861 // snark can execute same algorithm many times with different parameters
862 std::deque<PBPmeas> measurements; // deque is efficient for adding at end and iterating through
863 std::vector<double> minima; // wrappers around simple built-in types: assume efficient
864 std::vector<double> maxima;
865 int minIter, maxIter;
867 static unsigned NEXT_PMSID;
870 bool extrema_calculated;
873 PBPmeaset(execname_t line) {
874 for (int i = 0; i < 4; i++) algname[i] = 'X';
875 algname[4] = '\0'; // just in case
876 PMSID = NEXT_PMSID++;
878 minIter = maxIter = -1;
880 extrema_calculated = false;
882 memset(name, 0, 512);
886 static const char *needle = "xecution name:";
887 p = strstr(p, needle);
890 while ((' ' == *p) || ('\t' == *p)) p++;
891 for (int i = 0; (i < 490) && (*p) && ('\n' != *p) && ('\r' != *p); i++) {
895 *q = '\0'; // just to be sure
896 /// std::cout << "exec name in PBPmeaset is: `" << name << "'" << std::endl;
898 if (std::verbose >= 4) std::cout << "PBPmeaset " << PMSID << " ctor" << std::endl;
899 } // --PBPmeaset ctor
902 return &(algname[0]);
904 // so this is a bit baroque... I guess we won't need the 4-letter algnames after all.
906 execname_t getName() {
910 /** PBPmeaset::skip_algname() */
911 measline_t skip_algname(measline_t line) {
912 // my overkill implementation of strtok functionality (why? why?)
914 // std::cout<< "Input to skip_algname: " << std::endl << line << std::endl;;
916 while ((' ' == (*cursor)) || ('\t' == (*cursor)))
918 if ((!(*cursor)) || !((*cursor) >= 'A') && ((*cursor) <= 'Z'))
919 throw std::invalid_argument("bad line passed into PBPmeaset::skip_algname()");
920 while ((*cursor) && ((*cursor) >= 'A') && ((*cursor) <= 'Z'))
922 // std::cout<< "Returning from skip_algname: " << std::endl << cursor << std::endl;;
926 /** PBPmeaset::set_algname() */
927 measline_t set_algname(measline_t line) {
930 while ((' ' == *cursor) || ('\t' == *cursor)) cursor++;
931 if (!(*cursor >= 'A') && (*cursor <= 'Z'))
932 throw std::invalid_argument("bad line passed into PBPmeaset::set_algname()");
933 for (int i = 0; i < 4; i++)
934 algname[i] = *cursor++;
935 if ((algname[3] == '\t') || (algname[3] == ' ')) // alg is ART
937 algname[4] = '\0'; // defensive
941 // void addMeasurement(PBPmeas& p) {
943 // throw std::logic_error("Must NOT add to PBPmeaset once complete() is signalled");
944 // measurements.push_back(p);
947 /** PBPmeaset::addMeasurement() */
948 void addMeasurement(measline_t line) {
949 measline_t cursor = line;
951 throw std::logic_error("Must NOT add to PBPmeaset once complete() is signalled");
952 if (measurements.empty()) // if this is the first line
953 cursor = set_algname(cursor);
955 // std::cout<< "cursor:" << cursor << std::endl;
956 cursor = skip_algname(cursor);
957 // std::cout<< "cursor:" << cursor << std::endl;
960 measurements.push_back(p);
964 if (measurements.empty()) {
965 throw std::logic_error("empty PBPmeaset refused to complete() itself");
969 throw std::logic_error("complete() already signalled for this PBPmeaset, must NOT signal again.");
974 /** PBPmeaset::isComplete() whether or not this point-by-point measurement set has been completed */
975 bool isComplete() const {
977 } // PBPmeaset::isComplete()
979 /** ++PBPmeaset::get_num_Es() returns number of fields */
980 unsigned get_num_Es() {
981 if (measurements.empty()) {
984 num_Es = measurements[0].get_num_Es(); // guaranteed to be the same in all
987 } // --PBPmeaset::get_num_Es()
989 /** PBPmeaset::calculate_extrema(), to be called as 0-arg or 3-arg
990 returns true if input iteration range intersects with data's iteration range ("data domain")
991 makes the assumption that iterations increase in a PBPmeaset (such as (*this) )
993 bool calculate_extrema(bool restrict_domain = false, int min_it_arg = 0, int max_it_arg = 0) {
995 throw std::logic_error("Must NOT calculate extrema of PBPmeaset before complete() is signalled");
997 if (0 == get_num_Es())
998 throw std::logic_error("CANNOT calculate anything for PBPmeaset with no entries!");
1000 extrema_calculated = true; // intentionally set this to true even if return false
1001 std::deque<PBPmeas>::iterator it = measurements.begin();
1002 if (restrict_domain) {
1003 while ((it != measurements.end()) && (min_it_arg > (*it).getIter()))
1005 if (it == measurements.end())
1008 minIter = maxIter = (*it).getIter();
1009 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1010 double cur_E = (*it).get_E(myInd);
1011 minima.push_back(cur_E);
1012 maxima.push_back(cur_E);
1015 for (; it != measurements.end(); it++) { // executes 0 or more times
1016 if (restrict_domain && (max_it_arg < (*it).getIter()))
1018 maxIter = (*it).getIter(); // last of the small ones
1019 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1020 double cur_E = (*it).get_E(myInd);
1021 if (cur_E < minima[myInd]) minima[myInd] = cur_E;
1022 if (cur_E > maxima[myInd]) maxima[myInd] = cur_E;
1026 } // --PBPmeaset::calculate_extrema()
1030 throw std::logic_error("getMinIter() MUST not be called before complete() is signalled in PBPmeaset");
1031 if (extrema_calculated) // || calculate_extrema())
1032 return minIter; ///// control shouldn't reach the next line, just defensiveness
1034 } // --PBPmeaset::getMinIter()
1038 throw std::logic_error("getMaxIter() MUST not be called before complete() is signalled in PBPmeaset");
1039 if (extrema_calculated) // || calculate_extrema())
1042 } // --PBPmeaset::getMaxIter()
1044 double getMinE(unsigned ind) {
1046 throw std::logic_error("getMinE() MUST not be called before complete() is signalled in PBPmeaset");
1048 if (!extrema_calculated)
1049 calculate_extrema(); // which calculates num_Es
1051 throw std::logic_error("num_Es cannot be 0 in PBPmeaset::getMinE()");
1054 throw std::invalid_argument("bad parameter to getMinE");
1057 } // --PBPmeaset::getMinE()
1059 double getMaxE(unsigned ind) {
1061 throw std::logic_error("getMaxE() MUST not be called before complete() is signalled in PBPmeaset");
1063 if (!extrema_calculated)
1064 calculate_extrema(); // which calculates num_Es
1066 throw std::logic_error("num_Es cannot be 0 in PBPmeaset::getMinE()");
1069 throw std::invalid_argument("bad parameter to getMaxE");
1072 } // --PBPmeaset::getMaxE()
1074 /** shows the extrema of a PBP measurement set (due to a single execution of a single algorithm) */
1075 void show_extrema() {
1077 throw std::logic_error("Must NOT show extrema of PBPmeaset before complete() is signalled");
1078 if (!extrema_calculated) calculate_extrema(); // the order matters here
1079 if (minima.size() != maxima.size()) // won't really happen
1080 throw std::logic_error("minima and maxima of a PBPmeaset MUST have same size in show_extrema()");
1081 for (unsigned i = 0; i < minima.size(); i++) {
1082 std::cout << minima[i] << " " << maxima[i] << std::endl;
1084 } // --PBPmeaset::show_extrema()
1086 /** shows all measurements of a measurement set (for debugging) */
1089 throw std::logic_error("Must NOT show_all for PBPmeaset before complete() is signalled");
1090 for (std::deque<PBPmeas>::iterator mit = measurements.begin();
1091 mit != measurements.end(); mit++) {
1094 } // --PBPmeaset::show_all()
1096 void addPBPVarLine(line_real_set_t& LRS, unsigned PBPYVar) {
1097 line_real_t LR(getName());
1098 for (std::deque<PBPmeas>::iterator it = measurements.begin();
1099 it != measurements.end(); it++) {
1100 LR.add(it->getIter(), it->get_E(PBPYVar));
1102 if (!LR.empty()) LRS.add(LR);
1103 } // --PBPmeset::addPBPVarLine()
1105 /** PBPmeaset destructor */
1107 if (std::verbose >= 4) std::cout << "PBPmeaset " << PMSID << " Dtor" << std::endl;
1109 }; // --class PBPmeaset
1111 // unsigned PBPmeaset::NEXT_PMSID = 0; // class variable initialization
1113 /** contains PBPmeasets and globmeasets that appear in a single EVALUATE result */
1114 class eval_execution {
1115 std::deque<globmeaset> globmeasets;
1116 std::deque<PBPmeaset> PBPmeasets;
1118 bool global_extrema_calculated;
1119 bool PBP_extrema_calculated;
1120 // extrama... none calculated until eval_execution is 'completed', all calculated at once.
1121 // first the global extrema
1122 int minIter, maxIter;
1123 double minAverage, maxAverage, minDistance, maxDistance, minRelerr, maxRelerr;
1124 double minVariance, maxVariance, minStddev, maxStddev, minResidual, maxResidual, minKullback, maxKullback;
1125 // then the PBP extrema...
1126 std::vector<double> PBP_minima; // minima and maxima of each E(0)..E(N-1), N not varying within an eval file.
1127 std::vector<double> PBP_maxima; // calculated over ALL algorithm execution/iterations in this EVALUATE
1128 unsigned num_Es; // 'N' in comment above
1129 phantomeas* phantomeasp; // will be added directly...
1130 // e.g., PBP_minima[2] is the minimum value of all E(2) in all PBPmeasets.
1131 static unsigned NEXT_EEID;
1138 completed = global_extrema_calculated = PBP_extrema_calculated = false;
1141 minResidual = maxResidual = -1.0; // must initialize to negative value
1142 minKullback = maxKullback = -1.0;
1143 memset(name, 0, 512);
1144 } // --eval_execution ctor
1146 eval_execution(execname_t line) {
1147 /// std::cout << "++eval_execution::eval_execution(), line is " << line;
1149 completed = global_extrema_calculated = PBP_extrema_calculated = false;
1152 minResidual = maxResidual = -1.0; // must initialize to negative value
1153 minKullback = maxKullback = -1.0; // must initialize to negative value
1157 static const char *needle = "valuation name:";
1158 p = strstr(p, needle); // just in case of preceding whitespace
1159 memset(q, 0, 512); // sort of gratuitous
1162 p += strlen(needle);
1163 while ((' ' == *p) || ('\t' == *p)) p++;
1164 for (int i = 0; (i < 490) && (*p) && ('\n' != *p) && ('\r' != *p); i++) {
1168 *q = '\0'; // just to be sure
1169 /// std::cout << "--eval_execution::eval_execution(), name is " << (&(name[0])) << std::endl;
1170 } // --eval_execution ctor
1172 execname_t getName() {
1173 return static_cast<execname_t> (&(name[0]));
1174 } // --eval_execution::getName()
1176 void set_phantom(phantomeas* phanp) { // by pointer!!!
1177 phantomeasp = phanp;
1178 } // eval_execution::set_phantom()
1180 void new_globmeaset(execname_t line) {
1181 if (std::verbose >= 3)
1182 std::cout << "++ eval_execution::new_globmeaset()" << std::endl;
1184 throw std::logic_error("eval_execution::complete() already signalled in eval_execution::new_globmeaset().");
1186 if (!globmeasets.empty()) {
1187 globmeasets.back().complete();
1190 globmeasets.push_back(g);
1191 if (std::verbose >= 3) std::cout << "-- eval_execution::new_globmeaset()" << std::endl;
1192 } // eval_execution::new_globmeaset()
1194 void add_to_globmeaset(measline_t line) {
1195 if (std::verbose >= 4)
1196 std::cout << "++ eval_execution::add_to_globmeaset(line)" << std::endl;
1198 throw std::logic_error("eval_execution::complete() already signalled in eval_execution::add_to_globmeaset().");
1201 throw std::logic_error("attempting to add to globmeaset of eval_execution where none exist");
1202 globmeasets.back().addMeasurement(line);
1203 if (std::verbose >= 4)
1204 std::cout << "-- eval_execution::add_to_globmeaset(line)" << std::endl;
1207 void new_PBPmeaset(execname_t line) {
1209 throw std::logic_error("eval_execution::complete() already signalled in eval_execution::new_PBPmeaset().");
1211 if (!PBPmeasets.empty()) {
1212 PBPmeasets.back().complete();
1215 PBPmeasets.push_back(p);
1216 } // --eval_execution::new_PBPmeaset()
1218 void add_to_PBPmeaset(measline_t line) {
1220 throw std::logic_error("eval_execution::complete() already signalled in eval_execution::add_to_PBPmeaset().");
1223 throw std::logic_error("attempting to add to PBPmeaset of eval execution where none exist");
1225 PBPmeasets.back().addMeasurement(line); // add measurement to last PBPmeaset
1226 } // --eval_execution::add_to_PBPmeaset()
1228 unsigned get_num_globmeasets() const {
1229 return static_cast<unsigned> (globmeasets.size());
1232 unsigned get_num_PBPmeasets() const {
1233 return static_cast<unsigned> (PBPmeasets.size());
1236 bool hasGlobal() const {
1237 return (!(globmeasets.empty()));
1238 } // eval_execution::hasGlobal()
1240 bool hasPBP() const {
1241 return (!(PBPmeasets.empty()));
1242 } // eval_execution::hasPBP()
1244 /** Tell this eval_execution object that no more entries will be added to it, and calculations may begin */
1245 void complete() { // verb
1246 if ((!hasGlobal()) && (!hasPBP()))
1247 throw std::logic_error("eval_execution with NOTHING in it was asked to complete() itself!");
1250 throw std::logic_error("attempt to complete() same eval execution twice!");
1254 if (std::verbose >= 3) std::cout << "calling calculate_global_extrema()" << std::endl;
1255 globmeasets.back().complete();
1256 calculate_global_extrema(); // a good place to do this. (is it?)
1257 if (std::verbose >= 3) std::cout << "returned from calculate_global_extrema()" << std::endl;
1260 PBPmeasets.back().complete();
1261 if (std::verbose >= 3) std::cout << "calling calculate_PBP_extrema()" << std::endl;
1262 calculate_PBP_extrema(); // " " " " " "
1263 if (std::verbose >= 3) std::cout << "returned from calculate_PBP_extrema()" << std::endl;
1265 } // --eval_execution::complete()
1267 /** eval_execution::isComplete()
1268 for debugging--ask the eval_execution object whether it has been told that no more data will be added to it */
1269 bool isComplete() const {
1271 } // --eval_execution::isComplete()
1273 /** eval_execution::calculate_global_extrema()
1274 calculates global extrema of ALL global measurement sets in this EVALUATE execution
1275 called with 0 or 3 args meaningfully: 0-arg means "calculate over ALL data" */
1276 bool calculate_global_extrema(bool restrict_domain = false, int min_it_arg = 0, int max_it_arg = 0) {
1277 /// if(global_extrema_calculated) return false;
1279 throw std::logic_error("Must NOT calculate extrema of globmeaset before complete() is signalled");
1282 throw std::logic_error("Must NOT calculate extrema of empty globmeaset");
1284 std::deque<globmeaset>::iterator it = globmeasets.begin();
1285 // guaranteed to exist and point to an actual globmeaset if control reached here
1286 // skip while current globmeaset's domain does not intersect with input domain
1287 // "allows" to recalculate global extrema regardless
1288 while ((it != globmeasets.end()) &&
1289 !((*it).calculate_extrema(restrict_domain, min_it_arg, max_it_arg))) {
1290 it++; // boolean expression of while has intentional and possibly necessary side effect
1292 if (it == globmeasets.end())
1293 return false; // no globmeaset agrees with domain! unbelievable!
1295 minIter = (*it).getMinIter(); // return value will automagically be right due to
1296 maxIter = (*it).getMaxIter(); // the above globmeaset::calculate_extrema() call (first that succeeded)
1298 minAverage = (*it).getMinAverage();
1299 minDistance = (*it).getMinDistance();
1300 minRelerr = (*it).getMinRelerr();
1301 minVariance = (*it).getMinVariance();
1302 minStddev = (*it).getMinStddev();
1304 maxAverage = (*it).getMaxAverage();
1305 maxDistance = (*it).getMaxDistance();
1306 maxRelerr = (*it).getMaxRelerr();
1307 maxVariance = (*it).getMaxVariance();
1308 maxStddev = (*it).getMaxStddev();
1312 if (minAverage > (tmp = phantomeasp->getAverage())) minAverage = tmp;
1313 else if (maxAverage < tmp) maxAverage = tmp;
1315 if (minVariance > (tmp = phantomeasp->getVariance())) minVariance = tmp;
1316 else if (maxVariance < tmp) maxVariance = tmp;
1318 if (minStddev > (tmp = phantomeasp->getStddev())) minStddev = tmp;
1319 else if (maxStddev < tmp) maxStddev = tmp;
1322 if ((*it).hasResidual()) { // not necessarily true in the first globmeaset
1324 minResidual = (*it).getMinResidual(); // won't be nonnegative
1325 maxResidual = (*it).getMaxResidual(); // won't be nonnegative
1326 if (phantomeasp && (phantomeasp->hasResidual())) {
1327 if (minResidual > (tmp = phantomeasp->getResidual())) minResidual = tmp;
1328 else if (maxResidual < tmp) maxResidual = tmp;
1332 if ((*it).hasKullback()) { // not necessarily true in the first globmeaset
1334 minKullback = (*it).getMinKullback(); // won't be nonnegative
1335 maxKullback = (*it).getMaxKullback(); // won't be nonnegative
1336 if (phantomeasp && (phantomeasp->hasKullback())) {
1337 if (minKullback > (tmp = phantomeasp->getKullback())) minKullback = tmp;
1338 else if (maxKullback < tmp) maxKullback = tmp;
1342 for (; it != globmeasets.end(); it++) {
1343 if (!((*it).calculate_extrema(restrict_domain, min_it_arg, max_it_arg)))
1344 continue; // don't update as long as (*it)'s domain does not match the arguments
1346 if (minIter > (tmpi = ((*it).getMinIter()))) minIter = tmpi;
1347 if (maxIter < (tmpi = ((*it).getMaxIter()))) maxIter = tmpi;
1350 if (minAverage > (tmp = ((*it).getMinAverage()))) minAverage = tmp;
1351 if (minDistance > (tmp = ((*it).getMinDistance()))) minDistance = tmp;
1352 if (minRelerr > (tmp = ((*it).getMinRelerr()))) minRelerr = tmp;
1353 if (minVariance > (tmp = ((*it).getMinVariance()))) minVariance = tmp;
1354 if (minStddev > (tmp = ((*it).getMinStddev()))) minStddev = tmp;
1356 if (maxAverage < (tmp = ((*it).getMaxAverage()))) maxAverage = tmp;
1357 if (maxDistance < (tmp = ((*it).getMaxDistance()))) maxDistance = tmp;
1358 if (maxRelerr < (tmp = ((*it).getMaxRelerr()))) maxRelerr = tmp;
1359 if (maxVariance < (tmp = ((*it).getMaxVariance()))) maxVariance = tmp;
1360 if (maxStddev < (tmp = ((*it).getMaxStddev()))) maxStddev = tmp;
1362 if ((*it).hasResidual()) {
1363 if (minResidual < 0) { // this is the first globmeaset with residual
1364 minResidual = (*it).getMinResidual();
1365 maxResidual = (*it).getMaxResidual();
1366 } else { // we have seen a globmeaset with residual before and now seeing another
1368 if (minResidual > (tmp = ((*it).getMinResidual()))) minResidual = tmp;
1369 if (maxResidual < (tmp = ((*it).getMaxResidual()))) maxResidual = tmp;
1372 if ((*it).hasKullback()) {
1373 if (minKullback < 0) { // this is the first globmeaset with kl distance
1374 minKullback = (*it).getMinKullback();
1375 maxKullback = (*it).getMaxKullback();
1376 } else { // we have seen a globmeaset with kl distance before and now seeing another
1378 if (minKullback > (tmp = ((*it).getMinKullback()))) minKullback = tmp;
1379 if (maxKullback < (tmp = ((*it).getMaxKullback()))) maxKullback = tmp;
1382 } // --foreach globmeaset
1383 global_extrema_calculated = true;
1385 } // --eval_execution::calculate_global_extrema()
1387 /** These require global measurements' extrema to have been calculated */
1388 double getMinAverage() {
1390 throw std::logic_error("hasGlobal() is false in eval_execution::getMinAverage()");
1392 throw std::logic_error("attempt to get info from incomplete eval_execution");
1396 double getMaxAverage() {
1398 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxAverage()");
1400 throw std::logic_error("attempt to get info from incomplete eval_execution");
1404 double getMinDistance() {
1406 throw std::logic_error("hasGlobal() is false in eval_execution::getMinDistance()");
1408 throw std::logic_error("attempt to get info from incomplete eval_execution");
1410 } // --eval_execution::getMinDistance()
1412 double getMaxDistance() {
1414 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxDistance()");
1416 throw std::logic_error("attempt to get info from incomplete eval_execution");
1420 double getMinRelerr() {
1422 throw std::logic_error("hasGlobal() is false in eval_execution::getMinRelerr()");
1424 throw std::logic_error("attempt to get info from incomplete eval_execution");
1428 double getMaxRelerr() {
1430 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxRelerr()");
1432 throw std::logic_error("attempt to get info from incomplete eval_execution");
1434 } // --eval_execution::getMaxRelerr()
1436 double getMinVariance() {
1438 throw std::logic_error("hasGlobal() is false in eval_execution::getMinVariance()");
1440 throw std::logic_error("attempt to get info from incomplete eval_execution");
1444 double getMaxVariance() {
1446 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxVariance()");
1448 throw std::logic_error("attempt to get info from incomplete eval_execution");
1452 double getMinStddev() {
1454 throw std::logic_error("hasGlobal() is false in eval_execution::getMinStddev()");
1456 throw std::logic_error("attempt to get info from incomplete eval_execution");
1460 double getMaxStddev() {
1462 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxStddev()");
1464 throw std::logic_error("attempt to get info from incomplete eval_execution");
1466 } // --eval_execution::getMaxStddev()
1468 bool hasResidual() { // true if some of its globmeasets have some residual entry
1470 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxResidual()");
1472 throw std::logic_error("attempt to get info from incomplete eval_execution");
1473 return (-0.5 < minResidual);
1476 bool hasKullback() { // true if some of its globmeasets have some kl distance entries
1478 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxKullback()");
1480 throw std::logic_error("attempt to get info from incomplete eval_execution");
1481 return (-0.5 < minKullback);
1484 // pre: do NOT call these before calling hasResidual() and making sure it's true
1486 double getMinResidual() {
1488 throw std::logic_error("hasGlobal() is false in eval_execution::getMinResidual()");
1490 throw std::logic_error("hasResidual() is false in eval_execution::getMinResidual()");
1494 double getMinKullback() {
1496 throw std::logic_error("hasGlobal() is false in eval_execution::getMinKullback()");
1498 throw std::logic_error("hasKullback() is false in eval_execution::getMinKullback()");
1502 double getMaxResidual() {
1504 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxResidual()");
1506 throw std::logic_error("hasResidual() is false in eval_execution::getMaxResidual()");
1510 double getMaxKullback() {
1512 throw std::logic_error("hasGlobal() is false in eval_execution::getMaxKullback()");
1514 throw std::logic_error("hasKullback() is false in eval_execution::getMaxKullback()");
1518 /** eval_execution::calculate_PBP_extrema() */
1519 bool calculate_PBP_extrema(bool restrict_domain = false, int min_it_arg = 0, int max_it_arg = 0) {
1520 /// if(PBP_extrema_calculated) return; // not anymore.
1522 if (std::verbose >= 5) std::cout << "++ calculate_PBP_extrema()" << std::endl;
1523 // PBP_minima.resize(0);
1524 // PBP_maxima.resize(0);
1528 std::cerr << "Attempt to calculate_PBP_extrema() before signaling complete() to evaluate_execution";
1529 throw std::logic_error("Attempt to calculate_PBP_extrema() before signaling complete() to evaluate_execution");
1533 std::cerr << "Attempt to calculate_PBP_extrema() when no point-by-point data in this evaluate_execution";
1534 throw std::logic_error("Attempt to calculate_PBP_extrema() when no point-by-point data in this evaluate_execution");
1537 PBP_extrema_calculated = true;
1538 std::deque<PBPmeaset>::iterator it = PBPmeasets.begin();
1539 num_Es = (*it).get_num_Es(); // this is the same throughout the file. can use it even if we chuck the data.
1540 while ((it != PBPmeasets.end()) &&
1541 !((*it).calculate_extrema(restrict_domain, min_it_arg, max_it_arg))) {
1544 if (it == PBPmeasets.end())
1547 minIter = (*it).getMinIter();
1548 maxIter = (*it).getMaxIter();
1549 PBP_minima.resize(num_Es);
1550 PBP_maxima.resize(num_Es);
1551 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1552 PBP_minima[myInd] = (*it).getMinE(myInd);
1553 // PBP_maxima.push_back( (*it).getMaxE(myInd) );
1554 PBP_maxima[myInd] = (*it).getMaxE(myInd);
1557 for (; it != PBPmeasets.end(); it++) {
1558 // empty domain intersection
1559 if (!((*it).calculate_extrema(restrict_domain, min_it_arg, max_it_arg)))
1561 // now: min_it_arg >= (*it).getMinIter() and max_it_arg <= (*it).getMaxIter()
1563 if (minIter > (tmpi = (*it).getMinIter())) minIter = tmpi;
1564 if (maxIter < (tmpi = (*it).getMaxIter())) maxIter = tmpi;
1565 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1566 double curMinE, curMaxE;
1567 if (PBP_minima[myInd] > (curMinE = (*it).getMinE(myInd))) PBP_minima[myInd] = curMinE;
1568 if (PBP_maxima[myInd] < (curMaxE = (*it).getMaxE(myInd))) PBP_maxima[myInd] = curMaxE;
1571 if (std::verbose >= 5) std::cout << "-- calculate_PBP_extrema()" << std::endl;
1573 } // --eval_execution::calculate_PBP_extrema()
1575 /** for getMinIter() and getMaxIter(), global and PBP agree (given same restriction) */
1577 /** however, there is no guarantee that both are present. */
1580 throw std::logic_error("attempt to get info from incomplete eval_execution");
1582 if (!global_extrema_calculated && !PBP_extrema_calculated) {
1584 calculate_global_extrema();
1585 } else if (hasPBP()) {
1586 calculate_PBP_extrema();
1587 } else throw std::logic_error("no Global, no PBP in eval_execution::getMinIter()");
1594 throw std::logic_error("attempt to get info from incomplete eval_execution");
1596 if (!global_extrema_calculated && !PBP_extrema_calculated) {
1598 calculate_global_extrema();
1599 } else if (hasPBP()) {
1600 calculate_PBP_extrema();
1601 } else throw std::logic_error("no Global, no PBP in eval_execution::getMaxIter()");
1606 /** eval_execution::get_num_Es() with possible nasty side effect of recalculating PBP extrema! */
1607 unsigned get_num_Es() {
1609 throw std::logic_error("get_num_Es() MUST not be called before complete() is signalled in eval_execution");
1610 if (!PBP_extrema_calculated)
1611 calculate_PBP_extrema();
1612 return num_Es; // due to the "side effect" of calling calculate_PBP_extrema
1615 /** eval_execution::getMinE() to get minimum of a PBP measure attribute through EVALUATE */
1616 double getMinE(unsigned ind) {
1618 throw std::logic_error("getMinE() MUST not be called before complete() is signalled in eval_execution");
1620 if (!PBP_extrema_calculated)
1621 calculate_PBP_extrema(); // which calculates num_Es
1623 throw std::logic_error("num_Es cannot be 0 in PBPmeaset::getMinE()");
1626 throw std::invalid_argument("bad parameter to getMinE");
1628 return PBP_minima[ind];
1629 } // eval_execution::getMinE()
1631 double getMaxE(unsigned ind) {
1633 throw std::logic_error("getMinE() MUST not be called before complete() is signalled in PBPmeaset");
1635 if (!PBP_extrema_calculated)
1636 calculate_PBP_extrema(); // which calculates num_Es
1638 throw std::logic_error("num_Es cannot be 0 in PBPmeaset::getMaxE()");
1641 throw std::invalid_argument("bad parameter to getMaxE");
1643 return PBP_maxima[ind];
1644 } // eval_execution::getMaxE()
1646 /** debug routine: shows all values in the global measurement sets "recursively" */
1647 void show_all_globs() {
1649 // std::cout << "(cout) about to bail" << std::endl;
1650 // std::cerr << "(cerr) about to bail" << std::endl;
1651 throw std::logic_error("MUST not call show_all_globs() before signalling complete() to an eval_execution");
1654 if (globmeasets.empty()) {
1655 std::cout << "## No glob sets to show in eval exec " << EEID << std::endl;
1657 std::cout << "=>>=showing all globmeasets in eval exec " << EEID << std::endl;
1658 for (unsigned i = 0; i < get_num_globmeasets(); i++) {
1659 std::cout << "Showing globmeaset " << i << ":" << std::endl;
1660 globmeasets[i].show_all();
1662 std::cout << "=<<=showed all globmeasets in eval exec " << EEID << std::endl;
1664 } // --eval_execution::show_all_globs()
1666 /** debug routine: shows all values in the global measurement sets "recursively" */
1667 void show_all_PBPs() {
1669 throw std::logic_error("MUST not call show_all_ppbs() before signalling complete() to eval_execution");
1671 if (PBPmeasets.empty()) {
1672 std::cout << "## No PBP sets to show in eval exec " << EEID << std::endl;
1674 std::cout << "=>>=showing all PBPmeasets in eval exec " << EEID << std::endl;
1675 for (unsigned i = 0; i < get_num_PBPmeasets(); i++) {
1676 std::cout << "Showing PBPmeaset " << i << ": (algname ["
1677 << PBPmeasets[i].getAlgname() << "])" << std::endl;
1678 PBPmeasets[i].show_all();
1680 std::cout << "=<<=showed all PBPmeasets in eval exec " << EEID << std::endl;
1682 } // --eval_execution::show_all_PBPs()
1684 /** eval_execution::show_extrema() */
1685 void show_extrema() {
1687 throw std::logic_error("Must NOT show extrema of eval_execution before complete() is signalled");
1688 std::cout << "Showing extrema in eval_execution_set among selected eval_executions." << std::endl;
1689 bool successful = false;
1690 if (hasGlobal() && calculate_global_extrema()) {
1691 std::cout << "after global calculation: minIter, maxIter: " << minIter << " " << maxIter << std::endl;
1692 std::cout << "minAverage, maxAverage, minDistance, maxDistance, minRelerr, maxRelerr:" << std::endl
1693 << minAverage << " " << maxAverage << " " << minDistance << " " << maxDistance << " " << minRelerr << " " << maxRelerr;
1694 std::cout << std::endl;
1695 std::cout << "minVariance, maxVariance, minStddev, maxStddev, minResidual, maxResidual, minKullback, maxKullback:" << std::endl
1696 << minVariance << " " << maxVariance << " " << minStddev << " " << maxStddev << " " << minResidual << " " << maxResidual << " " << minKullback << " " << maxKullback;
1697 std::cout << std::endl;
1701 if (hasPBP() && calculate_PBP_extrema()) {
1702 std::cout << "after PBP calculation: minIter, maxIter: " << minIter << " " << maxIter << std::endl;
1703 for (unsigned i = 0; i < num_Es; i++) {
1704 std::cout << "PBP_minima[" << i << "] = " << PBP_minima[i] << "; "
1705 << "PBP_maxima[" << i << "] = " << PBP_maxima[i] << std::endl;
1710 std::cout << "Attempts to calculate both global and PBP extrema were unsuccessful in eval_execution." << std::endl;
1712 } // --eval_execution::show_extrema()
1715 std::cout << "==>>>==entering show_all() for eval exec " << EEID << std::endl;
1718 std::cout << "==<<<==leaving show_all() for eval exec " << EEID << std::endl;
1719 } // --eval_execution::show_all()
1721 void addPBPVarLines(line_real_set_t& LRS, unsigned PBPYVar) {
1722 for (std::deque<PBPmeaset>::iterator it = PBPmeasets.begin();
1723 it != PBPmeasets.end(); it++) {
1724 it->addPBPVarLine(LRS, PBPYVar);
1726 } // --eval_execution::addPBPVarLines()
1728 void addGlobVarLines(line_real_set_t& LRS, globalYVar_t globalYVar) {
1729 for (std::deque<globmeaset>::iterator it = globmeasets.begin();
1730 it != globmeasets.end(); it++) {
1731 it->addGlobVarLine(LRS, globalYVar);
1733 } // --eval_execution::addGlobVarLines()
1735 }; // --class eval_execution
1737 // unsigned eval_execution::NEXT_EEID = 0; // class variable initialization
1739 /** eval_execution_set: superstructure capable of holding information
1740 given by many eval executions, an entire eval08 file */
1741 // class eval_execution_set {
1742 // std::deque<eval_execution> execs; // entire output of snark14 EVALUATE executions
1743 // std::vector<bool> selected; // holds which execs are selected by snark14Display user
1744 // phantomeas* phantomeasp;
1745 // bool completed; // holds whether creation of execs is complete (is this really necessary here?)
1746 // bool extrema_calculated; // holds whether extrema are calculated (ditto.)
1747 // bool same_x_forall; // for iter, plotted on x-axis
1748 // bool same_y_forall; // for whatever it is that is requested for plotting on y-axis
1749 // // (almost the same as for eval_execution) extrama...
1750 // // first the global extrema
1751 // int minIter, maxIter;
1752 // double minAverage, maxAverage, minDistance, maxDistance, minRelerr, maxRelerr;
1753 // double minVariance, maxVariance, minStddev, maxStddev, minResidual, maxResidual;
1754 // // then the PBP extrema...
1755 // std::vector<double> PBP_minima; // minima and maxima of each E(0)..E(N-1), N not varying within an eval file.
1756 // std::vector<double> PBP_maxima; // to be calculated over ALL EVALUATE calls, depending.
1757 // unsigned num_Es; // 'N' in comment above
1758 // // e.g., PBP_minima[2] is the minimum value of all E(2) in all PBPmeasets in all execs.
1760 eval_execution_set::eval_execution_set() {
1761 completed = extrema_calculated = false;
1762 same_x_forall = same_y_forall = false; // initialize to use "locally" calculated domain/range bounds
1763 selectionHasResidualvar = false;
1764 selectionHasKullbackvar = false;
1766 } // eval_execution_set() ctor
1768 // void new_exec(eval_execution &ev) {
1770 // execs.push_back(ev);
1771 // selected.push_back(false);
1774 // void eval_execution_set::new_exec() {
1775 // if (!execs.empty()) {
1776 // execs.back().set_phantom(phantomeasp);
1777 // execs.back().complete();
1779 // eval_execution exec;
1780 // execs.push_back(exec);
1781 // selected.push_back(false);
1784 void eval_execution_set::new_exec(execname_t name) {
1785 if (!execs.empty()) {
1786 execs.back().set_phantom(phantomeasp);
1787 execs.back().complete();
1789 eval_execution exec(name);
1790 execs.push_back(exec);
1791 selected.push_back(false);
1794 void eval_execution_set::new_globmeaset(execname_t line) {
1796 throw std::logic_error("call to eval_execution_set::new_globmeaset() before ::new_exec()");
1798 execs.back().new_globmeaset(line);
1801 void eval_execution_set::add_to_globmeaset(measline_t line) {
1803 throw std::logic_error("call to eval_execution_set::add_to_globmeaset() before ::new_exec()");
1804 execs.back().add_to_globmeaset(line);
1807 void eval_execution_set::new_PBPmeaset(execname_t line) {
1809 throw std::logic_error("call to eval_execution_set::new_PBPmeaset() before ::new_exec()");
1810 execs.back().new_PBPmeaset(line);
1813 void eval_execution_set::add_to_PBPmeaset(measline_t line) {
1815 throw std::logic_error("call to eval_execution_set::add_to_PBPmeaset() before ::new_exec()");
1816 execs.back().add_to_PBPmeaset(line);
1819 /** eval_execution_set::set_phantomeas() sets _the_ phantom measurement of the eval_execution_set
1820 pre: all phantom-related lines in the eval file are identical
1821 barring the possibility of there being residual in some but not others
1822 this function sort of "updates" the value of phantom.
1823 logically, to be considered part of every eval_execution that has at least one globmeaset:
1824 (for applicable fields) both for the purpose of plotting and calculating extrema.
1825 if exists (!=0), DO NOT CHANGE phantomeasp OR YOU'LL SEGFAULT!
1827 void eval_execution_set::set_phantomeas(measline_t line) {
1829 if (phantomeasp && phantomeasp->hasResidual() && phantomeasp->hasKullback()) return;
1832 phantomeasp = new phantomeas(line);
1836 phantomeas locphan(line);
1837 if (locphan.hasResidual()) {
1838 phantomeasp->setNewResidual(locphan.getResidual()); // set by value
1840 if (locphan.hasKullback()) {
1841 phantomeasp->setNewKullback(locphan.getKullback()); // set by value
1843 } // --eval_execution_set::set_phantomeas()
1845 bool eval_execution_set::hasPhantom() {
1846 return (0 != phantomeasp);
1849 bool eval_execution_set::calculate_global_extrema() {
1850 return calculate_global_extrema(false, 0, 0);
1853 /** eval_execution_set::calculate_global_extrema() */
1854 bool eval_execution_set::calculate_global_extrema(bool restrict_domain, int min_it_arg, int max_it_arg) {
1856 throw std::logic_error("eval_execution_set::calculate_extrema() cannot be called on incomplete set");
1857 if (selected.size() != execs.size())
1858 throw std::logic_error("selected does not match execs in size");
1859 minResidual = maxResidual = -1.0;
1860 minKullback = maxKullback = -1.0;
1861 bool first_one = true;
1863 for (std::deque<eval_execution>::iterator it = execs.begin();
1864 it != execs.end(); j++, it++) {
1865 if (selected[j] && ((*it).hasGlobal()) && ((*it).calculate_global_extrema(restrict_domain, min_it_arg, max_it_arg))) {
1866 /// std::cout << "eval_execution_set::calculate_global_extrema() j = " << j << std::endl;
1867 if (first_one) { // for first selected eval_exec with global
1868 // it is the first one and non-empty intersects with argument domain, if restricted
1869 minIter = (*it).getMinIter();
1870 maxIter = (*it).getMaxIter();
1871 /// std::cout << "minIter: " << minIter << ", maxIter: " << maxIter << std::endl;
1872 minAverage = (*it).getMinAverage();
1873 minDistance = (*it).getMinDistance();
1874 minRelerr = (*it).getMinRelerr();
1875 minVariance = (*it).getMinVariance();
1876 minStddev = (*it).getMinStddev();
1878 maxAverage = (*it).getMaxAverage();
1879 maxDistance = (*it).getMaxDistance();
1880 maxRelerr = (*it).getMaxRelerr();
1881 maxVariance = (*it).getMaxVariance();
1882 maxStddev = (*it).getMaxStddev();
1884 if ((*it).hasResidual()) { // not necessarily true in the first evaluate
1885 selectionHasResidualvar = true;
1886 minResidual = (*it).getMinResidual();
1887 maxResidual = (*it).getMaxResidual();
1889 if ((*it).hasKullback()) { // not necessarily true in the first evaluate
1890 selectionHasKullbackvar = true;
1891 minKullback = (*it).getMinKullback();
1892 maxKullback = (*it).getMaxKullback();
1895 } else { // for all other selected eval_execs with global with matching domain
1897 if (minIter > (tmpi = (*it).getMinIter())) minIter = tmpi;
1898 if (maxIter < (tmpi = (*it).getMaxIter())) maxIter = tmpi;
1900 if (minAverage > (tmp = ((*it).getMinAverage()))) minAverage = tmp;
1901 if (minDistance > (tmp = ((*it).getMinDistance()))) minDistance = tmp;
1902 if (minRelerr > (tmp = ((*it).getMinRelerr()))) minRelerr = tmp;
1903 if (minVariance > (tmp = ((*it).getMinVariance()))) minVariance = tmp;
1904 if (minStddev > (tmp = ((*it).getMinStddev()))) minStddev = tmp;
1906 if (maxAverage < (tmp = ((*it).getMaxAverage()))) maxAverage = tmp;
1907 if (maxDistance < (tmp = ((*it).getMaxDistance()))) maxDistance = tmp;
1908 if (maxRelerr < (tmp = ((*it).getMaxRelerr()))) maxRelerr = tmp;
1909 if (maxVariance < (tmp = ((*it).getMaxVariance()))) maxVariance = tmp;
1910 if (maxStddev < (tmp = ((*it).getMaxStddev()))) maxStddev = tmp;
1912 if ((*it).hasResidual()) {
1913 if (minResidual < 0) { // this is the first globmeaset with residual
1914 minResidual = (*it).getMinResidual();
1915 maxResidual = (*it).getMaxResidual();
1916 } else { // we have seen a globmeaset with residual before and now seeing another
1918 if (minResidual > (tmp = ((*it).getMinResidual()))) minResidual = tmp;
1919 if (maxResidual < (tmp = ((*it).getMaxResidual()))) maxResidual = tmp;
1922 if ((*it).hasKullback()) {
1923 if (minKullback < 0) { // this is the first globmeaset with kl distance
1924 minKullback = (*it).getMinKullback();
1925 maxKullback = (*it).getMaxKullback();
1926 } else { // we have seen a globmeaset with kl distance before and now seeing another
1928 if (minKullback > (tmp = ((*it).getMinKullback()))) minKullback = tmp;
1929 if (maxKullback < (tmp = ((*it).getMaxKullback()))) maxKullback = tmp;
1932 } // --not the first one
1933 } // --selected evaluate with global
1934 } // --foreach EVALUATE execution
1935 return (!first_one);
1936 // return true if some execution has global measurements whose domain matches input domain restriction
1937 } // --eval_exec_set::calculate_global_extrema()
1939 bool eval_execution_set::calculate_PBP_extrema() {
1940 return calculate_PBP_extrema(false, 0, 0);
1943 /** eval_execution_set::calculate_PBP_extrema() */
1944 bool eval_execution_set::calculate_PBP_extrema(bool restrict_domain, int min_it_arg, int max_it_arg) {
1946 throw std::logic_error("eval_execution_set::calculate_extrema() cannot be called on incomplete set");
1947 if (selected.size() != execs.size())
1948 throw std::logic_error("selected does not match execs in size");
1950 // PBP_minima.resize(0);
1951 // PBP_maxima.resize(0);
1954 bool first_one = true;
1956 for (std::deque<eval_execution>::iterator it = execs.begin();
1957 it != execs.end(); j++, it++) {
1958 if ((selected[j]) && ((*it).hasPBP()) && ((*it).calculate_PBP_extrema(restrict_domain, min_it_arg, max_it_arg))) {
1960 minIter = (*it).getMinIter();
1961 maxIter = (*it).getMaxIter();
1962 num_Es = (*it).get_num_Es(); // this is the same throughout the file.
1963 PBP_minima.resize(num_Es);
1964 PBP_maxima.resize(num_Es);
1965 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1966 PBP_minima[myInd] = (*it).getMinE(myInd);
1967 PBP_maxima[myInd] = (*it).getMaxE(myInd);
1972 if (minIter > (tmpi = (*it).getMinIter())) minIter = tmpi;
1973 if (maxIter < (tmpi = (*it).getMaxIter())) maxIter = tmpi;
1974 for (unsigned myInd = 0; myInd < num_Es; myInd++) {
1976 if (PBP_minima[myInd] > (tmp = (*it).getMinE(myInd))) PBP_minima[myInd] = tmp;
1977 if (PBP_maxima[myInd] < (tmp = (*it).getMaxE(myInd))) PBP_maxima[myInd] = tmp;
1980 } // --selected evaluate with point
1982 return (!first_one);
1983 // return true if any selected execution has PBP measurements and input domain restriction matches their domain
1984 } // eval_execution_set::calculate_PBP_extrema()
1986 execname_t eval_execution_set::getExecName(unsigned idx) {
1987 return execs[idx].getName();
1990 /** by "for all", the selected set of EVALUATE executions are meant.
1991 setSameXForAll(true) to use "global" domain for each plot */
1992 //void eval_execution_set::setSameXForAll(bool val = true) {
1994 void eval_execution_set::setSameXForAll(bool val) {
1995 same_x_forall = val;
1998 //void eval_execution_set::setSameYForAll(bool val = true) {
2000 void eval_execution_set::setSameYForAll(bool val) {
2001 same_y_forall = val;
2004 bool eval_execution_set::getSameXForAll() {
2005 return same_x_forall;
2008 bool eval_execution_set::getSameYForAll() {
2009 return same_y_forall;
2012 // i don't even know if this idea will make it to the production version
2013 //void eval_execution_set::useSameExtremaForAll(bool val = true) {
2015 void eval_execution_set::useSameExtremaForAll(bool val) {
2016 setSameXForAll(val);
2017 setSameYForAll(val);
2020 void eval_execution_set::useDifferentExtremaForEach() {
2021 useSameExtremaForAll(false);
2024 void eval_execution_set::complete() {
2026 throw std::logic_error("attempt to compete() empty eval_execution_set!");
2028 execs.back().set_phantom(phantomeasp);
2029 execs.back().complete();
2033 unsigned eval_execution_set::num_eval_execs() {
2034 return static_cast<unsigned> (execs.size());
2037 void eval_execution_set::deselect_exec(unsigned idx) {
2039 throw std::logic_error("Cannot deselect_exec() without having a completed eval_execution_set.");
2040 if (idx >= num_eval_execs())
2041 throw std::invalid_argument("exec index out of range in eval_execution_set::deselect_exec()");
2042 selected[idx] = false;
2043 extrema_calculated = false; // previous extrema calcs annulled
2046 void eval_execution_set::select_exec(unsigned idx) { // everything is deselected by default
2048 throw std::logic_error("Cannot select_exec() without having a completed eval_execution_set.");
2049 if (idx >= num_eval_execs())
2050 throw std::invalid_argument("exec index out of range in eval_execution_set::deselect_exec()");
2051 selected[idx] = true;
2052 extrema_calculated = false; // previous extrema calcs annulled
2053 } // eval_execution_set::select_exec()
2055 void eval_execution_set::deselect_all_execs() {
2057 throw std::logic_error("Cannot deselect_all_execs() without having a completed eval_execution_set.");
2058 for (std::vector<bool>::iterator it = selected.begin(); it != selected.end(); it++) {
2061 extrema_calculated = false; // previous extrema calcs annulled
2064 void eval_execution_set::select_all_execs() {
2066 throw std::logic_error("Cannot select_all_execs() without having a completed eval_execution_set.");
2067 for (std::vector<bool>::iterator it = selected.begin(); it != selected.end(); it++) {
2070 extrema_calculated = false; // previous extrema calcs annulled
2073 bool eval_execution_set::selectionHasGlobal() {
2074 for (unsigned idx = 0; idx < num_eval_execs(); idx++) {
2075 if ((selected[idx]) && (execs[idx].hasGlobal())) {
2082 bool eval_execution_set::selectionHasResidual() {
2083 for (unsigned idx = 0; idx < num_eval_execs(); idx++) {
2084 if ((selected[idx]) && (execs[idx].hasGlobal()) && (execs[idx].hasResidual())) {
2091 bool eval_execution_set::selectionHasKullback() {
2092 for (unsigned idx = 0; idx < num_eval_execs(); idx++) {
2093 if ((selected[idx]) && (execs[idx].hasGlobal()) && (execs[idx].hasKullback())) {
2100 bool eval_execution_set::selectionHasPBP() {
2101 for (unsigned idx = 0; idx < num_eval_execs(); idx++) {
2102 if ((selected[idx]) && (execs[idx].hasPBP())) {
2109 /** eval_execution_set::get_num_Es() returns:
2110 number of PBP fields IF execution selection includes a PBP
2111 0 otherwise (should? throw exception)
2113 unsigned eval_execution_set::get_num_Es() {
2114 for (unsigned idx = 0; idx < num_eval_execs(); idx++) {
2115 if ((selected[idx]) && (execs[idx].hasPBP())) {
2116 return execs[idx].get_num_Es();
2122 // really throw exception... arkh.
2124 int eval_execution_set::getMinIterViaGlobal() {
2125 if (calculate_global_extrema())
2130 int eval_execution_set::getMaxIterViaGlobal() {
2131 if (calculate_global_extrema())
2136 int eval_execution_set::getMinIterViaPBP() {
2137 if (calculate_PBP_extrema())
2142 int eval_execution_set::getMaxIterViaPBP() {
2143 if (calculate_PBP_extrema())
2148 double eval_execution_set::getMinYGlobal(globalYVar_t globalYVar) {
2149 if (!calculate_global_extrema()) return -1; // throw exception!
2150 switch (globalYVar) {
2167 if (selectionHasResidual())
2170 if (selectionHasKullback())
2178 double eval_execution_set::getMaxYGlobal(globalYVar_t globalYVar) {
2179 if (!calculate_global_extrema()) return -1; // throw exception!
2180 switch (globalYVar) {
2197 if (selectionHasResidual())
2200 if (selectionHasKullback())
2206 } // --eval_execution_set::getMaxYGlobal(globalYVar_t globalYVar)
2208 double eval_execution_set::getMinYPBP(unsigned idx) {
2209 // if(idx >= num_Es) {
2210 // throw std::logic_error("blah");
2212 calculate_PBP_extrema();
2213 return PBP_minima[idx];
2216 double eval_execution_set::getMaxYPBP(unsigned idx) {
2217 calculate_PBP_extrema();
2218 return PBP_maxima[idx];
2221 /** eval_execution_set::show_all() and show_selected() are for debugging */
2222 void eval_execution_set::show_all() {
2224 phantomeasp->show();
2226 for (std::deque<eval_execution>::iterator it = execs.begin(); it != execs.end(); it++) {
2228 } // --foreach eval_execution
2229 } // eval_execution_set::show_all()
2231 void eval_execution_set::show_selected() {
2233 for (std::deque<eval_execution>::iterator it = execs.begin();
2234 it != execs.end(); j++, it++) {
2238 } // --foreach eval_execution
2240 } // eval_execution_set::show_selected()
2242 /** eval_execution_set::show_extrema() [mainly for debugging]
2243 * huge side effect: recalculates all extrema without domain restriction */
2244 void eval_execution_set::show_extrema() {
2246 throw std::logic_error("Must NOT show extrema of eval_execution_set before complete() is signalled");
2247 std::cout << "Showing extrema in eval_execution_set among selected eval_executions." << std::endl;
2251 phantomeasp->show();
2254 bool successful = false;
2255 if (calculate_global_extrema()) {
2256 std::cout << "after global calculation: minIter, maxIter: " << minIter << " " << maxIter << std::endl;
2257 std::cout << "minAverage, maxAverage, minDistance, maxDistance, minRelerr, maxRelerr:" << std::endl
2258 << minAverage << " " << maxAverage << " " << minDistance << " " << maxDistance << " " << minRelerr << " " << maxRelerr;
2259 std::cout << std::endl;
2260 std::cout << "minVariance, maxVariance, minStddev, maxStddev, minResidual, maxResidual, minKullback, maxKullback:" << std::endl
2261 << minVariance << " " << maxVariance << " " << minStddev << " " << maxStddev << " " << minResidual << " " << maxResidual << " " << minKullback << " " << maxKullback;
2262 std::cout << std::endl;
2266 if (calculate_PBP_extrema()) {
2267 std::cout << "after PBP calculation: minIter, maxIter: " << minIter << " " << maxIter << std::endl;
2268 for (unsigned i = 0; i < num_Es; i++) {
2269 std::cout << "PBP_minima[" << i << "] = " << PBP_minima[i] << "; "
2270 << "PBP_maxima[" << i << "] = " << PBP_maxima[i] << std::endl;
2276 std::cout << "Attempts to calculate both global and PBP extrema were unsuccessful." << std::endl;
2278 } // --eval_execution_set::show_extrema()
2280 void eval_execution_set::addPBPVarLines(line_real_set_t& LRS, unsigned PBPYVar, unsigned ee_index) {
2281 execs[ee_index].addPBPVarLines(LRS, PBPYVar); // this is 'inefficient' addressing, so what?
2284 void eval_execution_set::addGlobVarLines(line_real_set_t& LRS, globalYVar_t globalYVar, unsigned ee_index) {
2288 phanval = phantomeasp->get(globalYVar);
2292 if (phanval > -0.5) {
2293 line_real_t phantomline("phantom", LRS.getMinX(), LRS.getMaxX(), phanval);
2294 LRS.add(phantomline);
2296 // then the other lines
2297 execs[ee_index].addGlobVarLines(LRS, globalYVar);
2298 } // --eval_execution_set::addGlobVarLines()
2300 void eval_execution_set::spawnDialogsGlob(QWidget* parent, globalYVar_t globalYVar) {
2301 if (std::verbose >= 2) {
2302 std::cout << "in eval_execution_set::spawnDialogsGlob()" << std::endl;
2304 int posx = parent->pos().x();
2305 int posy = parent->pos().y();
2306 unsigned ee_index = 0;
2307 for (std::deque<eval_execution>::iterator it = execs.begin();
2308 it != execs.end(); ee_index++, it++) {
2309 // if selected and has global and if selected var is residual then has residual
2310 if ((selected[ee_index]) && ((*it).hasGlobal()) && ((globalYVar != RESIDUAL) || ((*it).hasResidual())) && ((globalYVar != KULLBACK) || ((*it).hasKullback()))) {
2313 /// it->show_extrema(); // might have side-effects
2314 it->calculate_global_extrema();
2315 int minX = it->getMinIter(); // to be the defaults in the range dialog window
2316 int maxX = it->getMaxIter();
2317 double minY = 0, maxY = 0; // initialize to shut up the compiler
2318 switch (globalYVar) {
2319 case AVERAGE: minY = it->getMinAverage();
2320 maxY = it->getMaxAverage();
2322 case DISTANCE: minY = it->getMinDistance();
2323 maxY = it->getMaxDistance();
2325 case RELERR: minY = it->getMinRelerr();
2326 maxY = it->getMaxRelerr();
2328 case VARIANCE: minY = it->getMinVariance();
2329 maxY = it->getMaxVariance();
2331 case STDDEV: minY = it->getMinStddev();
2332 maxY = it->getMaxStddev();
2334 case RESIDUAL: minY = it->getMinResidual();
2335 maxY = it->getMaxResidual();
2337 case KULLBACK: minY = it->getMinKullback();
2338 maxY = it->getMaxKullback();
2340 // default: never happens
2342 if (std::verbose >= 2) {
2343 std::cout << "in eval_execution_set::spawnDialogsGlob() minY is "
2344 << minY << " and maxY is " << maxY << std::endl;
2346 const char* ccp = it->getName();
2347 chooseRangesDialog* crdp =
2348 new chooseRangesDialog(parent, ccp, false, 0, posx, posy,
2349 ee_index, false, 0, globalYVar,
2350 minX, maxX, minY, maxY);
2354 } // --eval_execution_set::spawnDialogsGlob()
2356 /** spawn dialog box to get range for each selected eval execution with PBP */
2357 void eval_execution_set::spawnDialogsPBP(QWidget* parent, unsigned PBPYVar) {
2358 if (std::verbose >= 2) {
2359 std::cout << "in eval_execution_set::spawnDialogsPBP()" << std::endl;
2361 int posx = parent->pos().x();
2362 int posy = parent->pos().y();
2363 unsigned ee_index = 0;
2364 for (std::deque<eval_execution>::iterator it = execs.begin();
2365 it != execs.end(); ee_index++, it++) {
2366 if ((selected[ee_index]) && ((*it).hasPBP())) {
2369 it->calculate_PBP_extrema();
2370 int minX = it->getMinIter(); // to be the defaults in the range dialog window
2371 int maxX = it->getMaxIter();
2372 double minY = it->getMinE(PBPYVar);
2373 double maxY = it->getMaxE(PBPYVar);
2374 const char* ccp = it->getName();
2375 chooseRangesDialog* crdp =
2376 new chooseRangesDialog(parent, ccp, false, 0, posx, posy,
2377 ee_index, true, PBPYVar, AVERAGE,
2378 minX, maxX, minY, maxY);
2382 } // --eval_execution_set::spawnDialogsPBP()
2384 void eval_execution_set::spawnAllPlotsGlob(QWidget* parent,
2385 globalYVar_t globalYVar, int userMinXVal, int userMaxXVal,
2386 double userMinYVal, double userMaxYVal, bool isGrayScale) {
2387 /// std::cout << "in eval_execution_set::spawnAllPlotsGlob()" << std::endl;
2388 // int PMWidth = 650; // pixmap width, etc
2389 // sd_line_t::WIDTH = 650;
2390 int PMWidth = sd_line_t::WIDTH;
2391 // int PMHeight = 550;
2392 // sd_line_t::HEIGHT = 550;
2393 int PMHeight = sd_line_t::HEIGHT;
2394 int PMDepth = 24; // number of colors?
2395 unsigned ee_index = 0;
2396 int x = parent->pos().x();
2397 int y = parent->pos().y();
2398 // block for doing phan
2401 phanval = phantomeasp->get(globalYVar);
2406 switch (globalYVar) {
2407 case AVERAGE: YVarName = "Average";
2409 case DISTANCE: YVarName = "Distance";
2411 case RELERR: YVarName = "Relative Error";
2413 case VARIANCE: YVarName = "Variance";
2415 case STDDEV: YVarName = "Standard Deviation";
2417 case RESIDUAL: YVarName = "Residual";
2419 case KULLBACK: YVarName = "KL Distance";
2422 for (std::deque<eval_execution>::iterator it = execs.begin();
2423 it != execs.end(); ee_index++, it++) {
2424 if ((selected[ee_index]) && ((*it).hasGlobal()) && ((globalYVar != RESIDUAL) || ((*it).hasResidual())) && ((globalYVar != KULLBACK) || ((*it).hasKullback()))) {
2425 line_real_set_t LRS(userMinXVal, userMaxXVal, userMinYVal, userMaxYVal);
2426 QPixmap* myPixmapP = new QPixmap(PMWidth, PMHeight);
2427 myPixmapP->fill(Qt::white);
2428 QPainter* myPainterP = new QPainter;
2429 myPainterP->begin(myPixmapP);
2430 // do the thing with the plot
2431 if (phanval > -0.5) { // if no error getting stuff from phan
2432 line_real_t phantomline("phantom", LRS.getMinX(), LRS.getMaxX(), phanval);
2433 LRS.add(phantomline);
2435 it->addGlobVarLines(LRS, globalYVar);
2436 plot_t myPlotter(LRS); // now combine LRS with myPainterP
2437 QString evalexecname = it->getName();
2438 QString fullname = evalexecname;
2440 fullname += YVarName;
2441 myPlotter.setName(fullname);
2442 myPlotter.setYAxisName(YVarName);
2443 QString XAxisName = "Iteration"; // as in all evals
2444 myPlotter.setXAxisName(XAxisName);
2445 // jk 2/2/2009 adding grayScale option for graphs
2447 myPlotter.plotGray(*myPainterP);
2449 myPlotter.plot(*myPainterP);
2453 displaylineswindow *dwp = new displaylineswindow(parent, fullname, myPixmapP, false, 0, x, y);
2454 dwp->show(); // and display!
2457 } // --eval_execution_set::spawnAllPlotsGlob()
2459 void eval_execution_set::spawnAllPlotsPBP(QWidget* parent, unsigned PBPYVar,
2460 int userMinXVal, int userMaxXVal, double userMinYVal,
2461 double userMaxYVal, bool isGrayScale) {
2462 /// std::cout << "in eval_execution_set::spawnAllPlotsPBP()" << std::endl;
2463 // int PMWidth = 650; // pixmap width, etc
2464 // sd_line_t::WIDTH = 650;
2465 int PMWidth = sd_line_t::WIDTH;
2466 // int PMHeight = 550;
2467 // sd_line_t::HEIGHT = 550;
2468 int PMHeight = sd_line_t::HEIGHT;
2469 unsigned ee_index = 0;
2470 int x = parent->pos().x();
2471 int y = parent->pos().y();
2472 QString YVarName = "e(";
2473 QString PBPYVarAsQString;
2474 PBPYVarAsQString.setNum(PBPYVar);
2475 YVarName += PBPYVarAsQString;
2477 for (std::deque<eval_execution>::iterator it = execs.begin();
2478 it != execs.end(); ee_index++, it++) {
2479 if ((selected[ee_index]) && ((*it).hasPBP())) {
2480 line_real_set_t LRS(userMinXVal, userMaxXVal, userMinYVal, userMaxYVal);
2481 QPixmap* myPixmapP = new QPixmap(PMWidth, PMHeight);
2482 myPixmapP->fill(Qt::white);
2483 QPainter* myPainterP = new QPainter;
2484 myPainterP->begin(myPixmapP);
2485 // do the thing with the plot: NO phantom for PBP
2486 it->addPBPVarLines(LRS, PBPYVar);
2487 plot_t myPlotter(LRS); // now combine LRS with myPainterP
2488 // can give name here based on (*it)
2489 QString evalexecname = it->getName();
2490 QString fullname = evalexecname;
2492 fullname += YVarName;
2493 myPlotter.setName(fullname);
2494 QString xaxname = "Iteration";
2495 myPlotter.setXAxisName(xaxname);
2496 myPlotter.setYAxisName(YVarName);
2497 // jk 2/2/2009 adding grayScale option for graphs
2499 myPlotter.plotGray(*myPainterP);
2501 myPlotter.plot(*myPainterP);
2506 displaylineswindow *dwp = new displaylineswindow(parent, fullname, myPixmapP, false, 0, x, y);
2507 dwp->show(); // and display!
2510 } // --eval_execution_set::spawnAllPlotsPBP()
2512 /** eval_execution_set::clear() !!!! erases all information!!! (to allow callee to get on with life) */
2513 void eval_execution_set::clear() {
2514 /// std::cout << "in eval_execution_set::clear()!!!" << std::endl;
2515 completed = extrema_calculated = false;
2516 same_x_forall = same_y_forall = false; // initialize to use "locally" calculated domain/range bounds
2517 selectionHasResidualvar = false;
2518 selectionHasKullbackvar = false;
2520 if (phantomeasp) delete phantomeasp;
2526 minResidual = maxResidual = -1;
2527 minKullback = maxKullback = -1;
2528 } // --eval_execution_set()
2530 eval_execution_set::~eval_execution_set() {
2531 // std::cout << "in eval_execution_set destructor!!!" << std::endl;
2533 delete phantomeasp; // and make sure no one else does this!
2535 } // --eval_execution_set dtor
2536 //// // --class eval_execution_set
2538 unsigned globmeas::NEXT_GMID = 0; // class variable initialization
2539 unsigned globmeaset::NEXT_GMSID = 0; // class variable initialization
2540 unsigned PBPmeas::NEXT_PMID = 0; // class variable initialization
2541 unsigned PBPmeaset::NEXT_PMSID = 0; // class variable initialization
2542 unsigned eval_execution::NEXT_EEID = 0; // class variable initialization
2544 // --eval_helper.cpp