Initial snark14m import
[snark14.git] / src / snark / TerminationCriterion.cpp
1 /*
2  ***********************************************************
3  $SNARK_Header$
4  $HeadURL: svn://dig.cs.gc.cuny.edu/snark/trunk/src/snark/trm6.cpp $
5  $LastChangedRevision: 122 $
6  $Date: 2014-07-09 18:18:59 -0400 (Wed, 09 Jul 2014) $
7  $Author: agulati $
8  ***********************************************************
9
10  Residual based stopping criterion
11
12  */
13
14 #include <cstdio>
15 #include <cstdlib>
16 #include "consts.h"
17 #include "infile.h"
18 #include "TerminationCriterion.h"
19
20 using namespace std;
21
22 TerminationCriterion::TerminationCriterion(DistanceMeasure* distanceMeasureIn,
23                 char* reportingFilenameIn) {
24         this->terminationValue = 0;
25         this->distanceMeasure = distanceMeasureIn;
26
27         this->reportingEnabled = FALSE;
28         this->reportingSkipFactor = 0;
29         this->reportingFilename = reportingFilenameIn;
30 }
31
32 TerminationCriterion::~TerminationCriterion() {
33 }
34
35 void TerminationCriterion::Init() {
36         // read desired epsilon from command
37         BOOLEAN eol;
38         this->terminationValue = InFile.getnum(FALSE, &eol);
39
40         if (this->terminationValue < Consts_class::zero) {
41                 printf("\n **** epsilon must be specified and >= ZERO");
42                 printf("\n **** program aborted\n");
43                 exit(-1);
44         }
45
46         // read reporting command (disabled by default)
47         INTEGER rprt = CHAR2INT('r', 'p', 'r', 't');
48         if (InFile.getwrd(FALSE, &eol, &rprt, 1) == rprt) {
49                 this->reportingEnabled = true;
50                 printf("\n         reporting is enabled");
51                 printf("\n         reporting file: %s", this->reportingFilename);
52
53                 this->reportingSkipFactor = InFile.getnum(FALSE, &eol);
54                 if (this->reportingSkipFactor > 0) {
55                         printf("\n         report skip factor %d",
56                                         this->reportingSkipFactor);
57                 } else {
58                         printf("\n         reporting on every iteration");
59                 }
60         } else {
61                 this->reportingEnabled = false;
62                 printf("\n         reporting is disabled");
63         }
64
65         printf("\n         epsilon = %12.4f", this->terminationValue);
66 }
67
68 void TerminationCriterion::reportCurrentValue(REAL currentDistance,
69 INTEGER iter) {
70
71         if (this->reportingEnabled) {
72
73                 printf("\n         current epsilon (%s) = %20.4f",
74                                 this->distanceMeasure->getName(), currentDistance);
75
76                 FILE* RPRTfile;
77
78                 if (iter == 1) {
79                         RPRTfile = fopen(this->reportingFilename, "w");
80                         fprintf(RPRTfile, "%s stopping criterion reporting output\n",
81                                         this->reportingFilename);
82                         fprintf(RPRTfile, "    iter      %s\n", this->reportingFilename);
83                 } else {
84                         RPRTfile = fopen(this->reportingFilename, "a");
85                 }
86
87                 fprintf(RPRTfile, " %5i  %20.9f\n", iter, currentDistance);
88
89                 fclose(RPRTfile);
90         }
91 }
92
93 BOOLEAN TerminationCriterion::Run(REAL* recon, INTEGER* list,
94 REAL* weight, INTEGER iter) {
95
96         // calculate distance
97         REAL currentDistance = this->distanceMeasure->calculateDistance(recon, list,
98                         weight);
99
100         if (currentDistance <= this->terminationValue) {
101                 this->reportCurrentValue(currentDistance, iter);
102
103                 return true;
104         } else {
105                 if (iter == 1 || this->reportingSkipFactor == 0
106                                 || (iter % this->reportingSkipFactor) == 0) {
107                         this->reportCurrentValue(currentDistance, iter);
108                 }
109
110                 return false;
111         }
112 }