00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <memory.h>
00027 #include <math.h>
00028
00029 #ifdef MKL
00030 #include "mkl_wrappers.h"
00031 #else
00032 #include "lapack_wrappers.h"
00033 #endif
00034
00035 #include "maxdet.h"
00036
00037 void mydlascl(double from,double to,int m,int n,double *A)
00038 {
00039 int i;
00040 double scale=to/from;
00041 for(i=0;i<m*n;i++)
00042 A[i] *= scale;
00043 }
00044
00045
00046
00047
00048
00049 void disp_imat(FILE *fp,int *ip,int r, int c,int att)
00050 {
00051 register int i,j;
00052 register int *rip;
00053
00054 for (i=0; i<r; i++) {
00055 fprintf(fp,"| ");
00056 for (rip=ip+i, j=0; j<c; rip+=r, j++)
00057 fprintf(fp,"%8d ",*rip);
00058 fprintf(fp,"|\n");
00059 }
00060 fprintf(fp,"\n");
00061
00062 att = 0;
00063 }
00064
00065
00066 void disp_mat(FILE *fp, double *dp,int r,int c,int att)
00067 {
00068 register int i,j;
00069 register double *rdp,dtmp,maxmag=0;
00070
00071
00072 if (!r || !c) {
00073 fprintf(fp,"[]\n\n");
00074 return;
00075 }
00076
00077 for (i=0, rdp=dp; i<r*c; i++, rdp++) {
00078 dtmp = fabs(*rdp);
00079 if (dtmp>maxmag)
00080 maxmag = dtmp;
00081 }
00082
00083 if (maxmag>=1e4 || (maxmag<=1e-4 && maxmag>0)) {
00084 maxmag = pow((double) 10.0,(double) floor(log10(maxmag)));
00085 fprintf(fp,"%e *\n",maxmag);
00086 for (i=0; i<r; i++) {
00087 fprintf(fp,"%s",(i ? "\n " : " "));
00088 for (rdp=dp+i, j=0; j<c; rdp+=r, j++)
00089 fprintf(fp,"% 7.3f ",*rdp/maxmag);
00090 fprintf(fp,"\n");
00091
00092 }
00093 fprintf(fp," \n\n");
00094 } else {
00095 for (i=0; i<r; i++) {
00096 fprintf(fp,"%s",(i ? "\n " : " "));
00097 for (rdp=dp+i, j=0; j<c; rdp+=r, j++)
00098 fprintf(fp,"% 10.4f ",*rdp);
00099 fprintf(fp," ");
00100 }
00101 fprintf(fp," \n\n");
00102 }
00103
00104 att = 0;
00105 }
00106
00107
00108
00109
00110 double inprd(double *X, double *Z, int L, int *blck_szs)
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 {
00125 register int i, j, k;
00126 double result;
00127 int lngth, pos, sz;
00128
00129
00130 for (i=0, sz=0; i<L; i++) sz += (blck_szs[i]*(blck_szs[i]+1))/2;
00131
00132
00133 result = 2.0*ddot(sz, X, 1, Z, 1);
00134
00135
00136
00137 for (j=0, pos=0; j<L; j++)
00138
00139
00140
00141
00142 for (k=0, lngth=blck_szs[j]; k<blck_szs[j]; pos+=lngth,
00143 lngth-=1, k++)
00144
00145
00146 result -= Z[pos]*X[pos];
00147
00148 return result;
00149 }
00150
00151
00152
00153
00154
00155 double eig_val(double *sig, double *ap,int L, int *blck_szs, int Npd,
00156 double *work)
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 {
00175 register int i;
00176 int nainfo;
00177 double min_ev=0.0, *dps, *sigptr;
00178
00179 memcpy(work,ap,Npd*sizeof(double));
00180 for (i=0, sigptr=sig, dps=work; i<L; i++) {
00181 switch (blck_szs[i]) {
00182 case 1:
00183 *sigptr = *dps;
00184 min_ev = (i ? MIN(min_ev,*dps) : *dps);
00185 sigptr++;
00186 dps++;
00187 break;
00188 case 2:
00189 *sigptr = (dps[0]+dps[2]
00190 -sqrt(SQR(dps[0]-dps[2])+4.0*SQR(dps[1])))/2.0;
00191 *(sigptr+1) = (dps[0]+dps[2]
00192 +sqrt(SQR(dps[0]-dps[2])+4.0*SQR(dps[1])))/2.0;
00193 min_ev = (i ? MIN(min_ev,*sigptr) : *sigptr);
00194 sigptr += 2;
00195 dps += 3;
00196 break;
00197 default:
00198 dspev("N","L",blck_szs[i],dps,sigptr,NULL,1,work+Npd,&nainfo);
00199 if (nainfo) {
00200 fprintf(stderr,"Error in dspev(0), info = %d.\n", nainfo);
00201 exit(-1);
00202 }
00203 min_ev = (i ? MIN(min_ev,*sigptr) : *sigptr);
00204 sigptr += blck_szs[i];
00205 dps += blck_szs[i]*(blck_szs[i]+1)/2;
00206 break;
00207 }
00208 }
00209 return min_ev;
00210 }
00211
00212
00213
00214
00215 int maxdet(
00216 int m,
00217 int L,
00218 double *F,
00219 int *F_blkszs,
00220 int K,
00221 double *G,
00222 int *G_blkszs,
00223 double *c,
00224 double *x,
00225 double *Z,
00226 double *W,
00227 double *ul,
00228 double *hist,
00229 double gamma,
00230 double abstol,
00231 double reltol,
00232 int *NTiters,
00233
00234 double *work,
00235 int lwork,
00236 int *iwork,
00237 int *info,
00238 int negativeFlag
00239 )
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 {
00341 register int i, j, k, iii;
00342 double *dps, *dpt, dtmp, dtmp2;
00343 int iters, minlwork, lwkspc, maxNTiters;
00344 int dual_equ_feas=YES, dual_PD_feas=NO;
00345 int n, F_sz, F_upsz, max_n, l, G_sz, G_upsz, max_l, sz, M_sz, M_upsz;
00346 double t, sqrtt, t_old, y, gap, mu, lambda, alpha[2], beta, psi_ub;
00347 double grad1, grad2, hess1, hess2;
00348 double *rhs, *GaF, *ZWtmp, *Fsc, *Gsc, *XF, *XG, *dXF, *dXG, *dW, *dZ;
00349 double *LF, *LG, *LFinv, *LGinv;
00350 double *sigF, *sigG, *sigZ, *sigW;
00351 double *M1, *LM, *VM, *sigM, *v1, *v2;
00352 double *wkspc, *temp, *temp2, *temp3, *temp4;
00353
00354 int NAinfo;
00355
00356
00357 if (m < 1) {
00358 fprintf(stderr,"maxdet: m must be at least one.\n");
00359 *info = -1;
00360 return 1;
00361 }
00362 if (L < 1) {
00363 fprintf(stderr,"maxdet: L must be at least one.\n");
00364 *info = -2;
00365 return 1;
00366 }
00367 if (K < 1) {
00368 fprintf(stderr,"maxdet: K must be at least one.\n");
00369 *info = -5;
00370 return 1;
00371 }
00372 for (i=0; i<L; i++)
00373 if (F_blkszs[i] < 1) {
00374 fprintf(stderr,"maxdet: F_blkszs[%d] must be at least one.\n",i);
00375 *info = -4;
00376 return 1;
00377 }
00378 for (i=0; i<K; i++)
00379 if (G_blkszs[i] < 1) {
00380 fprintf(stderr,"maxdet: G_blkszs[%d] must be at least one.\n",i);
00381 *info = -7;
00382 return 1;
00383 }
00384 if (gamma <= 0) {
00385 fprintf(stderr,"maxdet: gamma must be greater than zero.\n");
00386 *info = -14;
00387 return 1;
00388 }
00389 if (reltol < 0) {
00390 fprintf(stderr,"maxdet: reltol must be non-negative.\n");
00391 *info = -16;
00392 return 1;
00393 }
00394 if (abstol < MINABSTOL)
00395 fprintf(stderr,"maxdet: (warning) abstol less than MINABSTOL=%10.2e\n\
00396 MINABSTOL is used instead.\n",MINABSTOL);
00397
00398
00399 #ifdef DEBUG
00400 printf("m:%d L:%d K:%d NTiters:%d abstol:%f \n",m,L,K, *NTiters, abstol);
00401 printf("-------------- F ------------------\n");
00402 disp_mat(stdout,F,1,168,0);
00403 printf("-------------- F_blkszs ------------------\n");
00404 disp_imat(stdout,F_blkszs,1,24,0);
00405
00406 printf("-------------- G ------------------\n");
00407 disp_mat(stdout,G,1,168,0);
00408 printf("-------------- G_blkszs ------------------\n");
00409 disp_imat(stdout,G_blkszs,1,4,0);
00410
00411 printf("-------------- c ------------------\n");
00412 disp_mat(stdout,c,1,m,0);
00413 printf("-------------- z0 ------------------\n");
00414 disp_mat(stdout,x,1,m,0);
00415
00416 printf("-------------- Z ------------------\n");
00417 disp_mat(stdout,Z,1,24,0);
00418 printf("-------------- W ------------------\n");
00419 disp_mat(stdout,W,1,24,0);
00420 #endif
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 for (i=0, n=0, F_sz=0, F_upsz=0, max_n=0; i<L; i++) {
00439 n += F_blkszs[i];
00440 F_sz += F_blkszs[i]*(F_blkszs[i]+1)/2;
00441 F_upsz += F_blkszs[i]*F_blkszs[i];
00442 max_n = MAX(max_n, F_blkszs[i]);
00443 }
00444 for (i=0, l=0, G_sz=0, G_upsz=0, max_l=0; i<K; i++) {
00445 l += G_blkszs[i];
00446 G_sz += G_blkszs[i]*(G_blkszs[i]+1)/2;
00447 G_upsz += G_blkszs[i]*G_blkszs[i];
00448 max_l = MAX(max_l, G_blkszs[i]);
00449 }
00450 sz = F_sz+G_sz;
00451 M_sz = m*(m+1)/2;
00452 M_upsz = SQR(m);
00453 if (m > sz) {
00454 fprintf(stderr, "maxdet: matrices diag(Fi,Gi), i=1,...,m are linearly\
00455 dependent.\n");
00456 *info = -23;
00457 return 1;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 minlwork = (2*m+5)*sz + 2*(n+l) +
00511 MAX(m+sz*NB,MAX(3*(m+M_upsz+MAX(G_sz,F_sz)),
00512 MAX(3*(MAX(max_l,max_n)+MAX(G_sz,F_sz)),
00513 MAX(G_sz+3*max_l,F_sz+3*max_n))));
00514 if (lwork < minlwork){
00515 fprintf(stderr, "maxdet: not enough workspace, need at least\
00516 %d*sizeof(double).\n", minlwork);
00517 *info = -20;
00518 return 1;
00519 }
00520 lwkspc = lwork - (2*m+5)*sz - 2*(n+l);
00521 #ifdef MAXDET_DEBUG
00522 fprintf(stdout,"workspace %d bytes.\n",8*lwork+4*m);
00523 #endif
00524
00525 rhs = work;
00526 GaF = rhs + sz;
00527 ZWtmp = GaF + sz;
00528 Fsc = ZWtmp + m*sz;
00529 Gsc = Fsc + m*F_sz;
00530 LF = Gsc + m*G_sz;
00531 LG = LF + F_sz;
00532 XF = LG + G_sz;
00533 XG = XF + F_sz;
00534 dXF = XG + G_sz;
00535 dXG = dXF + F_sz;
00536 sigF = dXG + G_sz;
00537 sigG = sigF + n;
00538 sigZ = sigG + l;
00539 sigW = sigZ + n;
00540
00541 wkspc = work + (2*m+5)*sz + 2*(n+l);
00542 temp = wkspc + (lwkspc-3*MAX(G_sz,F_sz));
00543 temp2 = temp + MAX(G_sz,F_sz);
00544 temp3 = temp2 + MAX(G_sz,F_sz);
00545 temp4 = LF;
00546
00547 LFinv = temp;
00548 LGinv = temp;
00549
00550 M1 = wkspc + 3*m;
00551 LM = M1 + M_upsz;
00552 VM = LM + M_upsz;
00553 sigM = dXF;
00554 v1 = sigF;
00555 v2 = sigZ;
00556
00557 dW = GaF;
00558 dZ = dW + G_sz;
00559
00560
00561 maxNTiters = (*NTiters >= 1) ? *NTiters : MAXITERS;
00562 *NTiters = 0;
00563 *info = -24;
00564 t = 1;
00565 #ifdef MAXDET_DEBUG
00566 fprintf(stdout," iters obj gap\n");
00567 #endif
00568
00569
00570
00571 for (iters=1; ; iters++) {
00572
00573
00574 int pos, pos2, NTcount;
00575 double mat_norm, rcond;
00576
00577
00578
00579 dcopy(F_sz,F,1,XF,1);
00580 dgemv("N",F_sz,m,1.0,F+F_sz,F_sz,x,1,1.0,XF,1);
00581 dcopy(G_sz,G,1,XG,1);
00582 dgemv("N",G_sz,m,1.0,G+G_sz,G_sz,x,1,1.0,XG,1);
00583
00584
00585
00586
00587
00588 if (iters==1) {
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 mat_norm = sqrt(inprd(Z,Z,L,F_blkszs)+inprd(W,W,K,G_blkszs));
00599 i = 0;
00600 while (dual_equ_feas==YES && i<m) {
00601 if (fabs(inprd(F+(i+1)*F_sz,Z,L,F_blkszs)+
00602 inprd(G+(i+1)*G_sz,W,K,G_blkszs)-c[i])
00603 > mat_norm*TOLC)
00604 dual_equ_feas = NO;
00605 i++;
00606 }
00607
00608 if (dual_equ_feas && eig_val(sigZ,Z,L,F_blkszs,F_sz,wkspc)>0 &&
00609 eig_val(sigW,W,K,G_blkszs,G_sz,wkspc)>0)
00610 dual_PD_feas = YES;
00611 }
00612
00613
00614 sqrtt = sqrt(t);
00615 for (NTcount=0; *NTiters<maxNTiters; ) {
00616 (*NTiters)++;
00617 NTcount++;
00618
00619
00620
00621
00622
00623 memcpy(Gsc,G+G_sz,m*G_sz*sizeof(double));
00624 memcpy(Fsc,F+F_sz,m*F_sz*sizeof(double));
00625 memcpy(LG,XG,G_sz*sizeof(double));
00626
00627
00628
00629
00630
00631
00632
00633 memcpy(LF,XF,F_sz*sizeof(double));
00634 for (i=0, pos=0, dpt=LG; i<K;
00635 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, dpt=LG+pos, i++) {
00636
00637
00638 switch (G_blkszs[i]) {
00639 case 1:
00640 if (*dpt<=0) {
00641 fprintf(stderr,"maxdet: x(1x1) infeasible because G(x)<=0.\n");
00642 *info = -9;
00643 return 1;
00644 }
00645 *dpt = sqrt(*dpt);
00646 break;
00647 case 2:
00648 if (*dpt + *(dpt+2)<=0 ||
00649 *dpt * *(dpt+2) - SQR(*(dpt+1))<=0) {
00650 fprintf(stderr,"maxdet: x(2x2) infeasible because G(x)<=0.\n");
00651 *info = -9;
00652 return 1;
00653 }
00654 *dpt = sqrt(*dpt);
00655 *(dpt+1) = *(dpt+1) / *dpt;
00656 *(dpt+2) = sqrt(*(dpt+2)-SQR(*(dpt+1)));
00657 break;
00658 default:
00659 dpptrf("L",G_blkszs[i],dpt,&NAinfo);
00660 if (NAinfo>0) {
00661 fprintf(stderr,"maxdet: x infeasible because G(x)<=0. %d block(3x3) %d iterations\n",i,NTcount);
00662 *info = -9;
00663 return 1;
00664 } else if (NAinfo) {
00665 fprintf(stderr,"Error in dpptrf(0), info = %d.\n",NAinfo);
00666 return 1;
00667 }
00668 break;
00669 }
00670
00671 for (j=0; j<m; j++) {
00672 dspgst(1,"L",G_blkszs[i],Gsc+j*G_sz+pos,dpt,&NAinfo);
00673 if (NAinfo){
00674 fprintf(stderr,"Error in dspgst(0), info = %d.\n",NAinfo);
00675 return 1;
00676 }
00677 }
00678 }
00679 for (i=0, pos=0, dpt=LF; i<L;
00680 pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, dpt=LF+pos, i++) {
00681
00682
00683 switch (F_blkszs[i]) {
00684 case 1:
00685 if (*dpt<=0) {
00686 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
00687 *info = -9;
00688 return 1;
00689 }
00690 *dpt = sqrt(*dpt);
00691 break;
00692 case 2:
00693 if (*dpt + *(dpt+2)<=0 ||
00694 *dpt * *(dpt+2) - SQR(*(dpt+1))<=0) {
00695 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
00696 *info = -9;
00697 return 1;
00698 }
00699 *dpt = sqrt(*dpt);
00700 *(dpt+1) = *(dpt+1) / *dpt;
00701 *(dpt+2) = sqrt(*(dpt+2)-SQR(*(dpt+1)));
00702 break;
00703 default:
00704 dpptrf("L",F_blkszs[i],dpt,&NAinfo);
00705 if (NAinfo>0) {
00706 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
00707 *info = -9;
00708 return 1;
00709 } else if (NAinfo) {
00710 fprintf(stderr,"Error in dpptrf(1), info = %d.\n",NAinfo);
00711 return 1;
00712 }
00713 break;
00714 }
00715
00716 for (j=0; j<m; j++) {
00717 dspgst(1,"L",F_blkszs[i],Fsc+j*F_sz+pos,dpt,&NAinfo);
00718 if (NAinfo){
00719 fprintf(stderr,"Error in dspgst(1), info = %d.\n",NAinfo);
00720 return 1;
00721 }
00722 }
00723 }
00724
00725 if (iters==1 && !dual_PD_feas) {
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 for (i=0, dps=M1, dpt=LM; i<m; i++)
00748 for(j=i; j<m; j++, dps++, dpt++) {
00749 *dps = inprd(Gsc+i*G_sz,Gsc+j*G_sz,K,G_blkszs);
00750 *dpt = inprd(Fsc+i*F_sz,Fsc+j*F_sz,L,F_blkszs);
00751 }
00752 for (i=0, dpt=LM, dps=M1; i<M_sz; i++, dpt++, dps++)
00753 *dpt += *dps;
00754
00755 dspgv(1,"V","L",m,M1,LM,sigM,VM,m,wkspc,&NAinfo);
00756 if (NAinfo>m) {
00757 fprintf(stderr, "maxdet: matrices diag(Fi,Gi), i=1,...,m\
00758 are linearly dependent\n (or F(x) and/or G(x) are very badly\
00759 conditioned).\n");
00760 *info = -23;
00761 return 1;
00762 } else if (NAinfo) {
00763 fprintf(stderr,"Error in dspgv(0), info = %d.\n",NAinfo);
00764 return 1;
00765 }
00766
00767 memcpy(temp,c,m*sizeof(double));
00768 for (i=0; i<m; i++)
00769 for (j=0, dps=Gsc+i*G_sz; j<K; j++)
00770 for (k=G_blkszs[j]; k>0; dps+=k, k--)
00771 *(temp+i) -= *dps;
00772 dgemv("T",m,m,1.0,VM,m,temp,1,0.0,v1,1);
00773 memset(temp,0,m*sizeof(double));
00774 for (i=0; i<m; i++)
00775 for (j=0, dps=Fsc+i*F_sz; j<L; j++)
00776 for (k=F_blkszs[j]; k>0; dps+=k, k--)
00777 *(temp+i) -= *dps;
00778 dgemv("T",m,m,1.0,VM,m,temp,1,0.0,v2,1);
00779
00780
00781 for (i=0; i<LSITERUB; i++) {
00782 grad1 = 0.0;
00783 hess1 = 0.0;
00784 for (j=0, dps=v1, dpt=sigM; j<m; j++, dps++, dpt++) {
00785 dtmp = t * *dps + *(v2+j);
00786 dtmp2 = (t-1) * *dpt + 1.0;
00787 grad1 += 2 * *dps * dtmp / dtmp2 -
00788 SQR(dtmp) * *dpt / SQR(dtmp2);
00789 hess1 += 2 * SQR(*dps) / dtmp2 -
00790 4 * dtmp * *dps * *dpt / SQR(dtmp2) +
00791 2 * SQR(dtmp) * SQR(*dpt) / (SQR(dtmp2)*dtmp2);
00792 }
00793 if (hess1<=0) {
00794 lambda = 0;
00795 } else {
00796 lambda = sqrt(SQR(grad1)/hess1);
00797 t = MAX(1,t-1/(1+lambda)*(grad1/hess1));
00798
00799 }
00800 if (lambda < LSTOL)
00801 break;
00802 }
00803 t = MAX(1,t);
00804 #ifdef debug
00805 printf("t=%10.4e from preliminary phase\n",t);
00806 #endif
00807
00808 for (i=0, dpt=rhs; i<m; i++, dpt++)
00809 *dpt = -( (t * *(v1+i) + *(v2+i)) /
00810 ((t-1) * *(sigM+i)+ 1.0) );
00811 memcpy(temp,rhs,m*sizeof(double));
00812 dgemv("N",m,m,1.0,VM,m,temp,1,0.0,rhs,1);
00813 sqrtt = sqrt(t);
00814
00815 } else {
00816
00817 if (NTcount==1 && iters==1) {
00818
00819
00820
00821
00822
00823
00824 gap = inprd(Z,XF,L,F_blkszs);
00825
00826 memcpy(rhs,W,G_sz*sizeof(double));
00827 for (i=0, pos=0, dpt=LG; i<K;
00828 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, dpt=LG+pos, i++) {
00829 dspgst(2,"L",G_blkszs[i],rhs+pos,dpt,&NAinfo);
00830 if (NAinfo){
00831 fprintf(stderr,"Error in dspgst(2), info = %d.\n",
00832 NAinfo);
00833 return 1;
00834 }
00835 }
00836 eig_val(sigG,rhs,K,G_blkszs,G_sz,wkspc);
00837 for (i=0; i<l; i++)
00838 gap += sigG[i]-1.0-log(sigG[i]);
00839 t = MAX(1.0 , n/gap);
00840 sqrtt = sqrt(t);
00841 #ifdef debug
00842 printf("t=%10.2e from feasible dual\n",t);
00843 #endif
00844 }
00845
00846
00847
00848 memcpy(rhs,W,G_sz*sizeof(double));
00849 dscal(G_sz,-1.0,rhs,1);
00850 memcpy(rhs+G_sz,Z,F_sz*sizeof(double));
00851 dtmp = -t;
00852 dscal(F_sz,dtmp,rhs+G_sz,1);
00853
00854 for (i=0, pos=0, dpt=LG; i<K;
00855 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, dpt=LG+pos, i++) {
00856
00857
00858 dspgst(2,"L",G_blkszs[i],rhs+pos,dpt,&NAinfo);
00859 if (NAinfo){
00860 fprintf(stderr,"Error in dspgst(3), info = %d.\n",NAinfo);
00861 return 1;
00862 }
00863
00864
00865 for (k=0, pos2=pos; k<G_blkszs[i]; pos2+=G_blkszs[i]-k,
00866 k++)
00867 *(rhs+pos2) = (*(rhs+pos2)+1.0)/sqrt(2.0);
00868
00869 }
00870 dscal(G_sz,sqrtt,rhs,1);
00871
00872 for (i=0, pos=0, dpt=LF; i<L;
00873 pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, dpt=LF+pos, i++) {
00874
00875
00876 dspgst(2,"L",F_blkszs[i],rhs+G_sz+pos,dpt,&NAinfo);
00877 if (NAinfo){
00878 fprintf(stderr,"Error in dspgst(4), info = %d.\n",NAinfo);
00879 return 1;
00880 }
00881
00882
00883 for (k=0, pos2=pos; k<F_blkszs[i]; pos2+=F_blkszs[i]-k,
00884 k++)
00885 *(rhs+G_sz+pos2) = (*(rhs+G_sz+pos2)+1.0)/sqrt(2.0);
00886 }
00887
00888 for (i=0, dpt=GaF; i<m; i++, dpt+=sz) {
00889 memcpy(dpt,Gsc+i*G_sz,G_sz*sizeof(double));
00890 for (j=0, dps=dpt; j<K; j++)
00891 for (k=G_blkszs[j]; k>0; dps+=k, k--)
00892 *dps /= sqrt(2.0);
00893 memcpy(dpt+G_sz,Fsc+i*F_sz,F_sz*sizeof(double));
00894 for (j=0, dps=dpt+G_sz; j<L; j++)
00895 for (k=F_blkszs[j]; k>0; dps+=k, k--)
00896 *dps /= sqrt(2.0);
00897 }
00898 dlascl("G",0,0,1.0,sqrtt,G_sz,m,GaF,sz,&NAinfo);
00899 if (NAinfo){
00900 fprintf(stderr,"Error in dlascl(0), info = %d.\n",NAinfo);
00901 return 1;
00902 }
00903
00904 dgels("N",sz,m,1,GaF,sz,rhs,sz,wkspc,lwkspc,&NAinfo);
00905 if (NAinfo){
00906 fprintf(stderr,"Error in dgels(0), info = %d.\n",NAinfo);
00907 return 1;
00908 }
00909
00910
00911
00912
00913
00914 if (iters == 1) {
00915 dtrcon("1","U","N",m,GaF,sz,&rcond,wkspc,iwork,&NAinfo);
00916 if (NAinfo < 0){
00917 fprintf(stderr,"Error in dtrcon(0), info = %d.\n", NAinfo);
00918 return 1;
00919 }
00920 if (rcond < MINRCOND) {
00921 fprintf(stderr,"maxdet: matrices diag(G_i,F_i), i=1,...,m\
00922 are linearly dependent\n (or F(x) and/or G(x) are very badly\
00923 conditioned).\n");
00924 *info = -23;
00925 return 1;
00926 }
00927 }
00928 }
00929
00930
00931 dgemv("N",G_sz,m,1.0,G+G_sz,G_sz,rhs,1,0.0,dXG,1);
00932 dgemv("N",F_sz,m,1.0,F+F_sz,F_sz,rhs,1,0.0,dXF,1);
00933
00934
00935 memcpy(temp,XG,G_sz*sizeof(double));
00936 memcpy(temp2,dXG,G_sz*sizeof(double));
00937 for (i=0, pos=0, dpt=sigG; i<K; dpt+=G_blkszs[i],
00938 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, i++) {
00939 switch (G_blkszs[i]) {
00940 case 1:
00941 *dpt = *(temp2+pos) / *(temp+pos);
00942 break;
00943 default:
00944 dspgv(1,"N","L",G_blkszs[i],temp2+pos,temp+pos,dpt,
00945 NULL,1,wkspc,&NAinfo);
00946 if (NAinfo) {
00947 fprintf(stderr,"Error in dspgv(1), info = %d.\n",NAinfo);
00948 return 1;
00949 }
00950 break;
00951 }
00952 }
00953 memcpy(temp,XF,F_sz*sizeof(double));
00954 memcpy(temp2,dXF,F_sz*sizeof(double));
00955 for (i=0, pos=0, dpt=sigF; i<L; dpt+=F_blkszs[i],
00956 pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, i++) {
00957 switch (F_blkszs[i]) {
00958 case 1:
00959 *dpt = *(temp2+pos) / *(temp+pos);
00960 break;
00961 default:
00962 dspgv(1,"N","L",F_blkszs[i],temp2+pos,temp+pos,dpt,
00963 NULL,1,wkspc,&NAinfo);
00964 if (NAinfo) {
00965 fprintf(stderr,"Error in dspgv(2), info = %d.\n",NAinfo);
00966 return 1;
00967 }
00968 break;
00969 }
00970 }
00971
00972
00973
00974
00975 if (iters==1 && !dual_PD_feas) {
00976
00977 int neg_sig=NO;
00978
00979 for (i=0, dps=sigG; (i<l && !neg_sig); i++, dps++)
00980 if (*dps<0) neg_sig=YES;
00981 for (i=0, dps=sigF; (i<n && !neg_sig); i++, dps++)
00982 if (*dps<0) neg_sig=YES;
00983 if (ddot(m,c,1,rhs,1)<=0 && !neg_sig) {
00984 fprintf(stderr,"maxdet: The dual problem is infeasible.\n");
00985 return 1;
00986 }
00987 }
00988
00989
00990 mu = 0.0;
00991 for (i=0, dps=sigG; i<l; i++, dps++)
00992 mu += SQR(*dps);
00993 mu *= t;
00994 for (i=0, dps=sigF; i<n; i++, dps++)
00995 mu += SQR(*dps);
00996 mu = sqrt(mu);
00997 if (mu < CENTOL)
00998 break;
00999
01000
01001
01002
01003 if (mu > .5) {
01004 for (i=0, *alpha=0.0; i<LSITERUB; i++) {
01005 grad1 = 0.0;
01006 hess1 = 0.0;
01007 for (j=0, dps=sigG; j<l; j++, dps++) {
01008 dtmp = 1 + *alpha * *dps;
01009 grad1 -= *dps / dtmp;
01010 hess1 += SQR(*dps) / SQR(dtmp);
01011 }
01012 grad1 *= t;
01013 hess1 *= t;
01014 for (j=0, dps=sigF; j<n; j++, dps++) {
01015 dtmp = 1 + *alpha * *dps;
01016 grad1 -= *dps / dtmp;
01017 hess1 += SQR(*dps) / SQR(dtmp);
01018 }
01019 grad1 += t * ddot(m,c,1,rhs,1);
01020 lambda = sqrt(SQR(grad1)/hess1);
01021 *alpha -= 1/(1+lambda)*(grad1/hess1);
01022 if (lambda < LSTOL)
01023 break;
01024 }
01025 } else {
01026 *alpha = 1.0;
01027 }
01028
01029
01030 daxpy(m,*alpha,rhs,1,x,1);
01031 daxpy(G_sz,*alpha,dXG,1,XG,1);
01032 daxpy(F_sz,*alpha,dXF,1,XF,1);
01033
01034
01035 dpt = hist+((*NTiters)-1)*(m+3);
01036 for (iii=0;iii<m;iii++)
01037 *(dpt+iii)=x[iii];
01038 *(dpt+m) = 0;
01039 *(dpt+m+1) =0;
01040 *(dpt+m+2) =-1;
01041
01042
01043 }
01044
01045
01046
01047
01048
01049 memcpy(ZWtmp,Z,F_sz*sizeof(double));
01050 memcpy(ZWtmp+F_sz,W,G_sz*sizeof(double));
01051 memset(W,0,G_sz*sizeof(double));
01052 memset(Z,0,F_sz*sizeof(double));
01053 for (i=0, dpt=W; i<K; i++)
01054 for (j=G_blkszs[i]; j>0; dpt+=j, j--)
01055 *dpt = 1.0;
01056 dgemv("N",G_sz,m,-1.0,Gsc,G_sz,rhs,1,1.0,W,1);
01057 memcpy(LGinv,LG,G_sz*sizeof(double));
01058
01059 for (i=0, pos=0; i<K; pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, i++) {
01060 dtptri("L","N",G_blkszs[i],LGinv+pos,&NAinfo);
01061 if (NAinfo) {
01062 fprintf(stderr,"Error in dtptri(0), info = %d.\n",NAinfo);
01063 return 1;
01064 }
01065 dspgst(2,"L",G_blkszs[i],W+pos,LGinv+pos,&NAinfo);
01066 if (NAinfo) {
01067 fprintf(stderr,"Error in dspgst(5), info = %d.\n",NAinfo);
01068 return 1;
01069 }
01070 }
01071 for (i=0, dpt=Z; i<L; i++)
01072 for (j=F_blkszs[i]; j>0; dpt+=j, j--)
01073 *dpt = 1.0;
01074 dgemv("N",F_sz,m,-1.0,Fsc,F_sz,rhs,1,1.0,Z,1);
01075 memcpy(LFinv,LF,F_sz*sizeof(double));
01076
01077 for (i=0, pos=0; i<L; pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, i++) {
01078 dtptri("L","N",F_blkszs[i],LFinv+pos,&NAinfo);
01079 if (NAinfo) {
01080 fprintf(stderr,"Error in dtptri(1), info = %d.\n",NAinfo);
01081 return 1;
01082 }
01083 dspgst(2,"L",F_blkszs[i],Z+pos,LFinv+pos,&NAinfo);
01084 if (NAinfo) {
01085 fprintf(stderr,"Error in dspgst(6), info = %d.\n",NAinfo);
01086 return 1;
01087 }
01088 }
01089 dtmp=1/t;
01090 dscal(F_sz,dtmp,Z,1);
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100 if ((iters==1 && !dual_PD_feas) || *NTiters>=maxNTiters) {
01101 if (eig_val(sigZ,Z,L,F_blkszs,F_sz,wkspc)<=0 ||
01102 eig_val(sigW,W,K,G_blkszs,G_sz,wkspc)<=0) {
01103 if (iters==1 && !dual_PD_feas) {
01104 fprintf(stderr,"maxdet: Infeasible dual updates, the dual\
01105 problem is likely to be infeasible.\n");
01106 return 1;
01107 } else {
01108 memcpy(Z,ZWtmp,F_sz*sizeof(double));
01109 memcpy(W,ZWtmp+F_sz,G_sz*sizeof(double));
01110 }
01111 }
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 gap = inprd(Z,XF,L,F_blkszs);
01124
01125 memcpy(rhs,W,G_sz*sizeof(double));
01126 for (i=0, pos=0, dpt=LG; i<K;
01127 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, dpt=LG+pos, i++) {
01128 dspgst(2,"L",G_blkszs[i],rhs+pos,dpt,&NAinfo);
01129 if (NAinfo){
01130 fprintf(stderr,"Error in dspgst(7), info = %d.\n",NAinfo);
01131 return 1;
01132 }
01133 }
01134 eig_val(sigG,rhs,K,G_blkszs,G_sz,wkspc);
01135 for (i=0; i<l; i++)
01136 gap += sigG[i]-1.0-log(sigG[i]);
01137
01138
01139 eig_val(sigG,XG,K,G_blkszs,G_sz,wkspc);
01140 ul[0] = ddot(m,c,1,x,1);
01141 for (i=0; i<l; i++)
01142 ul[0] -= log(sigG[i]);
01143
01144
01145 ul[1] = ul[0] - gap;
01146
01147
01148 dpt = hist+(*NTiters-1)*(m+3);
01149 for (iii=0;iii<m;iii++)
01150 *(dpt+iii)=x[iii];
01151 *(dpt+m) = ul[0];
01152 *(dpt+m+1) = gap;
01153 *(dpt+m+2) = NTcount;
01154
01155
01156 #ifdef MAXDET_DEBUG
01157 fprintf(stdout," %3d %10.2e %10.2e\n",*NTiters,ul[0],gap);
01158 #endif
01159 if(negativeFlag && ul[0] < 0){
01160 *info=4;
01161 dpt = hist+(*NTiters)*(m+3);
01162 *(dpt+m+2) = -2;
01163 return(0);
01164 }
01165 if (gap <= MAX(abstol,MINABSTOL)) {
01166 *info = 2;
01167 dpt = hist+(*NTiters)*(m+3);
01168 *(dpt+m+2) = -2;
01169 return(0);
01170 }
01171 if ( (ul[1] > 0 && gap <= reltol*ul[1]) ||
01172 (ul[0] < 0 && gap <= reltol*(-ul[0])) ) {
01173 *info = 3;
01174 dpt = hist+(*NTiters)*(m+3);
01175 *(dpt+m+2) = -2;
01176 return(0);
01177 }
01178 if (*NTiters >= maxNTiters) {
01179 *info = 1;
01180 dpt = hist+(*NTiters)*(m+3);
01181 *(dpt+m+2) = -2;
01182 return(0);
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 memcpy(Gsc,G+G_sz,m*G_sz*sizeof(double));
01197 memcpy(Fsc,F+F_sz,m*F_sz*sizeof(double));
01198 memcpy(LG,XG,G_sz*sizeof(double));
01199 memcpy(LF,XF,F_sz*sizeof(double));
01200 memcpy(rhs,W,G_sz*sizeof(double));
01201 dscal(G_sz,-1.0,rhs,1);
01202 memcpy(rhs+G_sz,Z,F_sz*sizeof(double));
01203 dtmp = -t;
01204 dscal(F_sz,dtmp,rhs+G_sz,1);
01205
01206 for (i=0, pos=0, dpt=LG; i<K;
01207 pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, dpt=LG+pos, i++) {
01208
01209
01210 switch (G_blkszs[i]) {
01211 case 1:
01212 if (*dpt<=0) {
01213 fprintf(stderr,"maxdet: x infeasible because G(x)<=0.\n");
01214 *info = -9;
01215 return 1;
01216 }
01217 *dpt = sqrt(*dpt);
01218 break;
01219 case 2:
01220 if (*dpt + *(dpt+2)<=0 ||
01221 *dpt * *(dpt+2) - SQR(*(dpt+1))<=0) {
01222 fprintf(stderr,"maxdet: x infeasible because G(x)<=0.\n");
01223 *info = -9;
01224 return 1;
01225 }
01226 *dpt = sqrt(*dpt);
01227 *(dpt+1) = *(dpt+1) / *dpt;
01228 *(dpt+2) = sqrt(*(dpt+2)-SQR(*(dpt+1)));
01229 break;
01230 default:
01231 dpptrf("L",G_blkszs[i],dpt,&NAinfo);
01232 if (NAinfo>0) {
01233 fprintf(stderr,"maxdet: x infeasible because G(x)<=0.\n");
01234 *info = -9;
01235 return 1;
01236 } else if (NAinfo) {
01237 fprintf(stderr,"Error in dpptrf(2), info = %d.\n",NAinfo);
01238 return 1;
01239 }
01240 break;
01241 }
01242
01243
01244 for (j=0; j<m; j++) {
01245 dspgst(1,"L",G_blkszs[i],Gsc+j*G_sz+pos,dpt,&NAinfo);
01246 if (NAinfo){
01247 fprintf(stderr,"Error in dspgst(8), info = %d.\n",NAinfo);
01248 return 1;
01249 }
01250 }
01251
01252
01253 dspgst(2,"L",G_blkszs[i],rhs+pos,dpt,&NAinfo);
01254 if (NAinfo){
01255 fprintf(stderr,"Error in dspgst(9), info = %d.\n",NAinfo);
01256 return 1;
01257 }
01258
01259
01260 for (k=0, pos2=pos; k<G_blkszs[i]; pos2+=G_blkszs[i]-k,k++)
01261 *(rhs+pos2) = (*(rhs+pos2)+1.0)/sqrt(2.0);
01262
01263 }
01264 dscal(G_sz,sqrtt,rhs,1);
01265
01266 for (i=0, pos=0, dpt=LF; i<L;
01267 pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, dpt=LF+pos, i++) {
01268
01269
01270 switch (F_blkszs[i]) {
01271 case 1:
01272 if (*dpt<=0) {
01273 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
01274 *info = -9;
01275 return 1;
01276 }
01277 *dpt = sqrt(*dpt);
01278 break;
01279 case 2:
01280 if (*dpt + *(dpt+2)<=0 ||
01281 *dpt * *(dpt+2) - SQR(*(dpt+1))<=0) {
01282 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
01283 *info = -9;
01284 return 1;
01285 }
01286 *dpt = sqrt(*dpt);
01287 *(dpt+1) = *(dpt+1) / *dpt;
01288 *(dpt+2) = sqrt(*(dpt+2)-SQR(*(dpt+1)));
01289 break;
01290 default:
01291 dpptrf("L",F_blkszs[i],dpt,&NAinfo);
01292 if (NAinfo>0) {
01293 fprintf(stderr,"maxdet: x infeasible because F(x)<=0.\n");
01294 *info = -9;
01295 return 1;
01296 } else if (NAinfo) {
01297 fprintf(stderr,"Error in dpptrf(3), info = %d.\n",NAinfo);
01298 return 1;
01299 }
01300 break;
01301 }
01302
01303
01304 for (j=0; j<m; j++) {
01305 dspgst(1,"L",F_blkszs[i],Fsc+j*F_sz+pos,dpt,&NAinfo);
01306 if (NAinfo){
01307 fprintf(stderr,"Error in dspgst(10), info = %d.\n",NAinfo);
01308 return 1;
01309 }
01310 }
01311
01312
01313 dspgst(2,"L",F_blkszs[i],rhs+G_sz+pos,dpt,&NAinfo);
01314 if (NAinfo){
01315 fprintf(stderr,"Error in dspgst(11), info = %d.\n",NAinfo);
01316 return 1;
01317 }
01318
01319 for (k=0, pos2=pos; k<F_blkszs[i]; pos2+=F_blkszs[i]-k,k++)
01320 *(rhs+G_sz+pos2) = *(rhs+G_sz+pos2) / sqrt(2.0);
01321 }
01322
01323 for (i=0, dpt=GaF; i<m; i++, dpt+=sz) {
01324 memcpy(dpt,Gsc+i*G_sz,G_sz*sizeof(double));
01325 for (j=0, dps=dpt; j<K; j++)
01326 for (k=G_blkszs[j]; k>0; dps+=k, k--)
01327 *dps /= sqrt(2.0);
01328 memcpy(dpt+G_sz,Fsc+i*F_sz,F_sz*sizeof(double));
01329 for (j=0, dps=dpt+G_sz; j<L; j++)
01330 for (k=F_blkszs[j]; k>0; dps+=k, k--)
01331 *dps /= sqrt(2.0);
01332 }
01333 dlascl("G",0,0,1.0,sqrtt,G_sz,m,GaF,sz,&NAinfo);
01334 if (NAinfo){
01335 fprintf(stderr,"Error in dlascl(1), info = %d.\n",NAinfo);
01336 return 1;
01337 }
01338
01339 dgels("N",sz,m,1,GaF,sz,rhs,sz,wkspc,lwkspc,&NAinfo);
01340 if (NAinfo){
01341 fprintf(stderr,"Error in dgels(1), info = %d.\n",NAinfo);
01342 return 1;
01343 }
01344
01345 (*NTiters)++;
01346
01347
01348 dgemv("N",G_sz,m,1.0,G+G_sz,G_sz,rhs,1,0.0,dXG,1);
01349 dgemv("N",F_sz,m,1.0,F+F_sz,F_sz,rhs,1,0.0,dXF,1);
01350
01351
01352
01353
01354
01355 memset(dW,0,G_sz*sizeof(double));
01356 memset(dZ,0,F_sz*sizeof(double));
01357 for (i=0, dpt=dW; i<K; i++)
01358 for (j=G_blkszs[i]; j>0; dpt+=j, j--)
01359 *dpt = 1.0;
01360 dgemv("N",G_sz,m,-1.0,Gsc,G_sz,rhs,1,1.0,dW,1);
01361 memcpy(LGinv,LG,G_sz*sizeof(double));
01362
01363 for (i=0, pos=0; i<K; pos+=G_blkszs[i]*(G_blkszs[i]+1)/2, i++) {
01364 dtptri("L","N",G_blkszs[i],LGinv+pos,&NAinfo);
01365 if (NAinfo) {
01366 fprintf(stderr,"Error in dtptri(2), info = %d.\n",NAinfo);
01367 return 1;
01368 }
01369 dspgst(2,"L",G_blkszs[i],dW+pos,LGinv+pos,&NAinfo);
01370 if (NAinfo) {
01371 fprintf(stderr,"Error in dspgst(12), info = %d.\n",NAinfo);
01372 return 1;
01373 }
01374 }
01375 for (i=0, dpt=dW, dps=W; i<G_sz; i++, dpt++, dps++)
01376 *dpt = t*(*dpt - *dps);
01377
01378 dgemv("N",F_sz,m,-1.0,Fsc,F_sz,rhs,1,0.0,dZ,1);
01379 memcpy(LFinv,LF,F_sz*sizeof(double));
01380
01381 for (i=0, pos=0; i<L; pos+=F_blkszs[i]*(F_blkszs[i]+1)/2, i++) {
01382 dtptri("L","N",F_blkszs[i],LFinv+pos,&NAinfo);
01383 if (NAinfo) {
01384 fprintf(stderr,"Error in dtptri(3), info = %d.\n",NAinfo);
01385 return 1;
01386 }
01387 dspgst(2,"L",F_blkszs[i],dZ+pos,LFinv+pos,&NAinfo);
01388 if (NAinfo) {
01389 fprintf(stderr,"Error in dspgst(13), info = %d.\n",NAinfo);
01390 return 1;
01391 }
01392 }
01393 dtmp = -t;
01394 daxpy(F_sz,dtmp,Z,1,dZ,1);
01395
01396
01397
01398 if (iters == 1) {
01399 dtmp = gamma/n;
01400 y = 1+sqrt(2.0*dtmp);
01401 dtmp2 = y;
01402 lambda = y-1-log(y)-dtmp;
01403 for (i=0; i<LSITERUB; i++) {
01404 y = y-lambda/(1-1/y);
01405 lambda = y-1-log(y)-dtmp;
01406 if (fabs(lambda)<LSTOL)
01407 break;
01408 }
01409 y = MAX(y,dtmp2);
01410 }
01411
01412
01413 t *= y;
01414
01415
01416 for (i=0; i<LSITERUB; i++) {
01417
01418 double norm_p, norm_d, norm_max;
01419 double gap_upd1=0.0, gap_upd2=0.0;
01420
01421
01422
01423 memcpy(temp,XG,G_sz*sizeof(double));
01424 memcpy(temp2,dXG,G_sz*sizeof(double));
01425 memcpy(temp3,W,G_sz*sizeof(double));
01426 memcpy(temp4,dW,G_sz*sizeof(double));
01427 for (j=0, pos=0, dpt=sigG, dps=sigW; j<K; dpt+=G_blkszs[j],
01428 dps+=G_blkszs[j], pos+=G_blkszs[j]*(G_blkszs[j]+1)/2, j++) {
01429 switch (G_blkszs[j]) {
01430 case 1:
01431 *dpt = *(dXG+pos) / *(XG+pos);
01432 *dps = *(dW+pos) / *(W+pos);
01433 break;
01434 default:
01435 dspgv(1,"N","L",G_blkszs[j],temp2+pos,temp+pos,dpt,
01436 NULL,1,wkspc,&NAinfo);
01437 if (NAinfo) {
01438 fprintf(stderr,"Error in dspgv(3), info = %d.\n",NAinfo);
01439 return 1;
01440 }
01441 dspgv(1,"N","L",G_blkszs[j],temp4+pos,temp3+pos,dps,
01442 NULL,1,wkspc,&NAinfo);
01443 if (NAinfo) {
01444 fprintf(stderr,"Error in dspgv(4), info = %d.\n",NAinfo);
01445 return 1;
01446 }
01447 break;
01448 }
01449 }
01450
01451 memcpy(temp,XF,F_sz*sizeof(double));
01452 memcpy(temp2,dXF,F_sz*sizeof(double));
01453 memcpy(temp3,Z,F_sz*sizeof(double));
01454 memcpy(temp4,dZ,F_sz*sizeof(double));
01455 for (j=0, pos=0, dpt=sigF, dps=sigZ; j<L; dpt+=F_blkszs[j],
01456 dps+=F_blkszs[j], pos+=F_blkszs[j]*(F_blkszs[j]+1)/2, j++) {
01457 switch (F_blkszs[j]) {
01458 case 1:
01459 *dpt = *(dXF+pos) / *(XF+pos);
01460 *dps = *(dZ+pos) / *(Z+pos);
01461 break;
01462 default:
01463 dspgv(1,"N","L",F_blkszs[j],temp2+pos,temp+pos,dpt,
01464 NULL,1,wkspc,&NAinfo);
01465 if (NAinfo) {
01466 fprintf(stderr,"Error in dspgv(5), info = %d.\n",NAinfo);
01467 return 1;
01468 }
01469 dspgv(1,"N","L",F_blkszs[j],temp4+pos,temp3+pos,dps,
01470 NULL,1,wkspc,&NAinfo);
01471 if (NAinfo) {
01472 fprintf(stderr,"Error in dspgv(6), info = %d.\n",NAinfo);
01473 return 1;
01474 }
01475 break;
01476 }
01477 }
01478
01479
01480
01481
01482 norm_p = dnrm2(n,sigF,1);
01483 norm_p += dnrm2(l,sigG,1);
01484 norm_d = dnrm2(n,sigZ,1);
01485 norm_d += dnrm2(l,sigW,1);
01486 norm_max = MAX(norm_p,norm_d);
01487
01488
01489
01490 alpha[0]=0.0;
01491 alpha[1]=0.0;
01492 for (j=0; j<LSITERUB; j++) {
01493 grad1 = 0.0;
01494 grad2 = 0.0;
01495 hess1 = 0.0;
01496 hess2 = 0.0;
01497 for (k=0, dps=sigG, dpt=sigW; k<l; k++, dps++, dpt++) {
01498 dtmp = 1 + alpha[0] * *dps;
01499 dtmp2 = 1 + alpha[1] * *dpt;
01500 grad1 -= t * *dps / dtmp;
01501 grad2 -= t * *dpt / dtmp2;
01502 hess1 += t * SQR(*dps) / SQR(dtmp);
01503 hess2 += t * SQR(*dpt) / SQR(dtmp2);
01504 }
01505 for (k=0, dps=sigF, dpt=sigZ; k<n; k++, dps++, dpt++) {
01506 dtmp = 1 + alpha[0] * *dps;
01507 dtmp2 = 1 + alpha[1] * *dpt;
01508 grad1 -= *dps / dtmp;
01509 grad2 -= *dpt / dtmp2;
01510 hess1 += SQR(*dps) / SQR(dtmp);
01511 hess2 += SQR(*dpt) / SQR(dtmp2);
01512 }
01513 grad1 += t*ddot(m,c,1,rhs,1);
01514 grad2 += t*(inprd(dW,G,K,G_blkszs)+inprd(dZ,F,L,F_blkszs));
01515
01516 if (norm_p>SIGTOL*norm_max && norm_d>SIGTOL*norm_max) {
01517 lambda = sqrt(SQR(grad1)/hess1+SQR(grad2)/hess2);
01518 dtmp = 1/(1+lambda);
01519 alpha[0] -= dtmp*grad1/hess1;
01520 alpha[1] -= dtmp*grad2/hess2;
01521 } else if (norm_p>SIGTOL*norm_max) {
01522 lambda = sqrt(SQR(grad1)/hess1);
01523 alpha[0] -= 1/(1+lambda)*grad1/hess1;
01524 } else if (norm_d>SIGTOL*norm_max) {
01525 lambda = sqrt(SQR(grad2)/hess2);
01526 alpha[1] -= 1/(1+lambda)*grad2/hess2;
01527 } else
01528 lambda = 0;
01529 if (lambda < LSTOL)
01530 break;
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 if (!i) {
01546 gap_upd1 = ddot(m,c,1,rhs,1);
01547 gap_upd2 = inprd(dZ,F,L,F_blkszs)+inprd(dW,G,K,G_blkszs);
01548 }
01549 dtmp = alpha[0]*gap_upd1;
01550 gap += dtmp+alpha[1]*gap_upd2;
01551 ul[0] += dtmp;
01552 for (j=0; j<l; j++) {
01553 gap -= (log(1.0 + alpha[0] * *(sigG+j))
01554 +log(1.0 + alpha[1] * *(sigW+j)));
01555 ul[0] -= log(1.0 + alpha[0] * *(sigG+j));
01556 }
01557
01558
01559 daxpy(m,*alpha,rhs,1,x,1);
01560 daxpy(G_sz,*alpha,dXG,1,XG,1);
01561 daxpy(F_sz,*alpha,dXF,1,XF,1);
01562 daxpy(G_sz,*(alpha+1),dW,1,W,1);
01563 daxpy(F_sz,*(alpha+1),dZ,1,Z,1);
01564
01565 if (!i) {
01566 beta = -n;
01567 eig_val(sigF,XF,L,F_blkszs,F_sz,wkspc);
01568 eig_val(sigZ,Z,L,F_blkszs,F_sz,wkspc);
01569 for (j=0; j<n; j++)
01570 beta += log(1 / *(sigF+j)) + log(1 / *(sigZ+j));
01571 } else {
01572 for (j=0; j<n; j++)
01573 beta -= log(1.0 + alpha[0] * *(sigF+j))
01574 +log(1.0 + alpha[1] * *(sigZ+j));
01575 }
01576
01577
01578 psi_ub = t*gap+beta-n*log(t);
01579 dtmp = MAX(abstol,MAX(MINABSTOL,reltol*MAX(-ul[0],ul[1])));
01580 if (gamma-psi_ub < LSTOL || t > 10*n/MAX(abstol,MINABSTOL)
01581 || gap<dtmp)
01582 break;
01583
01584
01585
01586 t_old = t;
01587 t = t_old+(gamma-psi_ub)/gap;
01588 dtmp = t;
01589 lambda = t*gap+beta-n*log(t)-gamma;
01590 for (j=0; j<LSITERUB; j++) {
01591 t -= lambda/(gap-n/t);
01592 lambda = t*gap+beta-n*log(t)-gamma;
01593 if (fabs(lambda) < LSTOL)
01594 break;
01595 }
01596 t = MAX(t,dtmp);
01597
01598 }
01599
01600 }
01601
01602 return 1;
01603 }
01604