7 #include "../toolkits/toolkits.h"
8 #include "../classes/classes.h"
9 #include "../shared/shared.h"
10 #include "../modules/modules.h"
11 #include "../solutionsequences/solutionsequences.h"
13 #if defined (_HAVE_M1QN3_)
15 extern "C" void *ctonbe_;
16 extern "C" void *ctcabe_;
17 extern "C" void *euclid_;
18 typedef void (*SimulFunc) (
long* indic,
long* n,
double* x,
double* pf,
double* g,
long [],
float [],
void* dzs);
19 extern "C" void m1qn3_ (
void f(
long* indic,
long* n,
double* x,
double* pf,
double* g,
long [],
float [],
void* dzs),
20 void **,
void **,
void **,
21 long *,
double [],
double *,
double [],
double*,
double *,
22 double *,
char [],
long *,
long *,
long *,
long *,
long *,
long *,
long [],
double [],
long *,
23 long *,
long *,
long [],
float [],
void* );
26 void simul(
long* indic,
long* n,
double* X,
double* pf,
double* G,
long izs[1],
float rzs[1],
void* dzs);
44 int intn,numberofvertices,num_controls,num_cost_functions,solution_type;
45 double *scaling_factors = NULL;
63 SimulFunc costfuncion = &simul;
64 void** prosca = &euclid_;
65 char normtype[] =
"dfn";
76 long niter = long(maxsteps);
77 long nsim = long(maxiter);
81 _assert_(intn==numberofvertices*num_controls);
88 for(
int c=0;c<num_controls;c++){
89 for(
int i=0;i<numberofvertices;i++){
90 int index = numberofvertices*c+i;
91 X[index] = X[index]/scaling_factors[c];
97 long ndz = 4*n+m*(2*n+1);
98 double* dz = xNew<double>(ndz);
102 _printf0_(
"Cost function f(x) | Gradient norm |g(x)| | List of contributions\n");
103 _printf0_(
"____________________________________________________________________\n");
106 m1qn3_struct mystruct;
108 mystruct.M = maxiter;
109 mystruct.N = num_cost_functions+1;
110 mystruct.Jlist = xNewZeroInit<IssmPDouble>(mystruct.M*mystruct.N);
111 mystruct.i = xNewZeroInit<int>(1);
115 simul(&indic,&n,X,&f,G,izs,rzs,(
void*)&mystruct);
121 m1qn3_(costfuncion,prosca,&ctonbe_,&ctcabe_,
122 &n,X,&f,G,&dxmin,&df1,
123 >tol,normtype,&impres,&io,imode,&omode,&niter,&nsim,iz,dz,&ndz,
124 &reverse,&indic,izs,rzs,(
void*)&mystruct);
128 case 0:
_printf0_(
" Stop requested (indic = 0)\n");
break;
129 case 1:
_printf0_(
" Convergence reached (gradient satisfies stopping criterion)\n");
break;
130 case 2:
_printf0_(
" Bad initialization\n");
break;
131 case 3:
_printf0_(
" Line search failure\n");
break;
132 case 4:
_printf0_(
" Maximum number of iterations exceeded\n");
break;
133 case 5:
_printf0_(
" Maximum number of function calls exceeded\n");
break;
134 case 6:
_printf0_(
" stopped on dxmin during line search\n");
break;
135 case 7:
_printf0_(
" <g,d> > 0 or <y,s> <0\n");
break;
136 default:
_printf0_(
" Unknown end condition\n");
144 for(
int c=0;c<num_controls;c++){
145 for(
int i=0;i<numberofvertices;i++){
146 int index = numberofvertices*c+i;
147 X[index] = X[index]*scaling_factors[c];
148 if(X[index]>XU[index]) X[index]=XU[index];
149 if(X[index]<XL[index]) X[index]=XL[index];
157 for(
int i=0;i<intn;i++) {
158 aX[i] = reCast<IssmDouble>(X[i]);
159 aG[i] = reCast<IssmDouble>(G[i]);
176 void (*solutioncore)(
FemModel*)=NULL;
186 xDelete<double>(scaling_factors);
187 xDelete<double>(mystruct.Jlist);
188 xDelete<int>(mystruct.i);
190 void simul(
long* indic,
long* n,
double* X,
double* pf,
double* G,
long izs[1],
float rzs[1],
void* dzs){
193 m1qn3_struct *input_struct = (m1qn3_struct*)dzs;
196 int JlistM = input_struct->M;
197 int JlistN = input_struct->N;
198 int *Jlisti = input_struct->i;
201 int num_responses,num_controls,numberofvertices,solution_type;
202 double* scaling_factors = NULL;
214 for(
int c=0;c<num_controls;c++){
215 for(
int i=0;i<numberofvertices;i++){
216 int index = numberofvertices*c+i;
217 X[index] = X[index]*scaling_factors[c];
218 if(X[index]>XU[index]) X[index]=XU[index];
219 if(X[index]<XL[index]) X[index]=XL[index];
224 for(
int i=0;i<*n;i++) aX[i] = reCast<IssmDouble>(X[i]);
232 void (*solutioncore)(
FemModel*)=NULL;
233 void (*adjointcore)(
FemModel*)=NULL;
245 *pf = reCast<double>(J);
246 _printf0_(
"f(x) = "<<setw(12)<<setprecision(7)<<*pf<<
" | ");
249 for(
int i=0;i<num_responses;i++) Jlist[(*Jlisti)*JlistN+i] = reCast<double>(Jtemp[i]);
250 Jlist[(*Jlisti)*JlistN+num_responses] = *pf;
251 xDelete<IssmDouble>(Jtemp);
258 for(
int i=0;i<num_responses;i++)
_printf0_(
" "<<setw(12)<<setprecision(7)<<Jlist[(*Jlisti)*JlistN+i]);
261 *Jlisti = (*Jlisti) +1;
274 for(
long i=0;i<*n;i++) G[i] = -reCast<double>(G2[i]);
275 xDelete<IssmDouble>(G2);
279 for(
int c=0;c<num_controls;c++){
280 for(
int i=0;i<numberofvertices;i++){
281 int index = numberofvertices*c+i;
282 if(X[index]>=XU[index]) G[index]=0.;
283 if(X[index]<=XL[index]) G[index]=0.;
284 G[index] = G[index]*scaling_factors[c];
285 X[index] = X[index]/scaling_factors[c];
286 Gnorm += G[index]*G[index];
292 _printf0_(
" "<<setw(12)<<setprecision(7)<<Gnorm<<
" |");
293 for(
int i=0;i<num_responses;i++)
_printf0_(
" "<<setw(12)<<setprecision(7)<<Jlist[(*Jlisti)*JlistN+i]);
297 *Jlisti = (*Jlisti) +1;
300 xDelete<double>(scaling_factors);
305 #endif //_HAVE_M1QN3_