Powell function minimization routine.
62 {
63 int pbIterNr;
67 double del, fp, fptt, t;
69 int ftol_reached=0;
70
71
72 if(verbose>0) printf("in powell(,,%d,%g,%d,,)\n", parNr, ftol, *iterNr);
73 if(verbose>1) {
74 printf("Initial parameter guesses and deltas:\n");
75 for(i=0; i<parNr; i++) printf(" %g %g\n", p[i], delta[i]);
76 }
77 *fret=nan("");
78 if(p==NULL) return(11);
79 if(delta==NULL) return(12);
80 if(parNr<1) return(21);
81 if(ftol<=0.0) return(22);
82 if(ftol>=1.0) return(23);
83 if((*iterNr)<1) return(24);
84
85
86 _powellFunc=_fun;
87 _powellFuncData=fundata;
88 iterMax=*iterNr;
89 _powell_ncom=parNr;
90
91 _powell_func_calls=1;
92 *fret=(*_powellFunc)(parNr, p, _powellFuncData);
93 if(verbose>10) printf("initial point fret=%g\n", *fret);
94 if(!isfinite(*fret)) {
95 if(verbose>0) printf("in powell(): objf failed at initial point.\n");
96 *fret=nan(""); return(2);
97 }
98
99 for(j=0; j<parNr; j++) origp[j]=pt[j]=p[j];
100
101 for(i=0; i<parNr; i++) if(fabs(delta[i])<1.0e-20) fixed[i]=1; else fixed[i]=0;
102
103
104 for(i=0; i<parNr; i++)
105 for(j=0; j<parNr; j++)
106 if(i==j) xi[i][j]=delta[i]; else xi[i][j]=0.0;
107
108
109 for(*iterNr=1; ; (*iterNr)++) {
110 if(verbose>2) printf(" iteration %d\n", *iterNr);
111 fp=*fret; ibig=0; del=0.0;
112
113
114 for(i=0; i<parNr; i++) {
115 if(fixed[i]) continue;
116 for(j=0; j<parNr; j++) if(fixed[j]) xit[j]=0.0; else xit[j]=xi[j][i];
117 fptt=*fret;
118
120 _powell_linmin(p, xit, parNr, fret, &pbIterNr);
121 if(verbose>3) printf("iterNr in _powell_linmin() with p%d: %d\n",
122 i, pbIterNr);
123 if(fabs(fptt-(*fret))>del) {del=fabs(fptt-(*fret)); ibig=i;}
124 }
125 if(verbose>20) printf("fret=%g fp=%g\n", *fret, fp);
126
127
128#if(0)
129 if(2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) break;
130#else
131 if(2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) {
132 if(ftol_reached>0 || (*iterNr)>=iterMax) break; else ftol_reached++;
133 } else ftol_reached=0;
134#endif
135 if((*iterNr)>=iterMax) {
136 if(verbose>0) printf("max iterations nr exceeded in powell().\n");
137 break;
138 }
139
140 for(j=0; j<parNr; j++) {
141 ptt[j]=2.0*p[j]-pt[j]; xit[j]=p[j]-pt[j];
142 pt[j]=p[j];
143 }
144 fptt=(*_powellFunc)(parNr, ptt, _powellFuncData); _powell_func_calls++;
145 if(fptt<fp) {
146 t=2.0*(fp-2.0*(*fret)+fptt)*_powell_sqr(fp-(*fret)-del)-del*_powell_sqr(fp-fptt);
147 if(t<0.0) {
149 _powell_linmin(p, xit, parNr, fret, &pbIterNr);
150 if(verbose>3) printf("iterNr in _powell_linmin(): %d\n", pbIterNr);
151 for(j=0; j<parNr; j++) {
152 xi[j][ibig]=xi[j][parNr-1]; xi[j][parNr-1]=xit[j];}
153 }
154 }
155 }
156 if(verbose>1) {
157 printf("iterNr := %d\n", *iterNr);
158 printf("nr of function calls := %d\n", _powell_func_calls);
159 }
160
161 if(isnan(*fret) || !isfinite(*fret)) {
162 if(verbose>10) printf("powell() fails and returns the initial point.\n");
163 if(verbose>11) {
164 if(isnan(*fret)) printf(" fret := NaN\n");
165 if(isfinite(*fret)) printf(" fret := overflow/underflow\n");
166 }
167
168 for(j=0; j<parNr; j++) p[j]=origp[j];
169
170 *fret=(*_powellFunc)(parNr, p, _powellFuncData);
171 return(3);
172 }
173
174 *fret=(*_powellFunc)(parNr, p, _powellFuncData);
175 if((*iterNr)>=iterMax) return(1);
176 if(verbose>0) printf("out of powell() in good order.\n");
177 return(0);
178}