int FitNullModel(Matrix& mat_Xnull, Matrix& mat_y, const EigenMatrix& kinshipU, const EigenMatrix& kinshipS){ // type conversion Eigen::MatrixXf x; Eigen::MatrixXf y; G_to_Eigen(mat_Xnull, &x); G_to_Eigen(mat_y, &y); this->lambda = kinshipS.mat; const Eigen::MatrixXf& U = kinshipU.mat; // rotate this->ux = U.transpose() * x; this->uy = U.transpose() * y; // get beta, sigma2_g and delta // where delta = sigma2_e / sigma2_g double loglik[101]; int maxIndex = -1; double maxLogLik = 0; for (int i = 0; i <= 100; ++i ){ double d = exp(-10 + i * 0.2); getBetaSigma2(d); loglik[i] = getLogLikelihood(d); // fprintf(stderr, "%d\tdelta=%g\tll=%lf\n", i, delta, loglik[i]); if (std::isnan(loglik[i])) { continue; } if (maxIndex < 0 || loglik[i] > maxLogLik) { maxIndex = i; maxLogLik = loglik[i]; } } if (maxIndex < -1) { fprintf(stderr, "Cannot optimize\n"); return -1; } if (maxIndex == 0 || maxIndex == 100) { // on the boundary // do not try maximize it. } else { gsl_function F; F.function = goalFunction; F.params = this; Minimizer minimizer; double lb = exp(-10 + (maxIndex-1) * 0.2); double ub = exp(-10 + (maxIndex+1) * 0.2); double start = exp(-10 + maxIndex * 0.2); if (minimizer.minimize(F, start, lb, ub)) { // fprintf(stderr, "Minimization failed, fall back to initial guess.\n"); this->delta = start; } else { this->delta = minimizer.getX(); // fprintf(stderr, "minimization succeed when delta = %g, sigma2_g = %g\n", this->delta, this->sigma2_g); } } // store some intermediate results // fprintf(stderr, "maxIndex = %d, delta = %g, Try brent\n", maxIndex, delta); // fprintf(stderr, "beta[%d][%d] = %g\n", (int)beta.rows(), (int)beta.cols(), beta(0,0)); this->h2 = 1.0 /(1.0 + this->delta); this->sigma2 = this->sigma2_g * this->h2; // we derive different formular to replace original eqn (7) this->gamma = (this->lambda.array() / (this->lambda.array() + this->delta)).sum() / this->sigma2_g / (this->ux.rows() - 1 ) ; // fprintf(stderr, "gamma = %g\n", this->gamma); // transformedY = \Sigma^{-1} * (y_tilda) and y_tilda = y - X * \beta // since \Sigma = (\sigma^2_g * h^2 ) * (U * (\lambda + delta) * U') // transformedY = 1 / (\sigma^2_g * h^2 ) * (U * (\lambda+delta)^{-1} * U' * (y_tilda)) // = 1 / (\sigma^2_g * h^2 ) * (U * \lambda^{-1} * (uResid)) // since h^2 = 1 / (1+delta) // transformedY = (1 + delta/ (\sigma^2_g ) * (U * \lambda^{-1} * (uResid)) Eigen::MatrixXf resid = y - x * (x.transpose() * x).eval().ldlt().solve(x.transpose() * y); // this is y_tilda this->transformedY.noalias() = U.transpose() * resid; this->transformedY = (this->lambda.array() + this->delta).inverse().matrix().asDiagonal() * this->transformedY; this->transformedY = U * this->transformedY; this->transformedY /= this->sigma2_g; // fprintf(stderr, "transformedY(0,0) = %g\n", transformedY(0,0)); this->ySigmaY= (resid.array() * transformedY.array()).sum(); return 0; }
double surface_tension(Minimizer min, Functional f0, LiquidProperties prop, bool verbose, const char *plotname) { int numptspersize = 100; int size = 64; const int gas_size = 10; Lattice lat(Cartesian(1,0,0), Cartesian(0,1,0), Cartesian(0,0,size*prop.lengthscale)); GridDescription gd(lat, 1, 1, numptspersize*size); Grid potential(gd); // Set the density to range from vapor to liquid const double Veff_liquid = -prop.kT*log(prop.liquid_density); const double Veff_gas = -prop.kT*log(prop.vapor_density); for (int i=0; i<gd.NxNyNz*gas_size/size; i++) potential[i] = Veff_gas; for (int i=gd.NxNyNz*gas_size/size; i<gd.NxNyNz; i++) potential[i] = Veff_liquid; // Enable the following line for debugging... //f0.run_finite_difference_test("f0", prop.kT, potential); min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on liberated interface...\n"); fflush(stdout); } const double Einterface = f0.integral(prop.kT, potential); double Ninterface = 0; Grid interface_density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Ninterface += interface_density[i]*gd.dvolume; if (verbose) printf("Got interface energy of %g.\n", Einterface); for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_gas; min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on gas...\n"); fflush(stdout); } const double Egas = f0.integral(prop.kT, potential); double Ngas = 0; { Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Ngas += density[i]*gd.dvolume; } for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_liquid; if (verbose) { printf("\n\n\nWorking on liquid...\n"); fflush(stdout); } min.minimize(f0, gd, &potential); while (min.improve_energy(verbose)) if (verbose) { printf("Working on liquid...\n"); fflush(stdout); } const double Eliquid = f0.integral(prop.kT, potential); double Nliquid = 0; { Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential)); for (int i=0;i<gd.NxNyNz;i++) Nliquid += density[i]*gd.dvolume; } const double X = Ninterface/Nliquid; // Fraction of volume effectively filled with liquid. const double surface_tension = (Einterface - Eliquid*X - Egas*(1-X))/2; if (verbose) { printf("\n\n"); printf("interface energy is %.15g\n", Einterface); printf("gas energy is %.15g\n", Egas); printf("liquid energy is %.15g\n", Eliquid); printf("Ninterface/liquid/gas = %g/%g/%g\n", Ninterface, Nliquid, Ngas); printf("X is %g\n", X); printf("surface tension is %.10g\n", surface_tension); } if (plotname) interface_density.Dump1D(plotname, Cartesian(0,0,0), Cartesian(0,0,size*prop.lengthscale)); return surface_tension; }
int FitNullModel(Matrix& mat_Xnull, Matrix& mat_y, const EigenMatrix& kinshipU, const EigenMatrix& kinshipS){ // sanity check if (mat_Xnull.rows != mat_y.rows) return -1; if (mat_Xnull.rows != kinshipU.mat.rows()) return -1; if (mat_Xnull.rows != kinshipS.mat.rows()) return -1; // type conversion G_to_Eigen(mat_Xnull, &this->ux); G_to_Eigen(mat_y, &this->uy); this->lambda = kinshipS.mat; const Eigen::MatrixXf& U = kinshipU.mat; // rotate this->ux = U.transpose() * this->ux; this->uy = U.transpose() * this->uy; // get beta, sigma and delta // where delta = sigma2_e / sigma2_g double loglik[101]; int maxIndex = -1; double maxLogLik = 0; for (int i = 0; i <= 100; ++i ){ delta = exp(-10 + i * 0.2); getBetaSigma2(delta); loglik[i] = getLogLikelihood(delta); #ifdef DEBUG fprintf(stderr, "%d\tdelta=%g\tll=%lf\n", i, delta, loglik[i]); fprintf(stderr, "beta(0)=%lf\tsigma2=%lf\n", beta(0), sigma2); #endif if (std::isnan(loglik[i])) { continue; } if (maxIndex < 0 || loglik[i] > maxLogLik) { maxIndex = i; maxLogLik = loglik[i]; } } if (maxIndex < -1) { fprintf(stderr, "Cannot optimize\n"); return -1; } #if 0 fprintf(stderr, "maxIndex = %d\tll=%lf\t\tbeta(0)=%lf\tsigma2=%lf\n", maxIndex, maxLogLik, beta(0), sigma2); #endif if (maxIndex == 0 || maxIndex == 100) { // on the boundary // do not try maximize it. } else { gsl_function F; F.function = goalFunction; F.params = this; Minimizer minimizer; double lb = exp(-10 + (maxIndex-1) * 0.2); double ub = exp(-10 + (maxIndex+1) * 0.2); double start = exp(-10 + maxIndex * 0.2); if (minimizer.minimize(F, start, lb, ub)) { fprintf(stderr, "Minimization failed, fall back to initial guess.\n"); this->delta = start; } else { this->delta = minimizer.getX(); #ifdef DEBUG fprintf(stderr, "minimization succeed when delta = %g, sigma2 = %g\n", this->delta, this->sigma2); #endif } } // store some intermediate results #ifdef DEBUG fprintf(stderr, "delta = sigma2_e/sigma2_g, and sigma2 is sigma2_g\n"); fprintf(stderr, "maxIndex = %d, delta = %g, Try brent\n", maxIndex, delta); fprintf(stderr, "beta[0][0] = %g\t sigma2_g = %g\tsigma2_e = %g\n", beta(0,0), this->sigma2, delta * sigma2); #endif // if (this->test == MetaCov::LRT) { // this->nullLikelihood = getLogLikelihood(this->delta); // } else if (this->test == MetaCov::SCORE) { // this->uResid = this->uy - this->ux * this->beta; // } return 0; }