1 /*  _______________________________________________________________________
2 
3     DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4     Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Dakota directory.
7     _______________________________________________________________________ */
8 
9 #include <cstdlib>
10 #include <iostream>
11 #include <fstream>
12 #include <string>
13 #include <vector>
14 #include <map>
15 #include <algorithm>
16 #include <cctype>
17 
18 enum var_t { X1, X2 };
19 
20 
main(int argc,char ** argv)21 int main(int argc, char** argv)
22 {
23 
24   // The Rosenbrock function may be solved as either a general minimization
25   // problem with Objective function = 100.*(x1-x0^2)^2 + (1-x0)^2
26   // or a least squares problem with Term1 = 10.*(x1-x0^2) and Term2 = (1-x0).
27   // See p. 95 in Practical Optimization by Gill, Murray, and Wright.
28 
29   // This application program reads and writes parameter and response data
30   // directly so no input/output filters are needed.
31   std::ifstream fin(argv[1]);
32   if (!fin) {
33     std::cerr << "\nError: failure opening " << argv[1] << std::endl;
34     exit(-1);
35   }
36   size_t i, j, num_vars, num_fns, num_deriv_vars;
37   std::string vars_text, fns_text, dvv_text;
38 
39   // define the std::string to enumeration map
40   std::map<std::string, var_t> var_t_map;
41   var_t_map["x1"] = X1;
42   var_t_map["x2"] = X2;
43 
44   // Get the parameter std::vector and ignore the labels
45   fin >> num_vars >> vars_text;
46   std::map<var_t, double> vars;
47   std::vector<var_t> labels(num_vars);
48   double var_i; std::string label_i; var_t v_i;
49   std::map<std::string, var_t>::iterator v_iter;
50   for (i=0; i<num_vars; i++) {
51     fin >> var_i >> label_i;
52     transform(label_i.begin(), label_i.end(), label_i.begin(),
53 	      (int(*)(int))tolower);
54     v_iter = var_t_map.find(label_i);
55     if (v_iter == var_t_map.end()) {
56       std::cerr << "Error: label \"" << label_i
57 		<< "\" not supported in analysis driver." << std::endl;
58       exit(-1);
59     }
60     else
61       v_i = v_iter->second;
62     vars[v_i] = var_i;
63     labels[i] = v_i;
64   }
65 
66   // Get the ASV std::vector and ignore the labels
67   fin >> num_fns >> fns_text;
68   std::vector<short> ASV(num_fns);
69   for (i=0; i<num_fns; i++) {
70     fin >> ASV[i];
71     fin.ignore(256, '\n');
72   }
73 
74   // Get the DVV std::vector and ignore the labels
75   fin >> num_deriv_vars >> dvv_text;
76   std::vector<var_t> DVV(num_deriv_vars);
77   unsigned int dvv_i;
78   for (i=0; i<num_deriv_vars; i++) {
79     fin >> dvv_i;
80     fin.ignore(256, '\n');
81     DVV[i] = labels[dvv_i-1];
82   }
83 
84   if (num_vars != 2) {
85     std::cerr << "Wrong number of variables for the rosenbrock problem\n";
86     exit(-1);
87   }
88   if (num_fns < 1 || num_fns > 2) { // 1 fn -> opt, 2 fns -> least sq
89     std::cerr << "Wrong number of functions in rosenbrock problem\n";
90     exit(-1);
91   }
92 
93   // Compute and output responses
94   bool least_sq_flag = (num_fns > 1) ? true : false;
95   double x1 = vars[X1], x2 = vars[X2];
96   double f1 = x2-x1*x1;
97   double f2 = 1.-x1;
98 
99   std::ofstream fout(argv[2]);
100   if (!fout) {
101     std::cerr << "\nError: failure creating " << argv[2] << std::endl;
102     exit(-1);
103   }
104   fout.precision(15); // 16 total digits
105   fout.setf(std::ios::scientific);
106   fout.setf(std::ios::right);
107 
108   if (least_sq_flag) {
109     if (ASV[0] & 1) // **** Residual R1:
110       fout << "                     " << 10.*f1  << " f1\n";
111     if (ASV[1] & 1) // **** Residual R2:
112       fout << "                     " << f2  << " f2\n";
113 
114     if (ASV[0] & 2) { // **** dR1/dx:
115       fout << "[ ";
116       for (i=0; i<num_deriv_vars; i++)
117 	switch (DVV[i]) {
118 	case X1: fout << -20.*x1 << ' '; break;
119 	case X2: fout <<  10.    << ' '; break;
120 	}
121       fout << "]\n ";
122     }
123     if (ASV[1] & 2) { // **** dR2/dx:
124       fout << "[ ";
125       for (i=0; i<num_deriv_vars; i++)
126 	switch (DVV[i]) {
127 	case X1: fout << -1. << ' '; break;
128 	case X2: fout <<  0. << ' '; break;
129 	}
130       fout << "]\n";
131     }
132 
133     if (ASV[0] & 4) { // **** d^2R1/dx^2:
134       fout << "[[ ";
135       for (i=0; i<num_deriv_vars; i++)
136 	for (j=0; j<num_deriv_vars; j++)
137 	  if (DVV[i] == X1 && DVV[j] == X1)
138 	    fout <<  -20. << ' ';
139 	  else
140 	    fout <<    0. << ' ';
141       fout << "]]\n";
142     }
143     if (ASV[1] & 4) { // **** d^2R2/dx^2:
144       fout << "[[ ";
145       for (i=0; i<num_deriv_vars; i++)
146 	for (j=0; j<num_deriv_vars; j++)
147 	  fout << 0. << ' ';
148       fout << "]]\n";
149     }
150   }
151   else {
152     if (ASV[0] & 1) // **** f:
153       fout << "                     " << 100.*f1*f1+f2*f2  << " f\n";
154 
155     if (ASV[0] & 2) { // **** df/dx:
156       fout << "[ ";
157       for (i=0; i<num_deriv_vars; i++)
158 	switch (DVV[i]) {
159 	case X1: fout << -400.*f1*x1 - 2.*f2 << ' '; break;
160 	case X2: fout <<  200.*f1            << ' '; break;
161 	}
162       fout << "]\n";
163     }
164 
165     if (ASV[0] & 4) { // **** d^2f/dx^2:
166       fout << "[[ ";
167       for (i=0; i<num_deriv_vars; i++)
168 	for (j=0; j<num_deriv_vars; j++)
169 	  if (DVV[i] == X1 && DVV[j] == X1)
170 	    fout << -400.*(x2 - 3.*x1*x1) + 2. << ' ';
171 	  else if ( (DVV[i] == X1 && DVV[j] == X2) ||
172 		    (DVV[i] == X2 && DVV[j] == X1) )
173 	    fout << -400.*x1 << ' ';
174 	  else if (DVV[i] == X2 && DVV[j] == X2)
175 	    fout <<  200. << ' ';
176       fout << "]]\n";
177     }
178   }
179 
180   fout.flush();
181   fout.close();
182   return 0;
183 }
184