#include "ilt.h" /* ####################################################################### */ /* 最適化したfから圧縮無しのσ^2を求める */ /* ####################################################################### */ double CalcSigma(MATRIX *K1, MATRIX *K2, double *f, HEAD *head, INDATA *d){ int i, incr = 1; int m1 = K1->m, m2 = K2->m; int n1 = K1->n, n2 = K2->n; int nn = n1*n2, mm = m1*m2; int info; double one=1.0, one_=-1.0, zero = 0.0, chi, sigma=0; double *KF, *F, *M; div_t temp; if (head->dimension == 2){ KF = malloc(sizeof(double)*m1*n2); F = malloc(sizeof(double)*nn); M = malloc(sizeof(double)*m1*m2); /* fから行列Fを生成 */ for (i=0; ia, &m1, F, &n1, &zero, KF, &m1, &info); /* (K1*F)*K2Tの計算 */ dgemm_("N", "T", &m1, &m2, &n2, &one, KF, &m1, K2->a, &m2, &zero, M, &m1, &info); /* M = -Mexp + Mcalの計算 */ daxpy_(&mm, &one_, d->m.a, &incr, M, &incr); /* ||Mcal - Msim|| */ chi = dnrm2_(&mm, M, &incr); /* sigma = σ^2 = ||KF-M||^2/m */ sigma = chi*chi/mm; free(KF); free(F); free(M); } if (head->dimension == 1){ M = malloc(sizeof(double)*m1); dgemv_("N", &m1, &n1, &one, K1->a, &m1, f, &incr, &zero, M, &incr); /* M = -Mexp + Mcalの計算 */ daxpy_(&m1, &one_, d->m.a, &incr, M, &incr); chi = dnrm2_(&m1, M, &incr); /* sigma = σ^2 = ||KF-M||^2/m */ sigma = chi*chi/m1; free(M); } return sigma; } /* ####################################################################### */ /* Scurve法でalpha_optを求める */ /* ####################################################################### */ void ScurveAlphaLoop(MATRIX *K0, MATRIX *Mz, HEAD *head, double *f, MATRIX *k1, MATRIX *k2, INDATA *d){ int m = K0->m; int n = K0->n; int i, j, pnt = 0, incr = 1; int alpha_num=head->alpha_num; double *kz, *mz, *cr, *aI, *H; double alpha, sigma; double zero = 0.0, one = 1.0; double alpha_s = head->alpha_start, alpha_e = head->alpha_end; double s_target=head->s_taget, alpha_log; double *alpha_list, *sigma_list, *grad; double *t = NULL; kz = K0->a; mz = Mz->a; cr = malloc(sizeof(double)*m); aI = malloc(sizeof(double)*m*m); H = malloc(sizeof(double)*n*n); alpha_list = (double *)malloc(sizeof(double)*alpha_num); sigma_list = (double *)malloc(sizeof(double)*alpha_num); grad = malloc(sizeof(double)*(alpha_num-1)); /* alphaのグリッド生成 */ for (i=0; i=0; j--){ /* alphaI (diagonal)の初期化*/ for (i=0; i0 だけが解 */ for (i=0; ialpha_loop++; } for (i=0; i s_target && pnt == 0) pnt = i; } double alpha_0, alpha_1, grad_0, grad_1; double sigma_0, sigma_1; int step; alpha_0 = alpha_list[pnt-1]; sigma_0 = sigma_list[pnt-1]; alpha_1 = alpha_list[pnt+1]; sigma_1 = sigma_list[pnt+1]; for (step=1;; step++){ pnt = alpha_num+step; alpha = alpha_0 + 0.5*(alpha_1 - alpha_0); if ((t = (double *)realloc(alpha_list, pnt*sizeof(double))) != NULL){ alpha_list = t; alpha_list[alpha_num+step-1] = alpha; } for (i=0; ialpha = alpha; if ((alpha_1 - alpha_0) < head->alpha_tol) break; printf("delta alpha = %g\n", alpha_1 - alpha_0); printf("grad0 = %g\n", grad_0); printf("grad1 = %g\n", grad_1); head->alpha_loop++; } head->alpha_list = malloc(pnt*sizeof(double)); head->sigma_list = malloc(pnt*sizeof(double)); head->alpha_num = pnt; for (i=0; ialpha_list[i] = alpha_list[i]; head->sigma_list[i] = sigma_list[i]; } free(cr); free(aI); free(H); free(alpha_list); free(sigma_list); free(grad); } void BRDAlphaLoop(MATRIX *K0, MATRIX *Mz, HEAD *head, double *f, MATRIX *k1, MATRIX *k2, INDATA *d){ int m = K0->m; int n = K0->n; int i, incr = 1; double *kz, *mz; double *cr, *cr_n; double *aI, *H; double zero = 0.0, one = 1.0, one_ = -1.0; double alpha_opt, cr_norm, sigma, sigma_z; if (head->alpha0 == 0) { head->alpha = 0.0; return; } kz = K0->a; mz = Mz->a; cr = malloc(sizeof(double)*m); cr_n = malloc(sizeof(double)*m); aI = malloc(sizeof(double)*m*m); H = malloc(sizeof(double)*n*n); /* 初期のfからcrを求める cr=-(Kf-m)/alpha */ dgemv_("N", &m, &n, &one, kz, &m, f, &incr, &zero, cr, &incr); daxpy_(&m, &one_, mz, &incr, cr, &incr); alpha_opt = -1.0/head->alpha0; dscal_(&m, &alpha_opt, cr, &incr); head->alpha = head->alpha0; /* alphaI (diagonal) とH (diagonal)の初期化 */ for (i=0; i<(n*n); i++) H[i] = 0.0; for (i=0; ialpha_loop=0;; head->alpha_loop++){ /* alphaI (diagonal)の初期化*/ for (i=0; ialpha; /* BRDでcrの最適化 */ cr_norm = BRDnewton_modify(kz, mz, aI, cr, H, head, &m, &n); /* crからfの計算f f= kz'*cr, fi>0 だけが解 */ dgemv_("T", &m, &n, &one, kz, &m, cr, &incr, &zero, f, &incr); for (i=0; isigma0 != 0.0) sigma = head->sigma0; printf("c_norm = %g\n", cr_norm); switch(head->Atype){ case 0: alpha_opt = sigma/sigma_z; break; case 1: alpha_opt = sigma_z/dnrm2_(&n, f, &incr)/(sqrt(1-sqrt(2*m)/m)); break; case 2: alpha_opt = sigma_z/dnrm2_(&n, f, &incr); break; case 3: alpha_opt = sigma/dnrm2_(&n, f, &incr)/(sqrt(1-sqrt(2*m)/m)); break; } /* alphaの収束チェック */ if (fabs(alpha_opt - head->alpha)/head->alpha < head->alpha_tol) break; /* alphaをmixingしてupdate */ if (head->alpha_loop > 1) head->alpha = alpha_opt; else head->alpha_loop++; if (head->alpha_loop == head->alpha_loop_max) { printf("Iteration reached maximum alpha loop.\n"); break; } } free(cr_n); free(cr); free(aI); free(H); }