PaGMO  1.1.5
snoptProblem_PAGMO.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include <iostream>
6 #include "../../problem/base.h"
7 #include "../../algorithm/snopt.h"
8 #include "snopt_PAGMO.h"
9 #include "snfilewrapper_PAGMO.h"
10 #include "snoptProblem_PAGMO.h"
11 
12 using namespace std;
13 
14 snoptProblem_PAGMO::snoptProblem_PAGMO(const pagmo::problem::base& problema, pagmo::algorithm::snopt::preallocated_memory *di_comodo):
15  iSpecs(0), iSumm(0), iPrint(0), initCalled(0),cu((char *)&problema),lencu(500),ru((doublereal *)di_comodo), lenru(500)
16 {
17  init2zero();
18 
19  // Nothing incremented yet
20  fortranStyleObj = 0;
21  fortranStyleAG = 0;
22 
23  // iSpecs = 4;
24  // if (screen) iSumm = 6;
25  // iPrint = 15;
26 
27  // Create temporary memory for the call to sninit_.
28  // Lengths must all be >= 500.
29  lencw = 500;
30  leniw = 500;
31  lenrw = 500;
32  this->alloc( 500, 500, 500 );
33  // sninit_ "undefines" the optional parameters
34 
35  this->init();
36 }
37 
38 snoptProblem_PAGMO::~snoptProblem_PAGMO()
39 {
40  //Close print and spec files if necessary.
41  if (iPrint != 0 ) {
42  snclose_( &iPrint );
43  }
44  if (iSpecs != 0 ) {
45  snclose_( &iSpecs );
46  }
47 
48  //Delete work arrays.
49  delete [] rw;
50  delete [] iw;
51  delete [] cw;
52 }
53 
54 void snoptProblem_PAGMO::init2zero()
55 {
56  // Data that must be set by user.
57 
58  n = 0; neF = 0;
59 
60  ObjRow = 0;
61  ObjAdd = 0;
62 
63  iAfun = 0; jAvar = 0; A = 0;
64  iGfun = 0; jGvar = 0;
65 
66  x = 0; xlow = 0; xupp = 0; xmul = 0;
67  F = 0; Flow = 0; Fupp = 0; Fmul = 0;
68 
69  xstate = 0; Fstate = 0;
70  nxnames = 0; nFnames = 0;
71 
72  usrfun = 0;
73 
74  neA = -1; // Indicate that neA is yet to be assigned
75  neG = -1;
76  lenA = -1;
77  lenG = -1;
78 }
79 
80 void snoptProblem_PAGMO::userDataSet()
81 {
82  if ( n == 0) errMsgExit( "n" );
83  if ( neF == 0) errMsgExit( "neF");
84 
85  if ( x == 0 ) errMsgExit( "x" );
86  if ( xlow == 0 ) errMsgExit( "xlow" );
87  if ( xupp == 0 ) errMsgExit( "xupp" );
88  if ( xmul == 0 ) errMsgExit( "xmul" );
89 
90  if ( F == 0 ) errMsgExit( "F" );
91  if ( Flow == 0 ) errMsgExit( "Flow" );
92  if ( Fupp == 0 ) errMsgExit( "Fupp" );
93  if ( Fmul == 0 ) errMsgExit( "Fmul" );
94 
95  if ( xnames == 0 ) errMsgExit( "xnames" );
96  if ( Fnames == 0 ) errMsgExit( "Fnames" );
97  if ( nxnames == 0 ) errMsgExit( "nxnames" );
98  if ( nFnames == 0 ) errMsgExit( "nFnames" );
99 
100  if ( usrfun == 0 ) errMsgExit( "usrfun" );
101  if ( lenA == -1 ) errMsgExit( "lenA" );
102  if ( lenG == -1 ) errMsgExit( "lenG" );
103 
104  if ( (neA > 0) && (iAfun == 0) ) errMsgExit( "iAfun" );
105  if ( (neA > 0) && (jAvar == 0) ) errMsgExit( "jAvar" );
106  if ( neA > 0 && A == 0 ) errMsgExit( "A" );
107 
108  if ( neG > 0 && iGfun == 0 ) errMsgExit( "iGfun" );
109  if ( neG > 0 && jGvar == 0 ) errMsgExit( "jGvar" );
110 }
111 
112 void snoptProblem_PAGMO::errMsgExit( const char *var )
113 {
114  cerr << "****************************************************\n";
115  cerr << "Error: " << var << " must be set prior to call to " << endl
116  << "snoptProblem_PAGMO::solve() or snoptProblem_PAGMO::computeJac()!\n";
117  cerr << "****************************************************\n";
118  exit(1);
119 }
120 
121 void snoptProblem_PAGMO::setMemory()
122 {
123  int memoryGuess;
124  memoryGuess = this->snmema(mincw, miniw, minrw);
125  if ( mincw > lencw || miniw > leniw || minrw > lenrw ) {
126  // Reallocate memory while retaining the values set in sninit_
127  this->realloc( mincw, miniw, minrw );
128  // Save the lengths of the new work arrays.
129  this->setIntParameter("Total real workspace ", lenrw );
130  this->setIntParameter("Total integer workspace", leniw );
131 
132  // Did we have to guess values of neA and neG for snmema()
133  if ( memoryGuess == 1 ) {
134  this->computeJac();
135  memoryGuess = this->snmema(mincw, miniw, minrw);
136  assert( memoryGuess == 0 );
137  this->realloc( mincw, miniw, minrw );
138  this->setIntParameter("Total real workspace ", lenrw );
139  this->setIntParameter("Total integer workspace", leniw );
140  }
141  }
142 }
143 
144 void snoptProblem_PAGMO::alloc( integer alencw, integer aleniw, integer alenrw )
145 {
146  // Reset work array lengths.
147  lencw = alencw;
148  leniw = aleniw;
149  lenrw = alenrw;
150 
151  // Allocate new memory for work arrays.
152  cw = new char[8*lencw];
153  iw = new integer[leniw];
154  rw = new doublereal[lenrw];
155 }
156 
157 void snoptProblem_PAGMO::realloc( integer alencw, integer aleniw, integer alenrw )
158 {
159  // Call to this->alloc will overwrite these values => must save.
160  integer tlencw = lencw;
161  integer tleniw = leniw;
162  integer tlenrw = lenrw;
163 
164  // Call to this->alloc will create new values for cw, iw, rw => must save.
165  char *tcw = cw;
166  integer *tiw = iw;
167  doublereal *trw = rw;
168 
169  // Allocate new memory
170  this->alloc ( alencw, aleniw, alenrw );
171  // Copy in old values, previously set
172  this->memcpyIn( tcw, tiw, trw, tlencw, tleniw, tlenrw );
173 
174  // Delete temporary work arrays
175  delete [] tcw;
176  delete [] tiw;
177  delete [] trw;
178 }
179 
180 void snoptProblem_PAGMO::memcpyIn( char *tcw, integer *tiw, doublereal *trw,
181  integer tlencw, integer tleniw, integer tlenrw )
182 {
183  integer mlencw = lencw < tlencw ? lencw : tlencw;
184  integer mleniw = leniw < tleniw ? leniw : tleniw;
185  integer mlenrw = lenrw < tlenrw ? lenrw : tlenrw;
186 
187  memcpy( cw, tcw, 8*mlencw*sizeof( char ) );
188  memcpy( iw, tiw, mleniw*sizeof(integer));
189  memcpy( rw, trw, mlenrw*sizeof(doublereal));
190 }
191 
192 void snoptProblem_PAGMO::memcpyOut( char *tcw, integer *tiw, doublereal *trw,
193  integer tlencw, integer tleniw, integer tlenrw )
194 {
195  integer mlencw = lencw < tlencw ? lencw : tlencw;
196  integer mleniw = leniw < tleniw ? leniw : tleniw;
197  integer mlenrw = lenrw < tlenrw ? lenrw : tlenrw;
198 
199  memcpy( tcw, cw, 8*mlencw*sizeof( char ) );
200  memcpy( tiw, iw, mleniw*sizeof(integer));
201  memcpy( trw, rw, mlenrw*sizeof(doublereal));
202 }
203 
204 void snoptProblem_PAGMO::increment()
205 {
206  if( !fortranStyleObj ) {
207  //Increment row indicator.
208  ObjRow++;
209  fortranStyleObj = 1;
210  }
211 
212  if( !fortranStyleAG ) {
213  //Increment A indices.
214  for( int k = 0; k < neA; k++ ) {
215  iAfun[k]++; jAvar[k]++;
216  }
217  //Increment G indices.
218  for( int k = 0; k < neG; k++ ) {
219  iGfun[k]++; jGvar[k]++;
220  }
221  fortranStyleAG = 1;
222  }
223 }
224 
225 void snoptProblem_PAGMO::decrement()
226 {
227  if( fortranStyleObj ) {
228  //Decrement row indicator.
229  ObjRow--;
230  fortranStyleObj = 0;
231  }
232 
233  if (fortranStyleAG) {
234  //Decrement A indices.
235  for( int k = 0; k < neA; k++ ) {
236  iAfun[k]--; jAvar[k]--;
237  }
238  //Decrement G indices.
239  for( int k = 0; k < neG; k++ ) {
240  iGfun[k]--; jGvar[k]--;
241  }
242  fortranStyleAG = 0;
243  }
244 }
245 
246 void snoptProblem_PAGMO::computeJac()
247 {
248  //Ensures all user data has been initialized.
249  userDataSet();
250  this->snmema( mincw, miniw, minrw );
251  if ( mincw > lencw || miniw > leniw || minrw > lenrw ) {
252  // Reallocate memory while retaining the values set in sninit_
253  this->realloc( mincw, miniw, minrw );
254  // Save the lengths of the new work arrays.
255  this->setIntParameter("Total real workspace ", lenrw );
256  this->setIntParameter("Total integer workspace", leniw );
257  }
258  snjac_( &inform, &neF, &n, usrfun,
259  iAfun, jAvar, &lenA, &neA, A,
260  iGfun, jGvar, &lenG, &neG,
261  x, xlow, xupp, &mincw, &miniw, &minrw,
262  cu, &lencu, iw, &leniw, ru, &lenru, //User Workspaces!!! Contain the Pointer Structure that will be reconstructed inside the static snopt_function_
263  cw, &lencw, iw, &leniw, rw, &lenrw,
264  8*500, 8*500 );
265  //snjac_ will generate fortran style arrays.
266  fortranStyleAG = 1;
267 }
268 
269 int snoptProblem_PAGMO::snmema
270  ( integer &amincw, integer &aminiw, integer &aminrw)
271 {
272  int memoryGuess = 0;
273  integer nxname = 1; integer nfname = 1;
274  if ( neA < 0 ) {
275  neA = n*neF;
276  memoryGuess = 1;
277  }
278  if ( neG < 0 ) {
279  neG = n*neF;
280  memoryGuess = 1;
281  }
282  snmema_( &inform, &neF, &n, &nxname, &nfname, &neA, &neG,
283  &amincw, &aminiw, &aminrw, cw, &lencw, iw, &leniw,
284  rw, &lenrw, 8*500 );
285  return memoryGuess;
286 }
287 
288 void snoptProblem_PAGMO::init()
289 {
290  initCalled = 1;
291  sninit_( &iPrint, &iSumm, cw, &lencw, iw, &leniw, rw, &lenrw, 8*500 );
292 }
293 
294 void snoptProblem_PAGMO::setParameter( char *stropt )
295 {
296  assert( initCalled == 1 );
297 
298  integer iPrt = 0; // suppresses printing
299  integer iSum = 0;
300  integer stropt_len = strlen(stropt);
301  snset_( stropt, &iPrt, &iSum, &inform, cw, &lencw, iw, &leniw,
302  rw, &lenrw, stropt_len, 8*500 );
303 }
304 
305 void snoptProblem_PAGMO::getParameter( char *stroptin, char *stroptout )
306 {
307  assert( initCalled == 1 );
308  integer stroptin_len = strlen(stroptin);
309  integer stroptout_len = strlen(stroptout);
310  sngetc_( stroptin, stroptout, &inform, cw, &lencw, iw, &leniw,
311  rw, &lenrw, stroptin_len, stroptout_len, 8*500 );
312 }
313 
314 void snoptProblem_PAGMO::setIntParameter( const char *stropt, integer opt )
315 {
316  assert( initCalled == 1 );
317 
318  integer iPrt = 0; // suppresses printing
319  integer iSum = 0;
320  integer stropt_len = strlen(stropt);
321  snseti_( (char*)(void*)stropt, &opt, &iPrt, &iSum, &inform,
322  cw, &lencw, iw, &leniw, rw, &lenrw, stropt_len, 8*500 );
323 }
324 
325 void snoptProblem_PAGMO::getIntParameter( const char *stropt, integer &opt )
326 {
327  assert( initCalled == 1 );
328  integer stropt_len = strlen(stropt);
329  sngeti_( (char*)(void*)stropt, &opt, &inform, cw, &lencw, iw, &leniw,
330  rw, &lenrw, stropt_len, 8*500 );
331 }
332 
333 void snoptProblem_PAGMO::setRealParameter( const char *stropt, doublereal opt )
334 {
335  assert( initCalled == 1 );
336 
337  integer iPrt = 0; // suppresses printing
338  integer iSum = 0;
339  integer stropt_len = strlen(stropt);
340  snsetr_( (char*)(void*)stropt, &opt, &iPrt, &iSum, &inform,
341  cw, &lencw, iw, &leniw, rw, &lenrw, stropt_len, 8*500 );
342 }
343 
344 void snoptProblem_PAGMO::getRealParameter( const char *stropt, doublereal &opt )
345 {
346  assert( initCalled == 1 );
347  integer stropt_len = strlen(stropt);
348  sngetr_( (char*)(void*)stropt, &opt, &inform, cw, &lencw, iw, &leniw,
349  rw, &lenrw, stropt_len, 8*500 );
350 }
351 
352 void snoptProblem_PAGMO::solve( integer starttype )
353 {
354  assert( initCalled == 1 );
355  //Ensures all user data initialized.
356  userDataSet();
357  //Unlike snjac_ we also need neA and neG to be set.
358  if ( neA == -1 || neG == -1 ) {
359  cerr << "Warning: neA and neG must be set before calling"
360  << "snoptProblem_PAGMO::solve()\n";
361  exit(1);
362  }
363  integer npname = strlen(Prob);
364  integer nS, nInf;
365  doublereal sInf;
366  this->increment(); //Convert array entries to Fortran style
367  this->setMemory();
368  snopta_( &starttype, &neF, &n, &nxnames,
369  &nFnames,
370  &ObjAdd, &ObjRow, Prob,
371  usrfun, iAfun, jAvar, &lenA, &neA, A,
372  iGfun, jGvar, &lenG, &neG,
373  xlow, xupp, xnames, Flow,
374  Fupp, Fnames, x, xstate,
375  xmul, F, Fstate, Fmul,
376  &inform, &mincw, &miniw, &minrw, &nS, &nInf, &sInf,
377  cu, &lencu, iw, &leniw, ru, &lenru, //User Workspaces!!! Contain the Pointer Structure that will be reconstructed inside the static snopt_function_
378  cw, &lencw, iw, &leniw, rw, &lenrw,
379  npname, 8*(nxnames), 8*(nFnames), 8*500, 8*500);
380  this->decrement(); //Convert array entries to C style
381 }
382 
383 void snoptProblem_PAGMO::setPrintFile( const char aprintname[] )
384 {
385  assert( initCalled = 1 );
386  if (iPrint != 0 ) {
387  snclose_( &iPrint );
388  }
389  iPrint = 15;
390  strcpy( printname, aprintname ); prnt_len = strlen(printname);
391  snopenappend_( &iPrint, printname, &inform, prnt_len );
392  this->setIntParameter("Print file", iPrint);
393 }
394 
395 void snoptProblem_PAGMO::setSpecFile( char aspecname[] )
396 {
397  assert( initCalled == 1 );
398  if (iSpecs != 0 ) {
399  snclose_( &iSpecs );
400  }
401  iSpecs = 4;
402  strcpy( specname, aspecname ); spec_len = strlen(specname);
403  snfilewrapper_( specname, &iSpecs, &inform, cw, &lencw,
404  iw, &leniw, rw, &lenrw, spec_len, 8*lencw);
405  if( inform != 101 ){
406  printf("Warning: unable to find specs file %s \n", specname);
407  }
408 }
409 
410 void snoptProblem_PAGMO::setProblemSize( integer an, integer aneF )
411 {
412  // checkSet = checkSet+2;
413  n = an;
414  neF = aneF;
415 }
416 
417 void snoptProblem_PAGMO::setObjective( integer aObjRow, doublereal aObjAdd )
418 {
419  //checkSet = checkSet+2;
420  ObjRow = aObjRow;
421  ObjAdd = aObjAdd;
422 }
423 
424 void snoptProblem_PAGMO::setA( integer alenA, integer *aiAfun,
425  integer *ajAvar, doublereal *aA )
426 {
427  //checkSet = checkSet+4;
428  lenA = alenA;
429  iAfun = aiAfun;
430  jAvar = ajAvar;
431  A = aA;
432 }
433 
434 void snoptProblem_PAGMO::setNeA( integer aneA )
435 {
436  //checkSet = checkSet+1;
437  neA = aneA;
438 }
439 void snoptProblem_PAGMO::setG( integer alenG, integer *aiGfun,
440  integer *ajGvar)
441 {
442  //checkSet = checkSet+3;
443  lenG = alenG;
444  iGfun = aiGfun;
445  jGvar = ajGvar;
446 }
447 
448 void snoptProblem_PAGMO::setNeG( integer aneG )
449 {
450  //checkSet = checkSet+1;
451  neG = aneG;
452 }
453 
454 void snoptProblem_PAGMO::setX( doublereal *ax, doublereal *axlow, doublereal *axupp,
455  doublereal *axmul, integer *axstate )
456 {
457  //checkSet = checkSet+5;
458  x = ax;
459  xlow = axlow;
460  xupp = axupp;
461  xmul = axmul;
462  xstate = axstate;
463 }
464 
465 void snoptProblem_PAGMO::setF( doublereal *aF, doublereal *aFlow, doublereal *aFupp,
466  doublereal *aFmul, integer *aFstate )
467 {
468  //checkSet = checkSet+5;
469  F = aF;
470  Flow = aFlow;
471  Fupp = aFupp;
472  Fmul = aFmul;
473  Fstate = aFstate;
474 }
475 
476 void snoptProblem_PAGMO::setXNames( char *axnames, integer anxnames )
477 {
478  //checkSet = checkSet+2;
479  xnames = axnames;
480  nxnames = anxnames;
481 }
482 
483 void snoptProblem_PAGMO::setFNames( char *aFnames, integer anFnames )
484 {
485  //checkSet = checkSet+2;
486  Fnames = aFnames;
487  nFnames = anFnames;
488 }
489 
490 void snoptProblem_PAGMO::setProbName( const char *aProb )
491 {
492  //checkSet = checkSet+1;
493  sprintf(Prob, "%8s", aProb );
494 }
495 
496 void snoptProblem_PAGMO::setUserFun( My_fp ausrfun )
497 {
498  //checkSet = checkSet+1;
499  usrfun = ausrfun;
500 }
STL namespace.
Base problem class.
Definition: problem/base.h:148