ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/minimizers/OOPSEMinimizer.cpp
Revision: 1826
Committed: Thu Dec 2 05:04:20 2004 UTC (19 years, 7 months ago) by tim
File size: 16870 byte(s)
Log Message:
adding qulified name prefix std

File Contents

# Content
1 #include <math.h>
2
3 #include "minimizers/OOPSEMinimizer.hpp"
4
5 #include "integrators/Integrator.cpp"
6
7
8
9 OOPSEMinimizer::OOPSEMinimizer( SimInfo *theInfo, ForceFields* the_ff ,
10
11 MinimizerParameterSet * param) :
12
13 RealIntegrator(theInfo, the_ff), bShake(true), bVerbose(false) {
14
15 dumpOut = NULL;
16
17 statOut = NULL;
18
19
20
21 tStats = new Thermo(info);
22
23
24
25
26
27 paramSet = param;
28
29
30
31 calcDim();
32
33
34
35 curX = getCoor();
36
37 curG.resize(ndim);
38
39
40
41 preMove();
42
43 }
44
45
46
47 OOPSEMinimizer::~OOPSEMinimizer(){
48
49 delete tStats;
50
51 if(dumpOut)
52
53 delete dumpOut;
54
55 if(statOut)
56
57 delete statOut;
58
59 delete paramSet;
60
61 }
62
63
64
65 void OOPSEMinimizer::calcEnergyGradient(vector<double>& x, std::vector<double>& grad,
66
67 double& energy, int& status){
68
69
70
71 DirectionalAtom* dAtom;
72
73 int index;
74
75 double force[3];
76
77 double dAtomGrad[6];
78
79 int shakeStatus;
80
81
82
83 status = 1;
84
85
86
87 setCoor(x);
88
89
90
91 if (nConstrained && bShake){
92
93 shakeStatus = shakeR();
94
95 }
96
97
98
99 calcForce(1, 1);
100
101
102
103 if (nConstrained && bShake){
104
105 shakeStatus = shakeF();
106
107 }
108
109
110
111 x = getCoor();
112
113
114
115
116
117 index = 0;
118
119
120
121 for(int i = 0; i < integrableObjects.size(); i++){
122
123
124
125 if (integrableObjects[i]->isDirectional()) {
126
127
128
129 integrableObjects[i]->getGrad(dAtomGrad);
130
131
132
133 //gradient is equal to -f
134
135 grad[index++] = -dAtomGrad[0];
136
137 grad[index++] = -dAtomGrad[1];
138
139 grad[index++] = -dAtomGrad[2];
140
141 grad[index++] = -dAtomGrad[3];
142
143 grad[index++] = -dAtomGrad[4];
144
145 grad[index++] = -dAtomGrad[5];
146
147
148
149 }
150
151 else{
152
153 integrableObjects[i]->getFrc(force);
154
155
156
157 grad[index++] = -force[0];
158
159 grad[index++] = -force[1];
160
161 grad[index++] = -force[2];
162
163
164
165 }
166
167
168
169 }
170
171
172
173 energy = tStats->getPotential();
174
175
176
177 }
178
179
180
181 void OOPSEMinimizer::setCoor(vector<double>& x){
182
183
184
185 DirectionalAtom* dAtom;
186
187 int index;
188
189 double position[3];
190
191 double eulerAngle[3];
192
193
194
195
196
197 index = 0;
198
199
200
201 for(int i = 0; i < integrableObjects.size(); i++){
202
203
204
205 position[0] = x[index++];
206
207 position[1] = x[index++];
208
209 position[2] = x[index++];
210
211
212
213 integrableObjects[i]->setPos(position);
214
215
216
217 if (integrableObjects[i]->isDirectional()){
218
219
220
221 eulerAngle[0] = x[index++];
222
223 eulerAngle[1] = x[index++];
224
225 eulerAngle[2] = x[index++];
226
227
228
229 integrableObjects[i]->setEuler(eulerAngle[0],
230
231 eulerAngle[1],
232
233 eulerAngle[2]);
234
235
236
237 }
238
239
240
241 }
242
243
244
245 }
246
247
248
249 std::vector<double> OOPSEMinimizer::getCoor(){
250
251
252
253 DirectionalAtom* dAtom;
254
255 int index;
256
257 double position[3];
258
259 double eulerAngle[3];
260
261 std::vector<double> x;
262
263
264
265 x.resize(getDim());
266
267
268
269 index = 0;
270
271
272
273 for(int i = 0; i < integrableObjects.size(); i++){
274
275 position = integrableObjects[i]->getPos();
276
277
278
279 x[index++] = position[0];
280
281 x[index++] = position[1];
282
283 x[index++] = position[2];
284
285
286
287 if (integrableObjects[i]->isDirectional()){
288
289
290
291 integrableObjects[i]->getEulerAngles(eulerAngle);
292
293
294
295 x[index++] = eulerAngle[0];
296
297 x[index++] = eulerAngle[1];
298
299 x[index++] = eulerAngle[2];
300
301
302
303 }
304
305
306
307 }
308
309
310
311 return x;
312
313
314
315 }
316
317
318
319
320
321 int OOPSEMinimizer::shakeR(){
322
323 int i, j;
324
325 int done;
326
327 double posA[3], posB[3];
328
329 double velA[3], velB[3];
330
331 double pab[3];
332
333 double rab[3];
334
335 int a, b, ax, ay, az, bx, by, bz;
336
337 double rma, rmb;
338
339 double dx, dy, dz;
340
341 double rpab;
342
343 double rabsq, pabsq, rpabsq;
344
345 double diffsq;
346
347 double gab;
348
349 int iteration;
350
351
352
353 for (i = 0; i < nAtoms; i++){
354
355 moving[i] = 0;
356
357 moved[i] = 1;
358
359 }
360
361
362
363 iteration = 0;
364
365 done = 0;
366
367 while (!done && (iteration < maxIteration)){
368
369 done = 1;
370
371 for (i = 0; i < nConstrained; i++){
372
373 a = constrainedA[i];
374
375 b = constrainedB[i];
376
377
378
379 ax = (a * 3) + 0;
380
381 ay = (a * 3) + 1;
382
383 az = (a * 3) + 2;
384
385
386
387 bx = (b * 3) + 0;
388
389 by = (b * 3) + 1;
390
391 bz = (b * 3) + 2;
392
393
394
395 if (moved[a] || moved[b]){
396
397 posA = atoms[a]->getPos();
398
399 posB = atoms[b]->getPos();
400
401
402
403 for (j = 0; j < 3; j++)
404
405 pab[j] = posA[j] - posB[j];
406
407
408
409 //periodic boundary condition
410
411
412
413 info->wrapVector(pab);
414
415
416
417 pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
418
419
420
421 rabsq = constrainedDsqr[i];
422
423 diffsq = rabsq - pabsq;
424
425
426
427 // the original rattle code from alan tidesley
428
429 if (fabs(diffsq) > (tol * rabsq * 2)){
430
431 rab[0] = oldPos[ax] - oldPos[bx];
432
433 rab[1] = oldPos[ay] - oldPos[by];
434
435 rab[2] = oldPos[az] - oldPos[bz];
436
437
438
439 info->wrapVector(rab);
440
441
442
443 rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
444
445
446
447 rpabsq = rpab * rpab;
448
449
450
451
452
453 if (rpabsq < (rabsq * -diffsq)){
454
455 #ifdef IS_MPI
456
457 a = atoms[a]->getGlobalIndex();
458
459 b = atoms[b]->getGlobalIndex();
460
461 #endif //is_mpi
462
463 //cerr << "Waring: constraint failure" << endl;
464
465 gab = sqrt(rabsq/pabsq);
466
467 rab[0] = (posA[0] - posB[0])*gab;
468
469 rab[1]= (posA[1] - posB[1])*gab;
470
471 rab[2] = (posA[2] - posB[2])*gab;
472
473
474
475 info->wrapVector(rab);
476
477
478
479 rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
480
481
482
483 }
484
485
486
487 //rma = 1.0 / atoms[a]->getMass();
488
489 //rmb = 1.0 / atoms[b]->getMass();
490
491 rma = 1.0;
492
493 rmb =1.0;
494
495
496
497 gab = diffsq / (2.0 * (rma + rmb) * rpab);
498
499
500
501 dx = rab[0] * gab;
502
503 dy = rab[1] * gab;
504
505 dz = rab[2] * gab;
506
507
508
509 posA[0] += rma * dx;
510
511 posA[1] += rma * dy;
512
513 posA[2] += rma * dz;
514
515
516
517 atoms[a]->setPos(posA);
518
519
520
521 posB[0] -= rmb * dx;
522
523 posB[1] -= rmb * dy;
524
525 posB[2] -= rmb * dz;
526
527
528
529 atoms[b]->setPos(posB);
530
531
532
533 moving[a] = 1;
534
535 moving[b] = 1;
536
537 done = 0;
538
539 }
540
541 }
542
543 }
544
545
546
547 for (i = 0; i < nAtoms; i++){
548
549 moved[i] = moving[i];
550
551 moving[i] = 0;
552
553 }
554
555
556
557 iteration++;
558
559 }
560
561
562
563 if (!done){
564
565 cerr << "Waring: can not constraint within maxIteration" << endl;
566
567 return -1;
568
569 }
570
571 else
572
573 return 1;
574
575 }
576
577
578
579
580
581 //remove constraint force along the bond direction
582
583 int OOPSEMinimizer::shakeF(){
584
585 int i, j;
586
587 int done;
588
589 double posA[3], posB[3];
590
591 double frcA[3], frcB[3];
592
593 double rab[3], fpab[3];
594
595 int a, b, ax, ay, az, bx, by, bz;
596
597 double rma, rmb;
598
599 double rvab;
600
601 double gab;
602
603 double rabsq;
604
605 double rfab;
606
607 int iteration;
608
609
610
611 for (i = 0; i < nAtoms; i++){
612
613 moving[i] = 0;
614
615 moved[i] = 1;
616
617 }
618
619
620
621 done = 0;
622
623 iteration = 0;
624
625 while (!done && (iteration < maxIteration)){
626
627 done = 1;
628
629
630
631 for (i = 0; i < nConstrained; i++){
632
633 a = constrainedA[i];
634
635 b = constrainedB[i];
636
637
638
639 ax = (a * 3) + 0;
640
641 ay = (a * 3) + 1;
642
643 az = (a * 3) + 2;
644
645
646
647 bx = (b * 3) + 0;
648
649 by = (b * 3) + 1;
650
651 bz = (b * 3) + 2;
652
653
654
655 if (moved[a] || moved[b]){
656
657
658
659 posA = atoms[a]->getPos();
660
661 posB = atoms[b]->getPos();
662
663
664
665 for (j = 0; j < 3; j++)
666
667 rab[j] = posA[j] - posB[j];
668
669
670
671 info->wrapVector(rab);
672
673
674
675 atoms[a]->getFrc(frcA);
676
677 atoms[b]->getFrc(frcB);
678
679
680
681 //rma = 1.0 / atoms[a]->getMass();
682
683 //rmb = 1.0 / atoms[b]->getMass();
684
685 rma = 1.0;
686
687 rmb = 1.0;
688
689
690
691
692
693 fpab[0] = frcA[0] * rma - frcB[0] * rmb;
694
695 fpab[1] = frcA[1] * rma - frcB[1] * rmb;
696
697 fpab[2] = frcA[2] * rma - frcB[2] * rmb;
698
699
700
701
702
703 gab=fpab[0] * fpab[0] + fpab[1] * fpab[1] + fpab[2] * fpab[2];
704
705
706
707 if (gab < 1.0)
708
709 gab = 1.0;
710
711
712
713 rabsq = rab[0] * rab[0] + rab[1] * rab[1] + rab[2] * rab[2];
714
715 rfab = rab[0] * fpab[0] + rab[1] * fpab[1] + rab[2] * fpab[2];
716
717
718
719 if (fabs(rfab) > sqrt(rabsq*gab) * 0.00001){
720
721
722
723 gab = -rfab /(rabsq*(rma + rmb));
724
725
726
727 frcA[0] = rab[0] * gab;
728
729 frcA[1] = rab[1] * gab;
730
731 frcA[2] = rab[2] * gab;
732
733
734
735 atoms[a]->addFrc(frcA);
736
737
738
739
740
741 frcB[0] = -rab[0] * gab;
742
743 frcB[1] = -rab[1] * gab;
744
745 frcB[2] = -rab[2] * gab;
746
747
748
749 atoms[b]->addFrc(frcB);
750
751
752
753 moving[a] = 1;
754
755 moving[b] = 1;
756
757 done = 0;
758
759 }
760
761 }
762
763 }
764
765
766
767 for (i = 0; i < nAtoms; i++){
768
769 moved[i] = moving[i];
770
771 moving[i] = 0;
772
773 }
774
775
776
777 iteration++;
778
779 }
780
781
782
783 if (!done){
784
785 cerr << "Waring: can not constraint within maxIteration" << endl;
786
787 return -1;
788
789 }
790
791 else
792
793 return 1;
794
795 }
796
797
798
799
800
801
802
803 //calculate the value of object function
804
805 void OOPSEMinimizer::calcF(){
806
807 calcEnergyGradient(curX, curG, curF, egEvalStatus);
808
809 }
810
811
812
813 void OOPSEMinimizer::calcF(vector<double>& x, double&f, int& status){
814
815 std::vector<double> tempG;
816
817 tempG.resize(x.size());
818
819
820
821 calcEnergyGradient(x, tempG, f, status);
822
823 }
824
825
826
827 //calculate the gradient
828
829 void OOPSEMinimizer::calcG(){
830
831 calcEnergyGradient(curX, curG, curF, egEvalStatus);
832
833 }
834
835
836
837 void OOPSEMinimizer::calcG(vector<double>& x, std::vector<double>& g, double& f, int& status){
838
839 calcEnergyGradient(x, g, f, status);
840
841 }
842
843
844
845 void OOPSEMinimizer::calcDim(){
846
847 DirectionalAtom* dAtom;
848
849
850
851 ndim = 0;
852
853
854
855 for(int i = 0; i < integrableObjects.size(); i++){
856
857 ndim += 3;
858
859 if (integrableObjects[i]->isDirectional())
860
861 ndim += 3;
862
863 }
864
865 }
866
867
868
869 void OOPSEMinimizer::setX(vector < double > & x){
870
871
872
873 if (x.size() != ndim && bVerbose){
874
875 //sprintf(painCave.errMsg,
876
877 // "OOPSEMinimizer Error: dimesion of x and curX does not match\n");
878
879 // painCave.isFatal = 1;
880
881 // simError();
882
883 }
884
885
886
887 curX = x;
888
889 }
890
891
892
893 void OOPSEMinimizer::setG(vector < double > & g){
894
895
896
897 if (g.size() != ndim && bVerbose){
898
899 //sprintf(painCave.errMsg,
900
901 // "OOPSEMinimizer Error: dimesion of g and curG does not match\n");
902
903 // painCave.isFatal = 1;
904
905 //simError();
906
907 }
908
909
910
911 curG = g;
912
913 }
914
915
916
917 void OOPSEMinimizer::writeOut(vector<double>& x, double iter){
918
919
920
921 setX(x);
922
923
924
925 calcG();
926
927
928
929 dumpOut->writeDump(iter);
930
931 statOut->writeStat(iter);
932
933 }
934
935
936
937
938
939 void OOPSEMinimizer::printMinimizerInfo(){
940
941 cout << "--------------------------------------------------------------------" << endl;
942
943 cout << minimizerName << endl;
944
945 cout << "minimization parameter set" << endl;
946
947 cout << "function tolerance = " << paramSet->getFTol() << endl;
948
949 cout << "gradient tolerance = " << paramSet->getGTol() << endl;
950
951 cout << "step tolerance = "<< paramSet->getFTol() << endl;
952
953 cout << "absolute gradient tolerance = " << endl;
954
955 cout << "max iteration = " << paramSet->getMaxIteration() << endl;
956
957 cout << "max line search iteration = " << paramSet->getLineSearchMaxIteration() <<endl;
958
959 cout << "shake algorithm = " << bShake << endl;
960
961 cout << "--------------------------------------------------------------------" << endl;
962
963
964
965 }
966
967
968
969 /**
970
971 * In thoery, we need to find the minimum along the search direction
972
973 * However, function evaluation is too expensive.
974
975 * At the very begining of the problem, we check the search direction and make sure
976
977 * it is a descent direction
978
979 * we will compare the energy of two end points,
980
981 * if the right end point has lower energy, we just take it
982
983 *
984
985 *
986
987 *
988
989 */
990
991
992
993 int OOPSEMinimizer::doLineSearch(vector<double>& direction, double stepSize){
994
995 std::vector<double> xa;
996
997 std::vector<double> xb;
998
999 std::vector<double> xc;
1000
1001 std::vector<double> ga;
1002
1003 std::vector<double> gb;
1004
1005 std::vector<double> gc;
1006
1007 double fa;
1008
1009 double fb;
1010
1011 double fc;
1012
1013 double a;
1014
1015 double b;
1016
1017 double c;
1018
1019 int status;
1020
1021 double initSlope;
1022
1023 double slopeA;
1024
1025 double slopeB;
1026
1027 double slopeC;
1028
1029 bool foundLower;
1030
1031 int iter;
1032
1033 int maxLSIter;
1034
1035 double mu;
1036
1037 double eta;
1038
1039 double ftol;
1040
1041 double lsTol;
1042
1043
1044
1045 xa.resize(ndim);
1046
1047 xb.resize(ndim);
1048
1049 xc.resize(ndim);
1050
1051
1052
1053 ga.resize(ndim);
1054
1055 gb.resize(ndim);
1056
1057 gc.resize(ndim);
1058
1059
1060
1061 a = 0.0;
1062
1063 fa = curF;
1064
1065 xa = curX;
1066
1067 ga = curG;
1068
1069 c = a + stepSize;
1070
1071 ftol = paramSet->getFTol();
1072
1073 lsTol = paramSet->getLineSearchTol();
1074
1075
1076
1077 //calculate the derivative at a = 0
1078
1079 slopeA = 0;
1080
1081 for (size_t i = 0; i < ndim; i++)
1082
1083 slopeA += curG[i]*direction[i];
1084
1085
1086
1087 initSlope = slopeA;
1088
1089
1090
1091 // if going uphill, use negative gradient as searching direction
1092
1093 if (slopeA > 0) {
1094
1095
1096
1097 if (bVerbose){
1098
1099 cout << "LineSearch Warning: initial searching direction is not a descent searching direction, "
1100
1101 << " use negative gradient instead. Therefore, finding a smaller vaule of function "
1102
1103 << " is guaranteed"
1104
1105 << endl;
1106
1107 }
1108
1109
1110
1111 for (size_t i = 0; i < ndim; i++)
1112
1113 direction[i] = -curG[i];
1114
1115
1116
1117 for (size_t i = 0; i < ndim; i++)
1118
1119 slopeA += curG[i]*direction[i];
1120
1121
1122
1123 initSlope = slopeA;
1124
1125 }
1126
1127
1128
1129 // Take a trial step
1130
1131 for(size_t i = 0; i < ndim; i++)
1132
1133 xc[i] = curX[i] + direction[i] * c;
1134
1135
1136
1137 calcG(xc, gc, fc, status);
1138
1139
1140
1141 if (status < 0){
1142
1143 if (bVerbose)
1144
1145 cerr << "Function Evaluation Error" << endl;
1146
1147 }
1148
1149
1150
1151 //calculate the derivative at c
1152
1153 slopeC = 0;
1154
1155 for (size_t i = 0; i < ndim; i++)
1156
1157 slopeC += gc[i]*direction[i];
1158
1159
1160
1161 // found a lower point
1162
1163 if (fc < fa) {
1164
1165 curX = xc;
1166
1167 curG = gc;
1168
1169 curF = fc;
1170
1171 return LS_SUCCEED;
1172
1173 }
1174
1175 else {
1176
1177
1178
1179 if (slopeC > 0)
1180
1181 stepSize *= 0.618034;
1182
1183 }
1184
1185
1186
1187 maxLSIter = paramSet->getLineSearchMaxIteration();
1188
1189
1190
1191 iter = 0;
1192
1193
1194
1195 do {
1196
1197 // Select a new trial point.
1198
1199 // If the derivatives at points a & c have different sign we use cubic interpolate
1200
1201 //if (slopeC > 0){
1202
1203 eta = 3 *(fa -fc) /(c - a) + slopeA + slopeC;
1204
1205 mu = sqrt(eta * eta - slopeA * slopeC);
1206
1207 b = a + (c - a) * (1 - (slopeC + mu - eta) /(slopeC - slopeA + 2 * mu));
1208
1209
1210
1211 if (b < lsTol){
1212
1213 if (bVerbose)
1214
1215 cout << "stepSize is less than line search tolerance" << endl;
1216
1217 break;
1218
1219 }
1220
1221 //}
1222
1223
1224
1225 // Take a trial step to this new point - new coords in xb
1226
1227 for(size_t i = 0; i < ndim; i++)
1228
1229 xb[i] = curX[i] + direction[i] * b;
1230
1231
1232
1233 //function evaluation
1234
1235 calcG(xb, gb, fb, status);
1236
1237
1238
1239 if (status < 0){
1240
1241 if (bVerbose)
1242
1243 cerr << "Function Evaluation Error" << endl;
1244
1245 }
1246
1247
1248
1249 //calculate the derivative at c
1250
1251 slopeB = 0;
1252
1253 for (size_t i = 0; i < ndim; i++)
1254
1255 slopeB += gb[i]*direction[i];
1256
1257
1258
1259 //Amijo Rule to stop the line search
1260
1261 if (fb <= curF + initSlope * ftol * b) {
1262
1263 curF = fb;
1264
1265 curX = xb;
1266
1267 curG = gb;
1268
1269 return LS_SUCCEED;
1270
1271 }
1272
1273
1274
1275 if (slopeB <0 && fb < fa) {
1276
1277 //replace a by b
1278
1279 fa = fb;
1280
1281 a = b;
1282
1283 slopeA = slopeB;
1284
1285
1286
1287 // swap coord a/b
1288
1289 std::swap(xa, xb);
1290
1291 std::swap(ga, gb);
1292
1293 }
1294
1295 else {
1296
1297 //replace c by b
1298
1299 fc = fb;
1300
1301 c = b;
1302
1303 slopeC = slopeB;
1304
1305
1306
1307 // swap coord b/c
1308
1309 std::swap(gb, gc);
1310
1311 std::swap(xb, xc);
1312
1313 }
1314
1315
1316
1317
1318
1319 iter++;
1320
1321 } while((fb > fa || fb > fc) && (iter < maxLSIter));
1322
1323
1324
1325 if(fb < curF || iter >= maxLSIter) {
1326
1327 //could not find a lower value, we might just go uphill.
1328
1329 return LS_ERROR;
1330
1331 }
1332
1333
1334
1335 //select the end point
1336
1337
1338
1339 if (fa <= fc) {
1340
1341 curX = xa;
1342
1343 curG = ga;
1344
1345 curF = fa;
1346
1347 }
1348
1349 else {
1350
1351 curX = xc;
1352
1353 curG = gc;
1354
1355 curF = fc;
1356
1357 }
1358
1359
1360
1361 return LS_SUCCEED;
1362
1363
1364
1365 }
1366
1367
1368
1369 void OOPSEMinimizer::minimize(){
1370
1371
1372
1373 int convgStatus;
1374
1375 int stepStatus;
1376
1377 int maxIter;
1378
1379 int writeFrq;
1380
1381 int nextWriteIter;
1382
1383
1384
1385 if (bVerbose)
1386
1387 printMinimizerInfo();
1388
1389
1390
1391 dumpOut = new DumpWriter(info);
1392
1393 statOut = new StatWriter(info);
1394
1395
1396
1397 init();
1398
1399
1400
1401 writeFrq = paramSet->getWriteFrq();
1402
1403 nextWriteIter = writeFrq;
1404
1405
1406
1407 maxIter = paramSet->getMaxIteration();
1408
1409
1410
1411 for (curIter = 1; curIter <= maxIter; curIter++){
1412
1413
1414
1415 stepStatus = step();
1416
1417
1418
1419 if (nConstrained && bShake)
1420
1421 preMove();
1422
1423
1424
1425 if (stepStatus < 0){
1426
1427 saveResult();
1428
1429 minStatus = MIN_LSERROR;
1430
1431 cerr << "OOPSEMinimizer Error: line search error, please try a small stepsize" << endl;
1432
1433 return;
1434
1435 }
1436
1437
1438
1439 if (curIter == nextWriteIter){
1440
1441 nextWriteIter += writeFrq;
1442
1443 writeOut(curX, curIter);
1444
1445 }
1446
1447
1448
1449 convgStatus = checkConvg();
1450
1451
1452
1453 if (convgStatus > 0){
1454
1455 saveResult();
1456
1457 minStatus = MIN_CONVERGE;
1458
1459 return;
1460
1461 }
1462
1463
1464
1465 prepareStep();
1466
1467
1468
1469 }
1470
1471
1472
1473
1474
1475 if (bVerbose) {
1476
1477 cout << "OOPSEMinimizer Warning: "
1478
1479 << minimizerName << " algorithm did not converge within "
1480
1481 << maxIter << " iteration" << endl;
1482
1483 }
1484
1485 minStatus = MIN_MAXITER;
1486
1487 saveResult();
1488
1489
1490
1491 }
1492

Properties

Name Value
svn:executable *