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 <vector>
13 #include <string>
14 #include <cmath>
15 
16 
main(int argc,char ** argv)17 int main(int argc, char** argv)
18 {
19 
20   std::ifstream fin(argv[1]);
21   if (!fin) {
22     std::cerr << "\nError: failure opening " << argv[1] << std::endl;
23     exit(-1);
24   }
25   size_t i, num_vars, num_fns, num_deriv_vars;
26   std::string vars_text, fns_text, dvv_text;
27 
28   // Get the parameter std::vector and ignore the labels
29   fin >> num_vars >> vars_text;
30   std::vector<double> x(num_vars);
31   for (i=0; i<num_vars; i++) {
32     fin >> x[i];
33     fin.ignore(256, '\n');
34   }
35 
36   // Get the ASV std::vector and ignore the labels
37   fin >> num_fns >> fns_text;
38   std::vector<int> ASV(num_fns);
39   for (i=0; i<num_fns; i++) {
40     fin >> ASV[i];
41     fin.ignore(256, '\n');
42   }
43 
44   // Get the DVV std::vector and ignore the labels
45   fin >> num_deriv_vars >> dvv_text;
46   std::vector<int> DVV(num_deriv_vars);
47   for (i=0; i<num_deriv_vars; i++) {
48     fin >> DVV[i];
49     fin.ignore(256, '\n');
50   }
51 
52   // typical usage is 2 design vars + 6 uncertain variables, although the
53   // number of uncertain variables can be any factor of two.
54   if (num_vars < 4 || num_vars % 2) {
55     std::cerr << "Error: Bad number of variables in text_book_ouu direct fn." <<std::endl;
56     exit(-1);
57   }
58   if (num_fns > 3) {
59     std::cerr << "Error: Bad number of functions in text_book_ouu direct fn." <<std::endl;
60     exit(-1);
61   }
62 
63   // Compute the results and output them directly to argv[2] (the NO_FILTER
64   // option is used).  Response tags are now optional; output them for ease
65   // of results readability.
66   std::ofstream fout(argv[2]);
67   if (!fout) {
68     std::cerr << "\nError: failure creating " << argv[2] << std::endl;
69     exit(-1);
70   }
71   fout.precision(15); // 16 total digits
72   fout.setf(std::ios::scientific);
73   fout.setf(std::ios::right);
74 
75   int split = 2 + (num_vars - 2)/2;
76 
77   // **** f:
78   if (ASV[0] & 1) {
79     double f = 0.;
80     for(i=2; i<split; i++)
81       f += pow(x[i]-10.*x[0], 4.0);
82     for(i=split; i<num_vars; i++)
83       f += pow(x[i]-10.*x[1], 4.0);
84     fout << "                     " << f << " f\n";
85   }
86 
87   // **** c1:
88   if (num_fns>1 && (ASV[1] & 1))
89     fout << "                     " << x[0]*(x[2]*x[2] - 0.5*x[3]) << " c1\n";
90 
91   // **** c2:
92   if (num_fns>2 && (ASV[2] & 1))
93     fout << "                     " << x[1]*(x[3]*x[3] - 0.5*x[2]) << " c2\n";
94 
95 
96   // **** df/dx (w.r.t. active/uncertain variables):
97   if (ASV[0] & 2) {
98     fout << "[ ";
99     for (i=0; i<num_deriv_vars; i++) {
100       int var_index = DVV[i] - 1;
101       double f0, f1, x0, x1, xvi;
102       switch (var_index) {
103       case 0: // design variable derivative
104 	f0 = 0.; x0 = x[0];
105 	for (size_t j=2; j<split; j++)
106 	  f0 += -40.*pow(x[j]-10.*x0, 3.0);
107 	fout << f0 << ' ';
108 	break;
109       case 1: // design variable derivative
110 	f1 = 0.; x1 = x[1];
111 	for (size_t j=split; j<num_vars; j++)
112 	  f1 += -40.*pow(x[j]-10.*x1, 3.0);
113 	fout << f1 << ' ';
114 	break;
115       default: // uncertain variable derivative
116 	xvi = x[var_index];
117 	if (var_index<split)
118 	  fout << 4*pow(xvi-10.*x[0], 3.0) << ' ';
119 	else
120 	  fout << 4*pow(xvi-10.*x[1], 3.0) << ' ';
121 	break;
122       }
123     }
124     fout << "]\n";
125   }
126 
127   // **** dc1/dx (w.r.t. active/uncertain variables):
128   if (num_fns>1 && (ASV[1] & 2)) {
129     fout << "[ ";
130     for (i=0; i<num_deriv_vars; i++) {
131       int var_index = DVV[i] - 1;
132       switch (var_index) {
133       case 0: // design variable derivative
134 	fout << x[2]*x[2] - 0.5*x[3] << ' '; break;
135       case 2: // uncertain variable derivative
136 	fout << 2*x[0]*x[2] << ' ';          break;
137       case 3: // uncertain variable derivative
138 	fout << -0.5*x[0] << ' ';            break;
139       default: // all other derivatives
140 	fout << "0. ";                       break;
141       }
142     }
143     fout << "]\n";
144   }
145 
146   // **** dc2/dx (w.r.t. active/uncertain variables):
147   if (num_fns>2 && (ASV[2] & 2)) {
148     fout << "[ ";
149     for (i=0; i<num_deriv_vars; i++) {
150       int var_index = DVV[i] - 1;
151       switch (var_index) {
152       case 1: // design variable derivative
153 	fout << x[3]*x[3] - 0.5*x[2] << ' '; break;
154       case 2: // uncertain variable derivative
155 	fout << -0.5*x[1] << ' ';            break;
156       case 3: // uncertain variable derivative
157 	fout << 2*x[1]*x[3] << ' ';          break;
158       default: // all other derivative
159 	fout << "0. ";                       break;
160       }
161     }
162     fout << "]\n";
163   }
164 
165   fout.flush();
166   fout.close();
167   return 0;
168 }
169