cloudy
trunk
|
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and 00002 * others. For conditions of distribution and use see copyright notice in license.txt */ 00003 /*optimize_phymir Peter van Hoof's optimization routine */ 00004 00005 #if defined(unix) || defined(__unix) || defined(__unix__) 00006 /* __unix may not be defined here (this is done in cddefines.h), so we have to cover all bets */ 00007 /* this statement needs to be in front of cddefines.h, because cddefines.h includes <stdio.h>, 00008 * which in turn includes <sys/types.h> under HP/UX 10.20. If _INCLUDE_POSIX_SOURCE is not 00009 * defined before we enter cddefines.h, pid_t will not be defined and the compilation will fail. 00010 * Error reported by Richard Hook. */ 00011 #define _INCLUDE_POSIX_SOURCE 00012 #endif 00013 #include "cddefines.h" 00014 #include "version.h" 00015 #include "optimize.h" 00016 #ifdef __unix 00017 #include <stddef.h> 00018 #include <sys/types.h> 00019 #include <sys/wait.h> 00020 #include <unistd.h> 00021 #endif 00022 00023 #define F0 1.4142136f 00024 #define F1 0.7071068f 00025 #define F2 0.1f 00026 00027 00028 /* The optimization algorithm Phymir and its subsidiary routines have been 00029 * written by Peter van Hoof. An article describing the algorithm is 00030 * currently in preparation and is intended to be submitted to New Astronomy. */ 00031 00032 /* the a2's in the prototypes are necessary to prevent a bug in lclint 2.5m */ 00033 STATIC void phygrm(realnum a2[][LIMPAR],long); 00034 STATIC void wr_continue(realnum,long,realnum a2[][LIMPAR],const realnum[],const realnum[], 00035 const realnum[],const realnum[],realnum,realnum,realnum,long,long,const realnum[], 00036 const realnum[],const char[],const char[],const char[],const char*); 00037 STATIC void rd_continue(realnum*,long*,realnum a2[][LIMPAR],realnum[],realnum[],realnum[],realnum[], 00038 realnum*,realnum*,realnum*,long*,long*,realnum[],realnum[],char[],char[],char[],const char*); 00039 #ifdef __unix 00040 STATIC void cpfile(const char*); 00041 STATIC void wr_block(void*,size_t,const char*); 00042 STATIC void rd_block(void*,size_t,const char*); 00043 #endif 00044 00045 00046 void optimize_phymir(realnum xc[], 00047 realnum del[], 00048 long int nvarPhymir, 00049 realnum *ymin, 00050 realnum toler) 00051 { 00052 #define DELTA(i,j) (((i) == (j)) ? 1.f : 0.f) 00053 00054 char chDum1[STDLEN], 00055 chDum2[STDLEN], 00056 chDum3[STDLEN]; 00057 bool lgFinish, 00058 lgNegd2, 00059 lgNewCnt, 00060 lgRead; 00061 long int i, 00062 imax, 00063 j, 00064 jj, 00065 jmin=0, 00066 limcp, 00067 nvarcp; 00068 realnum a2[LIMPAR][LIMPAR], 00069 amax, 00070 c1[LIMPAR], 00071 c2[LIMPAR], 00072 d1, 00073 d2, 00074 diff, 00075 dmax=0.f, 00076 dold=0.f, 00077 r1, 00078 r2, 00079 sgn, 00080 temp, 00081 vers, 00082 vpusedPhymir, 00083 xcold[LIMPAR], 00084 xhlp[LIMPAR], 00085 xnrm, 00086 xp[LIMPAR][2*LIMPAR + 1], 00087 yp[2*LIMPAR + 1]; 00088 # ifdef __unix 00089 long int currentCPU; 00090 int stat; 00091 char fnam1[20], 00092 fnam2[20]; 00093 pid_t pid; 00094 # endif 00095 00096 DEBUG_ENTRY( "optimize_phymir()" ); 00097 00098 if( nvarPhymir > LIMPAR ) 00099 { 00100 fprintf( ioQQQ, "optimize_phymir: too many parameters are varied, increase LIMPAR\n" ); 00101 cdEXIT(EXIT_FAILURE); 00102 } 00103 00104 /* >>chng 06 jan 02, fix uninitialized var problem detected by valgrind/purify, PvH */ 00105 memset( chDum1, '\0', STDLEN ); 00106 memset( chDum2, '\0', STDLEN ); 00107 memset( chDum3, '\0', STDLEN ); 00108 00109 for( i=0; i < LIMPAR; ++i ) 00110 { 00111 c1[i] = -FLT_MAX; 00112 c2[i] = -FLT_MAX; 00113 xcold[i] = -FLT_MAX; 00114 for( j=0; j < LIMPAR; ++j ) 00115 { 00116 a2[i][j] = -FLT_MAX; 00117 } 00118 } 00119 00120 optimize.nOptimiz = 0; 00121 # ifdef __unix 00122 currentCPU = 0; 00123 # endif 00124 lgFinish = false; 00125 lgRead = optimize.lgOptCont; 00126 if( optimize.lgOptCont ) 00127 goto L_20; 00128 00129 /* initialize hypercube dimensions and center */ 00130 dmax = 0.f; 00131 for( i=0; i < nvarPhymir; i++ ) 00132 { 00133 temp = (realnum)fabs(del[i]); 00134 dmax = MAX2(dmax,temp); 00135 } 00136 00137 dold = dmax; 00138 for( i=0; i < nvarPhymir; i++ ) 00139 { 00140 xcold[i] = xc[i] + 10.f*toler; 00141 c1[i] = (realnum)fabs(del[i])/dmax; 00142 c2[i] = c1[i]; 00143 xp[i][0] = xc[i]; 00144 optimize.vparm[0][i] = xc[i]; 00145 /* this is done by child process and is lost, so copy code to parent process */ 00146 if( optimize.lgParallel ) 00147 { 00148 vpusedPhymir = MIN2(optimize.vparm[0][i],optimize.varang[i][1]); 00149 vpusedPhymir = MAX2(vpusedPhymir,optimize.varang[i][0]); 00150 optimize.varmax[i] = MAX2(optimize.varmax[i],vpusedPhymir); 00151 optimize.varmin[i] = MIN2(optimize.varmin[i],vpusedPhymir); 00152 } 00153 } 00154 # ifdef __unix 00155 if( optimize.lgParallel ) 00156 { 00157 /* flush all open files */ 00158 fflush(NULL); 00159 pid = fork(); 00160 if( pid == 0 ) 00161 { 00162 /* this is child process so execute */ 00163 sprintf(fnam1,"chi2_%ld",0L); 00164 sprintf(fnam2,"output_%ld",0L); 00165 /* each child should have its own output file */ 00166 ioQQQ = open_data( fnam2, "w", AS_LOCAL_ONLY ); 00167 /* fail-safe in case optimize_func crashes */ 00168 yp[0] = FLT_MAX; 00169 wr_block(&yp[0],(size_t)sizeof(realnum),fnam1); 00170 yp[0] = (realnum)optimize_func(xc); 00171 wr_block(&yp[0],(size_t)sizeof(realnum),fnam1); 00172 fclose( ioQQQ ); 00173 ioQQQ = NULL; 00174 cdEXIT(EXIT_SUCCESS); 00175 } 00176 else 00177 { 00178 /* parent process waits, this way all initializations remain intact */ 00179 pid = wait(&stat); 00180 sprintf(fnam1,"chi2_%ld",0L); 00181 sprintf(fnam2,"output_%ld",0L); 00182 rd_block(&yp[0],(size_t)sizeof(realnum),fnam1); 00183 remove(fnam1); 00184 cpfile(fnam2); 00185 remove(fnam2); 00186 } 00187 /* this was incremented by child process and is lost, so copy code here */ 00188 optimize.nOptimiz++; 00189 } 00190 else 00191 { 00192 yp[0] = (realnum)optimize_func(xc); 00193 } 00194 # else 00195 /* on non-UNIX machines only sequential mode is supported */ 00196 yp[0] = (realnum)optimize_func(xc); 00197 # endif 00198 *ymin = yp[0]; 00199 jmin = 0; 00200 /* restart entry; initialize transformation matrix to unity */ 00201 L_10: 00202 for( i=0; i < nvarPhymir; i++ ) 00203 { 00204 for( j=0; j < nvarPhymir; j++ ) 00205 { 00206 a2[j][i] = DELTA(i,j); 00207 } 00208 } 00209 /* loop entry */ 00210 L_20: 00211 if( lgRead ) 00212 { 00213 rd_continue(&vers,&limcp,a2,c1,c2,xc,xcold,&dmax,&dold,ymin,&nvarcp,&optimize.nOptimiz, 00214 optimize.varmax,optimize.varmin,chDum1,chDum2,chDum3,CNTFILE); 00215 if( nvarcp != nvarPhymir ) 00216 { 00217 printf( "optimize continue - wrong number of free parameters, sorry\n" ); 00218 cdEXIT(EXIT_FAILURE); 00219 } 00220 for( i=0; i < nvarPhymir; i++ ) 00221 { 00222 xp[i][0] = xc[i]; 00223 } 00224 yp[0] = *ymin; 00225 jmin = 0; 00226 lgRead = false; 00227 } 00228 else 00229 { 00230 // use STDLEN-1 so that last 0 byte is not overwritten... 00231 strncpy(chDum1,t_version::Inst().chDate,STDLEN-1); 00232 strncpy(chDum2,t_version::Inst().chVersion,STDLEN-1); 00233 strncpy(chDum3,cpu.host_name(),STDLEN-1); 00234 wr_continue(VRSNEW,LIMPAR,a2,c1,c2,xc,xcold,dmax,dold,*ymin,nvarPhymir,optimize.nOptimiz, 00235 optimize.varmax,optimize.varmin,chDum1,chDum2,chDum3,CNTFILE); 00236 } 00237 00238 if( lgFinish ) 00239 { 00240 return; 00241 } 00242 /* maximum no. of iterations exceeded? */ 00243 if( optimize.nOptimiz >= optimize.nIterOptim ) 00244 { 00245 fprintf( ioQQQ, " Optimizer exceeding maximum iterations.\n This can be reset with the OPTIMIZE ITERATIONS command.\n" ); 00246 return; 00247 } 00248 00249 for( j=0; j < nvarPhymir; j++ ) 00250 { 00251 sgn = 1.f; 00252 for( jj=2*j+1; jj <= 2*j+2; jj++ ) 00253 { 00254 sgn = -sgn; 00255 for( i=0; i < nvarPhymir; i++ ) 00256 { 00257 xp[i][jj] = xc[i] + sgn*dmax*c2[j]*a2[j][i]; 00258 xhlp[i] = xp[i][jj]; 00259 optimize.vparm[0][i] = xhlp[i]; 00260 /* this is done by child process, so copy code to parent process */ 00261 if( optimize.lgParallel ) 00262 { 00263 vpusedPhymir = MIN2(optimize.vparm[0][i],optimize.varang[i][1]); 00264 vpusedPhymir = MAX2(vpusedPhymir,optimize.varang[i][0]); 00265 optimize.varmax[i] = MAX2(optimize.varmax[i],vpusedPhymir); 00266 optimize.varmin[i] = MIN2(optimize.varmin[i],vpusedPhymir); 00267 } 00268 } 00269 # ifdef __unix 00270 if( optimize.lgParallel ) 00271 { 00272 currentCPU++; 00273 if( currentCPU > optimize.useCPU ) 00274 { 00275 /* too many processes, wait for one to finish */ 00276 pid = wait(&stat); 00277 currentCPU--; 00278 } 00279 /* flush all open files */ 00280 fflush(NULL); 00281 pid = fork(); 00282 if( pid == 0 ) 00283 { 00284 /* this is child process so execute */ 00285 sprintf(fnam1,"chi2_%ld",jj); 00286 sprintf(fnam2,"output_%ld",jj); 00287 /* each child should have its own output file */ 00288 ioQQQ = open_data( fnam2, "w", AS_LOCAL_ONLY ); 00289 /* fail-safe in case optimize_func crashes */ 00290 yp[jj] = FLT_MAX; 00291 wr_block(&yp[jj],(size_t)sizeof(realnum),fnam1); 00292 yp[jj] = (realnum)optimize_func(xhlp); 00293 wr_block(&yp[jj],(size_t)sizeof(realnum),fnam1); 00294 fclose( ioQQQ ); 00295 ioQQQ = NULL; 00296 cdEXIT(EXIT_SUCCESS); 00297 } 00298 /* this was incremented by child process, so copy code here */ 00299 optimize.nOptimiz++; 00300 } 00301 else 00302 { 00303 yp[jj] = (realnum)optimize_func(xhlp); 00304 } 00305 # else 00306 /* on non-UNIX machines only sequential mode is supported */ 00307 yp[jj] = (realnum)optimize_func(xhlp); 00308 # endif 00309 } 00310 } 00311 # ifdef __unix 00312 /* wait for child processes to terminate */ 00313 if( optimize.lgParallel ) 00314 { 00315 while( currentCPU > 0 ) 00316 { 00317 pid = wait(&stat); 00318 currentCPU--; 00319 } 00320 } 00321 # endif 00322 /* find best model */ 00323 for( jj=1; jj <= 2*nvarPhymir; jj++ ) 00324 { 00325 # ifdef __unix 00326 if( optimize.lgParallel ) 00327 { 00328 sprintf(fnam1,"chi2_%ld",jj); 00329 sprintf(fnam2,"output_%ld",jj); 00330 rd_block(&yp[jj],(size_t)sizeof(realnum),fnam1); 00331 remove(fnam1); 00332 cpfile(fnam2); 00333 remove(fnam2); 00334 } 00335 # endif 00336 if( yp[jj] < *ymin ) 00337 { 00338 *ymin = yp[jj]; 00339 jmin = jj; 00340 } 00341 } 00342 00343 lgNewCnt = jmin > 0; 00344 /* determine minimum and relative uncertainties */ 00345 lgNegd2 = false; 00346 xnrm = 0.f; 00347 for( i=0; i < nvarPhymir; i++ ) 00348 { 00349 d1 = yp[2*i+2] - yp[2*i+1]; 00350 d2 = 0.5f*yp[2*i+2] - yp[0] + 0.5f*yp[2*i+1]; 00351 if( d2 <= 0.f ) 00352 lgNegd2 = true; 00353 xhlp[i] = -dmax*c2[i]*(MAX2(MIN2((0.25f*d1)/MAX2(d2,1.e-10f),F0),-F0) - DELTA(2*i+1,jmin) + DELTA(2*i+2,jmin)); 00354 xnrm += POW2(xhlp[i]); 00355 } 00356 xnrm = (realnum)sqrt(xnrm); 00357 /* set up new transformation matrix */ 00358 imax = 0; 00359 amax = 0.f; 00360 for( j=0; j < nvarPhymir; j++ ) 00361 { 00362 for( i=0; i < nvarPhymir; i++ ) 00363 { 00364 if( xnrm > 0.f ) 00365 { 00366 if( j == 0 ) 00367 { 00368 a2[0][i] *= xhlp[0]; 00369 } 00370 else 00371 { 00372 a2[0][i] += xhlp[j]*a2[j][i]; 00373 a2[j][i] = DELTA(i,j); 00374 if( j == nvarPhymir-1 && (realnum)fabs(a2[0][i]) > amax ) 00375 { 00376 imax = i; 00377 amax = (realnum)fabs(a2[0][i]); 00378 } 00379 } 00380 } 00381 else 00382 { 00383 a2[j][i] = DELTA(i,j); 00384 } 00385 } 00386 } 00387 /* this is to assure maximum linear independence of the base vectors */ 00388 if( imax > 0 ) 00389 { 00390 a2[imax][0] = 1.f; 00391 a2[imax][imax] = 0.f; 00392 } 00393 /* apply Gram-Schmidt procedure to get orthogonal base */ 00394 phygrm(a2,nvarPhymir); 00395 00396 /* set up hypercube dimensions in new base and choose new center */ 00397 for( i=0; i < nvarPhymir; i++ ) 00398 { 00399 c2[i] = 0.f; 00400 for( j=0; j < nvarPhymir; j++ ) 00401 { 00402 c2[i] += POW2(a2[i][j]/c1[j]); 00403 } 00404 c2[i] = 1.f/sqrt(c2[i]); 00405 xc[i] = xp[i][jmin]; 00406 xp[i][0] = xc[i]; 00407 } 00408 yp[0] = yp[jmin]; 00409 jmin = 0; 00410 /* choose size of next hypercube */ 00411 if( lgNegd2 ) 00412 { 00413 /* this means that the hypercube either is bigger than the scale 00414 * on which the function varies, or is so small that we see noise. 00415 * in both cases make the hypercube smaller. */ 00416 r1 = F1; 00417 r2 = F1; 00418 } 00419 else 00420 { 00421 r1 = F2; 00422 if( lgNewCnt ) 00423 { 00424 /* when we make progress, dmax may become bigger */ 00425 r2 = sqrt(1.f/F1); 00426 } 00427 else 00428 { 00429 /* when there is no progress force dmax smaller, otherwise there 00430 * may never be an end */ 00431 r2 = sqrt(F1); 00432 } 00433 } 00434 dmax = MIN2(MAX2(xnrm/c2[0],dmax*r1),dmax*r2); 00435 /* fail-safe against excessive behaviour */ 00436 dmax = MIN2(dmax,dold); 00437 00438 if( dmax > toler ) 00439 goto L_20; 00440 /* do we restart? */ 00441 diff = 0.f; 00442 for( i=0; i < nvarPhymir; i++ ) 00443 { 00444 diff += POW2(xc[i] - xcold[i]); 00445 xcold[i] = xc[i]; 00446 c2[i] = c1[i]; 00447 } 00448 diff = sqrt(diff); 00449 dmax = dold; 00450 lgFinish = diff <= toler; 00451 goto L_10; 00452 # undef DELTA 00453 } 00454 00455 STATIC void phygrm(realnum a[][LIMPAR], 00456 long int n) 00457 { 00458 long int i, 00459 j, 00460 k; 00461 realnum ip; 00462 00463 DEBUG_ENTRY( "phygrm()" ); 00464 00465 /* apply modified Gram-Schmidt procedure to a */ 00466 for( i=0; i < n; i++ ) 00467 { 00468 ip = 0.f; 00469 for( k=0; k < n; k++ ) 00470 ip += POW2(a[i][k]); 00471 ip = sqrt(ip); 00472 for( k=0; k < n; k++ ) 00473 a[i][k] /= ip; 00474 for( j=i+1; j < n; j++ ) 00475 { 00476 ip = 0.f; 00477 for( k=0; k < n; k++ ) 00478 ip += a[i][k]*a[j][k]; 00479 for( k=0; k < n; k++ ) 00480 a[j][k] -= ip*a[i][k]; 00481 } 00482 } 00483 return; 00484 } 00485 00486 STATIC void wr_continue(realnum vers, 00487 long dim, 00488 realnum a2[][LIMPAR], /* a2[LIMPAR][LIMPAR] */ 00489 const realnum c1[], /* c1[LIMPAR] */ 00490 const realnum c2[], /* c2[LIMPAR] */ 00491 const realnum xc[], /* xc[LIMPAR] */ 00492 const realnum xcold[], /* xcold[LIMPAR] */ 00493 realnum dmax, 00494 realnum dold, 00495 realnum ymin, 00496 long nvar, 00497 long noptim, 00498 const realnum varmax[], /* varmax[LIMPAR] */ 00499 const realnum varmin[], /* varmin[LIMPAR] */ 00500 const char chDum1[], /* chDum1[STDLEN] */ 00501 const char chDum2[], /* chDum2[STDLEN] */ 00502 const char chDum3[], /* chDum3[STDLEN] */ 00503 const char *fnam) 00504 { 00505 bool lgErr; 00506 int res; 00507 size_t num; 00508 FILE *fdes; 00509 00510 DEBUG_ENTRY( "wr_continue()" ); 00511 00512 try 00513 { 00514 fdes = open_data( fnam, "wb", AS_LOCAL_ONLY ); 00515 } 00516 catch( cloudy_exit ) 00517 { 00518 return; 00519 } 00520 lgErr = false; 00521 num = 1; 00522 lgErr = lgErr || ( fwrite(&vers,sizeof(realnum),num,fdes) != num ); 00523 lgErr = lgErr || ( fwrite(&dim,sizeof(long),num,fdes) != num ); 00524 num = (size_t)(LIMPAR*LIMPAR); 00525 lgErr = lgErr || ( fwrite(a2,sizeof(realnum),num,fdes) != num ); 00526 num = (size_t)LIMPAR; 00527 lgErr = lgErr || ( fwrite(c1,sizeof(realnum),num,fdes) != num ); 00528 lgErr = lgErr || ( fwrite(c2,sizeof(realnum),num,fdes) != num ); 00529 lgErr = lgErr || ( fwrite(xc,sizeof(realnum),num,fdes) != num ); 00530 lgErr = lgErr || ( fwrite(xcold,sizeof(realnum),num,fdes) != num ); 00531 num = 1; 00532 lgErr = lgErr || ( fwrite(&dmax,sizeof(realnum),num,fdes) != num ); 00533 lgErr = lgErr || ( fwrite(&dold,sizeof(realnum),num,fdes) != num ); 00534 lgErr = lgErr || ( fwrite(&ymin,sizeof(realnum),num,fdes) != num ); 00535 lgErr = lgErr || ( fwrite(&nvar,sizeof(long),num,fdes) != num ); 00536 lgErr = lgErr || ( fwrite(&noptim,sizeof(long),num,fdes) != num ); 00537 num = (size_t)LIMPAR; 00538 lgErr = lgErr || ( fwrite(varmax,sizeof(realnum),num,fdes) != num ); 00539 lgErr = lgErr || ( fwrite(varmin,sizeof(realnum),num,fdes) != num ); 00540 num = (size_t)STDLEN; 00541 lgErr = lgErr || ( fwrite(chDum1,sizeof(char),num,fdes) != num ); 00542 lgErr = lgErr || ( fwrite(chDum2,sizeof(char),num,fdes) != num ); 00543 lgErr = lgErr || ( fwrite(chDum3,sizeof(char),num,fdes) != num ); 00544 fclose(fdes); 00545 if( lgErr ) 00546 { 00547 printf( "error writing file: %s\n",fnam ); 00548 res = remove(fnam); 00549 /* following to keep lint quiet - res is not used anywhere */ 00550 if( false) fprintf(ioQQQ,"%i\n", res ); 00551 } 00552 return; 00553 } 00554 00555 STATIC void rd_continue(realnum *vers, 00556 long *dim, 00557 realnum a2[][LIMPAR], /* a2[LIMPAR][LIMPAR] */ 00558 realnum c1[], /* c1[LIMPAR] */ 00559 realnum c2[], /* c2[LIMPAR] */ 00560 realnum xc[], /* xc[LIMPAR] */ 00561 realnum xcold[], /* xcold[LIMPAR] */ 00562 realnum *dmax, 00563 realnum *dold, 00564 realnum *ymin, 00565 long *nvar, 00566 long *noptim, 00567 realnum varmax[], /* varmax[LIMPAR] */ 00568 realnum varmin[], /* varmin[LIMPAR] */ 00569 char chDum1[], /* chDum1[STDLEN] */ 00570 char chDum2[], /* chDum2[STDLEN] */ 00571 char chDum3[], /* chDum3[STDLEN] */ 00572 const char *fnam) 00573 { 00574 bool lgErr; 00575 size_t num; 00576 FILE *fdes; 00577 00578 DEBUG_ENTRY( "rd_continue()" ); 00579 00580 fdes = open_data( fnam, "rb", AS_LOCAL_ONLY ); 00581 lgErr = false; 00582 num = 1; 00583 lgErr = lgErr || ( fread(vers,sizeof(realnum),num,fdes) != num ); 00584 if( lgErr || *vers != VRSNEW ) 00585 { 00586 printf( "optimize continue - file has incompatible version, sorry\n" ); 00587 cdEXIT(EXIT_FAILURE); 00588 } 00589 lgErr = lgErr || ( fread(dim,sizeof(long),num,fdes) != num ); 00590 if( lgErr || *dim != LIMPAR ) 00591 { 00592 printf( "optimize continue - arrays have wrong dimension, sorry\n" ); 00593 cdEXIT(EXIT_FAILURE); 00594 } 00595 num = (size_t)(LIMPAR*LIMPAR); 00596 lgErr = lgErr || ( fread(a2,sizeof(realnum),num,fdes) != num ); 00597 num = (size_t)LIMPAR; 00598 lgErr = lgErr || ( fread(c1,sizeof(realnum),num,fdes) != num ); 00599 lgErr = lgErr || ( fread(c2,sizeof(realnum),num,fdes) != num ); 00600 lgErr = lgErr || ( fread(xc,sizeof(realnum),num,fdes) != num ); 00601 lgErr = lgErr || ( fread(xcold,sizeof(realnum),num,fdes) != num ); 00602 num = 1; 00603 lgErr = lgErr || ( fread(dmax,sizeof(realnum),num,fdes) != num ); 00604 lgErr = lgErr || ( fread(dold,sizeof(realnum),num,fdes) != num ); 00605 lgErr = lgErr || ( fread(ymin,sizeof(realnum),num,fdes) != num ); 00606 lgErr = lgErr || ( fread(nvar,sizeof(long),num,fdes) != num ); 00607 lgErr = lgErr || ( fread(noptim,sizeof(long),num,fdes) != num ); 00608 num = (size_t)LIMPAR; 00609 lgErr = lgErr || ( fread(varmax,sizeof(realnum),num,fdes) != num ); 00610 lgErr = lgErr || ( fread(varmin,sizeof(realnum),num,fdes) != num ); 00611 num = (size_t)STDLEN; 00612 lgErr = lgErr || ( fread(chDum1,sizeof(char),num,fdes) != num ); 00613 lgErr = lgErr || ( fread(chDum2,sizeof(char),num,fdes) != num ); 00614 lgErr = lgErr || ( fread(chDum3,sizeof(char),num,fdes) != num ); 00615 fclose(fdes); 00616 if( lgErr ) 00617 { 00618 printf( "error reading file: %s\n",fnam ); 00619 cdEXIT(EXIT_FAILURE); 00620 } 00621 return; 00622 } 00623 00624 #ifdef __unix 00625 00626 STATIC void cpfile(const char *fnam) 00627 { 00628 char chr; 00629 00630 FILE *fdes; 00631 00632 DEBUG_ENTRY( "cpfile()" ); 00633 00634 /* append output produced by child process on <fnam>, to output of parent process */ 00635 00636 fdes = open_data( fnam, "r", AS_LOCAL_ONLY_TRY ); 00637 if( fdes == NULL ) 00638 return; 00639 chr = (char)fgetc(fdes); 00640 while( ! feof(fdes) ) 00641 { 00642 fputc( chr , ioQQQ ); 00643 chr = (char)fgetc(fdes); 00644 } 00645 fclose(fdes); 00646 return; 00647 } 00648 00649 STATIC void wr_block(void *ptr, 00650 size_t len, 00651 const char *fnam) 00652 { 00653 FILE *fdes; 00654 00655 DEBUG_ENTRY( "wr_block()" ); 00656 00657 /* write <len> bytes of data from buffer <*ptr> into unformatted file <fnam> */ 00658 00659 fdes = open_data( fnam, "wb", AS_LOCAL_ONLY ); 00660 if( fwrite(ptr,len,(size_t)1,fdes) != 1 ) { 00661 printf( "error writing on file: %s\n",fnam ); 00662 fclose(fdes); 00663 cdEXIT(EXIT_FAILURE); 00664 } 00665 fclose(fdes); 00666 return; 00667 } 00668 00669 STATIC void rd_block(void *ptr, 00670 size_t len, 00671 const char *fnam) 00672 { 00673 FILE *fdes; 00674 00675 DEBUG_ENTRY( "rd_block()" ); 00676 00677 /* read <len> bytes of data into buffer <*ptr> from unformatted file <fnam> */ 00678 00679 fdes = open_data( fnam, "rb", AS_LOCAL_ONLY ); 00680 if( fread(ptr,len,(size_t)1,fdes) != 1 ) { 00681 printf( "error reading on file: %s\n",fnam ); 00682 fclose(fdes); 00683 cdEXIT(EXIT_FAILURE); 00684 } 00685 fclose(fdes); 00686 return; 00687 } 00688 00689 #endif