QString ShaderFactory::addLighting() { QString shader; // shader += " vec3 gx, gy, gz;\n"; // shader += " gx = vec3(1/vsize.x,0,0);\n"; // shader += " gy = vec3(0,1/vsize.y,0);\n"; // shader += " gz = vec3(0,0,1/vsize.z);\n"; // shader += " float vx = texture3D(dataTex, voxelCoord+gx).x - texture3D(dataTex, voxelCoord-gx).x;\n"; // shader += " float vy = texture3D(dataTex, voxelCoord+gy).x - texture3D(dataTex, voxelCoord-gy).x;\n"; // shader += " float vz = texture3D(dataTex, voxelCoord+gz).x - texture3D(dataTex, voxelCoord-gz).x;\n"; // shader += " vec3 grad = vec3(vx, vy, vz);\n"; shader += getGrad(); shader += " if (length(grad) > 0.1)\n"; shader += " {\n"; shader += " grad = normalize(grad);\n"; shader += " vec3 lightVec = viewDir;\n"; shader += " float diff = abs(dot(lightVec, grad));\n"; shader += " vec3 reflecvec = reflect(lightVec, grad);\n"; shader += " float spec = pow(abs(dot(grad, reflecvec)), 512.0);\n"; shader += " colorSample.rgb *= (0.6 + 0.4*diff + spec);\n"; shader += " if (any(greaterThan(colorSample.rgb,vec3(1.0,1.0,1.0)))) \n"; shader += " colorSample.rgb = vec3(1.0,1.0,1.0);\n"; shader += " }\n"; return shader; }
// ** Temporary version int ClpPdco::pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo) { // D1, D2 are positive-definite diagonal matrices defined from d1, d2. // In particular, d2 indicates the accuracy required for // satisfying each row of Ax = b. // // D1 and D2 (via d1 and d2) provide primal and dual regularization // respectively. They ensure that the primal and dual solutions // (x,r) and (y,z) are unique and bounded. // // A scalar d1 is equivalent to d1 = ones(n,1), D1 = diag(d1). // A scalar d2 is equivalent to d2 = ones(m,1), D2 = diag(d2). // Typically, d1 = d2 = 1e-4. // These values perturb phi(x) only slightly (by about 1e-8) and request // that A*x = b be satisfied quite accurately (to about 1e-8). // Set d1 = 1e-4, d2 = 1 for least-squares problems with bound constraints. // The problem is then // // minimize phi(x) + 1/2 norm(d1*x)^2 + 1/2 norm(A*x - b)^2 // subject to bl <= x <= bu. // // More generally, d1 and d2 may be n and m vectors containing any positive // values (preferably not too small, and typically no larger than 1). // Bigger elements of d1 and d2 improve the stability of the solver. // // At an optimal solution, if x(j) is on its lower or upper bound, // the corresponding z(j) is positive or negative respectively. // If x(j) is between its bounds, z(j) = 0. // If bl(j) = bu(j), x(j) is fixed at that value and z(j) may have // either sign. // // Also, r and y satisfy r = D2 y, so that Ax + D2^2 y = b. // Thus if d2(i) = 1e-4, the i-th row of Ax = b will be satisfied to // approximately 1e-8. This determines how large d2(i) can safely be. // // // EXTERNAL FUNCTIONS: // options = pdcoSet; provided with pdco.m // [obj,grad,hess] = pdObj( x ); provided by user // y = pdMat( name,mode,m,n,x ); provided by user if pdMat // is a string, not a matrix // // INPUT ARGUMENTS: // pdObj is a string containing the name of a function pdObj.m // or a function_handle for such a function // such that [obj,grad,hess] = pdObj(x) defines // obj = phi(x) : a scalar, // grad = gradient of phi(x) : an n-vector, // hess = diag(Hessian of phi): an n-vector. // Examples: // If phi(x) is the linear function c"x, pdObj should return // [obj,grad,hess] = [c"*x, c, zeros(n,1)]. // If phi(x) is the entropy function E(x) = sum x(j) log x(j), // [obj,grad,hess] = [E(x), log(x)+1, 1./x]. // pdMat may be an ifexplicit m x n matrix A (preferably sparse!), // or a string containing the name of a function pdMat.m // or a function_handle for such a function // such that y = pdMat( name,mode,m,n,x ) // returns y = A*x (mode=1) or y = A"*x (mode=2). // The input parameter "name" will be the string pdMat. // b is an m-vector. // bl is an n-vector of lower bounds. Non-existent bounds // may be represented by bl(j) = -Inf or bl(j) <= -1e+20. // bu is an n-vector of upper bounds. Non-existent bounds // may be represented by bu(j) = Inf or bu(j) >= 1e+20. // d1, d2 may be positive scalars or positive vectors (see above). // options is a structure that may be set and altered by pdcoSet // (type help pdcoSet). // x0, y0, z0 provide an initial solution. // xsize, zsize are estimates of the biggest x and z at the solution. // They are used to scale (x,y,z). Good estimates // should improve the performance of the barrier method. // // // OUTPUT ARGUMENTS: // x is the primal solution. // y is the dual solution associated with Ax + D2 r = b. // z is the dual solution associated with bl <= x <= bu. // inform = 0 if a solution is found; // = 1 if too many iterations were required; // = 2 if the linesearch failed too often. // PDitns is the number of Primal-Dual Barrier iterations required. // CGitns is the number of Conjugate-Gradient iterations required // if an iterative solver is used (LSQR). // time is the cpu time used. //---------------------------------------------------------------------- // PRIVATE FUNCTIONS: // pdxxxbounds // pdxxxdistrib // pdxxxlsqr // pdxxxlsqrmat // pdxxxmat // pdxxxmerit // pdxxxresid1 // pdxxxresid2 // pdxxxstep // // GLOBAL VARIABLES: // global pdDDD1 pdDDD2 pdDDD3 // // // NOTES: // The matrix A should be reasonably well scaled: norm(A,inf) =~ 1. // The vector b and objective phi(x) may be of any size, but ensure that // xsize and zsize are reasonably close to norm(x,inf) and norm(z,inf) // at the solution. // // The files defining pdObj and pdMat // must not be called Fname.m or Aname.m!! // // // AUTHOR: // Michael Saunders, Systems Optimization Laboratory (SOL), // Stanford University, Stanford, California, USA. // [email protected] // // CONTRIBUTORS: // Byunggyoo Kim, SOL, Stanford University. // [email protected] // // DEVELOPMENT: // 20 Jun 1997: Original version of pdsco.m derived from pdlp0.m. // 29 Sep 2002: Original version of pdco.m derived from pdsco.m. // Introduced D1, D2 in place of gamma*I, delta*I // and allowed for general bounds bl <= x <= bu. // 06 Oct 2002: Allowed for fixed variabes: bl(j) = bu(j) for any j. // 15 Oct 2002: Eliminated some work vectors (since m, n might be LARGE). // Modularized residuals, linesearch // 16 Oct 2002: pdxxx..., pdDDD... names rationalized. // pdAAA eliminated (global copy of A). // Aname is now used directly as an ifexplicit A or a function. // NOTE: If Aname is a function, it now has an extra parameter. // 23 Oct 2002: Fname and Aname can now be function handles. // 01 Nov 2002: Bug fixed in feval in pdxxxmat. //----------------------------------------------------------------------- // global pdDDD1 pdDDD2 pdDDD3 double inf = 1.0e30; double eps = 1.0e-15; double atolold = -1.0, r3ratio = -1.0, Pinf, Dinf, Cinf, Cinf0; printf("\n --------------------------------------------------------"); printf("\n pdco.m Version of 01 Nov 2002"); printf("\n Primal-dual barrier method to minimize a convex function"); printf("\n subject to linear constraints Ax + r = b, bl <= x <= bu"); printf("\n --------------------------------------------------------\n"); int m = numberRows_; int n = numberColumns_; bool ifexplicit = true; CoinDenseVector<double> b(m, rhs_); CoinDenseVector<double> x(n, x_); CoinDenseVector<double> y(m, y_); CoinDenseVector<double> z(n, dj_); //delete old arrays delete [] rhs_; delete [] x_; delete [] y_; delete [] dj_; rhs_ = NULL; x_ = NULL; y_ = NULL; dj_ = NULL; // Save stuff so available elsewhere pdcoStuff_ = stuff; double normb = b.infNorm(); double normx0 = x.infNorm(); double normy0 = y.infNorm(); double normz0 = z.infNorm(); printf("\nmax |b | = %8g max |x0| = %8g", normb , normx0); printf( " xsize = %8g", xsize_); printf("\nmax |y0| = %8g max |z0| = %8g", normy0, normz0); printf( " zsize = %8g", zsize_); //--------------------------------------------------------------------- // Initialize. //--------------------------------------------------------------------- //true = 1; //false = 0; //zn = zeros(n,1); //int nb = n + m; int CGitns = 0; int inform = 0; //--------------------------------------------------------------------- // Only allow scalar d1, d2 for now //--------------------------------------------------------------------- /* if (d1_->size()==1) d1_->resize(n, d1_->getElements()[0]); // Allow scalar d1, d2 if (d2_->size()==1) d2->resize(m, d2->getElements()[0]); // to mean dk * unit vector */ assert (stuff->sizeD1() == 1); double d1 = stuff->getD1(); double d2 = stuff->getD2(); //--------------------------------------------------------------------- // Grab input options. //--------------------------------------------------------------------- int maxitn = options.MaxIter; double featol = options.FeaTol; double opttol = options.OptTol; double steptol = options.StepTol; int stepSame = 1; /* options.StepSame; // 1 means stepx == stepz */ double x0min = options.x0min; double z0min = options.z0min; double mu0 = options.mu0; int LSproblem = options.LSproblem; // See below int LSmethod = options.LSmethod; // 1=Cholesky 2=QR 3=LSQR int itnlim = options.LSQRMaxIter * CoinMin(m, n); double atol1 = options.LSQRatol1; // Initial atol double atol2 = options.LSQRatol2; // Smallest atol,unless atol1 is smaller double conlim = options.LSQRconlim; //int wait = options.wait; // LSproblem: // 1 = dy 2 = dy shifted, DLS // 11 = s 12 = s shifted, DLS (dx = Ds) // 21 = dx // 31 = 3x3 system, symmetrized by Z^{1/2} // 32 = 2x2 system, symmetrized by X^{1/2} //--------------------------------------------------------------------- // Set other parameters. //--------------------------------------------------------------------- int kminor = 0; // 1 stops after each iteration double eta = 1e-4; // Linesearch tolerance for "sufficient descent" double maxf = 10; // Linesearch backtrack limit (function evaluations) double maxfail = 1; // Linesearch failure limit (consecutive iterations) double bigcenter = 1e+3; // mu is reduced if center < bigcenter. // Parameters for LSQR. double atolmin = eps; // Smallest atol if linesearch back-tracks double btol = 0; // Should be small (zero is ok) double show = false; // Controls lsqr iteration log /* double gamma = d1->infNorm(); double delta = d2->infNorm(); */ double gamma = d1; double delta = d2; printf("\n\nx0min = %8g featol = %8.1e", x0min, featol); printf( " d1max = %8.1e", gamma); printf( "\nz0min = %8g opttol = %8.1e", z0min, opttol); printf( " d2max = %8.1e", delta); printf( "\nmu0 = %8.1e steptol = %8g", mu0 , steptol); printf( " bigcenter= %8g" , bigcenter); printf("\n\nLSQR:"); printf("\natol1 = %8.1e atol2 = %8.1e", atol1 , atol2 ); printf( " btol = %8.1e", btol ); printf("\nconlim = %8.1e itnlim = %8d" , conlim, itnlim); printf( " show = %8g" , show ); // LSmethod = 3; ////// Hardwire LSQR // LSproblem = 1; ////// and LS problem defining "dy". /* if wait printf("\n\nReview parameters... then type "return"\n") keyboard end */ if (eta < 0) printf("\n\nLinesearch disabled by eta < 0"); //--------------------------------------------------------------------- // All parameters have now been set. //--------------------------------------------------------------------- double time = CoinCpuTime(); //bool useChol = (LSmethod == 1); //bool useQR = (LSmethod == 2); bool direct = (LSmethod <= 2 && ifexplicit); char solver[7]; strncpy(solver, " LSQR", 7); //--------------------------------------------------------------------- // Categorize bounds and allow for fixed variables by modifying b. //--------------------------------------------------------------------- int nlow, nupp, nfix; int *bptrs[3] = {0}; getBoundTypes(&nlow, &nupp, &nfix, bptrs ); int *low = bptrs[0]; int *upp = bptrs[1]; int *fix = bptrs[2]; int nU = n; if (nupp == 0) nU = 1; //Make dummy vectors if no Upper bounds //--------------------------------------------------------------------- // Get pointers to local copy of model bounds //--------------------------------------------------------------------- CoinDenseVector<double> bl(n, columnLower_); double *bl_elts = bl.getElements(); CoinDenseVector<double> bu(nU, columnUpper_); // this is dummy if no UB double *bu_elts = bu.getElements(); CoinDenseVector<double> r1(m, 0.0); double *r1_elts = r1.getElements(); CoinDenseVector<double> x1(n, 0.0); double *x1_elts = x1.getElements(); if (nfix > 0) { for (int k = 0; k < nfix; k++) x1_elts[fix[k]] = bl[fix[k]]; matVecMult(1, r1, x1); b = b - r1; // At some stage, might want to look at normfix = norm(r1,inf); } //--------------------------------------------------------------------- // Scale the input data. // The scaled variables are // xbar = x/beta, // ybar = y/zeta, // zbar = z/zeta. // Define // theta = beta*zeta; // The scaled function is // phibar = ( 1 /theta) fbar(beta*xbar), // gradient = (beta /theta) grad, // Hessian = (beta2/theta) hess. //--------------------------------------------------------------------- double beta = xsize_; if (beta == 0) beta = 1; // beta scales b, x. double zeta = zsize_; if (zeta == 0) zeta = 1; // zeta scales y, z. double theta = beta * zeta; // theta scales obj. // (theta could be anything, but theta = beta*zeta makes // scaled grad = grad/zeta = 1 approximately if zeta is chosen right.) for (int k = 0; k < nlow; k++) bl_elts[low[k]] = bl_elts[low[k]] / beta; for (int k = 0; k < nupp; k++) bu_elts[upp[k]] = bu_elts[upp[k]] / beta; d1 = d1 * ( beta / sqrt(theta) ); d2 = d2 * ( sqrt(theta) / beta ); double beta2 = beta * beta; b.scale( (1.0 / beta) ); y.scale( (1.0 / zeta) ); x.scale( (1.0 / beta) ); z.scale( (1.0 / zeta) ); //--------------------------------------------------------------------- // Initialize vectors that are not fully used if bounds are missing. //--------------------------------------------------------------------- CoinDenseVector<double> rL(n, 0.0); CoinDenseVector<double> cL(n, 0.0); CoinDenseVector<double> z1(n, 0.0); CoinDenseVector<double> dx1(n, 0.0); CoinDenseVector<double> dz1(n, 0.0); CoinDenseVector<double> r2(n, 0.0); // Assign upper bd regions (dummy if no UBs) CoinDenseVector<double> rU(nU, 0.0); CoinDenseVector<double> cU(nU, 0.0); CoinDenseVector<double> x2(nU, 0.0); CoinDenseVector<double> z2(nU, 0.0); CoinDenseVector<double> dx2(nU, 0.0); CoinDenseVector<double> dz2(nU, 0.0); //--------------------------------------------------------------------- // Initialize x, y, z, objective, etc. //--------------------------------------------------------------------- CoinDenseVector<double> dx(n, 0.0); CoinDenseVector<double> dy(m, 0.0); CoinDenseVector<double> Pr(m); CoinDenseVector<double> D(n); double *D_elts = D.getElements(); CoinDenseVector<double> w(n); double *w_elts = w.getElements(); CoinDenseVector<double> rhs(m + n); //--------------------------------------------------------------------- // Pull out the element array pointers for efficiency //--------------------------------------------------------------------- double *x_elts = x.getElements(); double *x2_elts = x2.getElements(); double *z_elts = z.getElements(); double *z1_elts = z1.getElements(); double *z2_elts = z2.getElements(); for (int k = 0; k < nlow; k++) { x_elts[low[k]] = CoinMax( x_elts[low[k]], bl[low[k]]); x1_elts[low[k]] = CoinMax( x_elts[low[k]] - bl[low[k]], x0min ); z1_elts[low[k]] = CoinMax( z_elts[low[k]], z0min ); } for (int k = 0; k < nupp; k++) { x_elts[upp[k]] = CoinMin( x_elts[upp[k]], bu[upp[k]]); x2_elts[upp[k]] = CoinMax(bu[upp[k]] - x_elts[upp[k]], x0min ); z2_elts[upp[k]] = CoinMax(-z_elts[upp[k]], z0min ); } //////////////////// Assume hessian is diagonal. ////////////////////// // [obj,grad,hess] = feval( Fname, (x*beta) ); x.scale(beta); double obj = getObj(x); CoinDenseVector<double> grad(n); getGrad(x, grad); CoinDenseVector<double> H(n); getHessian(x , H); x.scale((1.0 / beta)); //double * g_elts = grad.getElements(); double * H_elts = H.getElements(); obj /= theta; // Scaled obj. grad = grad * (beta / theta) + (d1 * d1) * x; // grad includes x regularization. H = H * (beta2 / theta) + (d1 * d1) ; // H includes x regularization. /*--------------------------------------------------------------------- // Compute primal and dual residuals: // r1 = b - Aprod(x) - d2*d2*y; // r2 = grad - Atprod(y) + z2 - z1; // rL = bl - x + x1; // rU = x + x2 - bu; */ //--------------------------------------------------------------------- // [r1,r2,rL,rU,Pinf,Dinf] = ... // pdxxxresid1( Aname,fix,low,upp, ... // b,bl,bu,d1,d2,grad,rL,rU,x,x1,x2,y,z1,z2 ); pdxxxresid1( this, nlow, nupp, nfix, low, upp, fix, b, bl_elts, bu_elts, d1, d2, grad, rL, rU, x, x1, x2, y, z1, z2, r1, r2, &Pinf, &Dinf); //--------------------------------------------------------------------- // Initialize mu and complementarity residuals: // cL = mu*e - X1*z1. // cU = mu*e - X2*z2. // // 25 Jan 2001: Now that b and obj are scaled (and hence x,y,z), // we should be able to use mufirst = mu0 (absolute value). // 0.1 worked poorly on StarTest1 with x0min = z0min = 0.1. // 29 Jan 2001: We might as well use mu0 = x0min * z0min; // so that most variables are centered after a warm start. // 29 Sep 2002: Use mufirst = mu0*(x0min * z0min), // regarding mu0 as a scaling of the initial center. //--------------------------------------------------------------------- // double mufirst = mu0*(x0min * z0min); double mufirst = mu0; // revert to absolute value double mulast = 0.1 * opttol; mulast = CoinMin( mulast, mufirst ); double mu = mufirst; double center, fmerit; pdxxxresid2( mu, nlow, nupp, low, upp, cL, cU, x1, x2, z1, z2, ¢er, &Cinf, &Cinf0 ); fmerit = pdxxxmerit(nlow, nupp, low, upp, r1, r2, rL, rU, cL, cU ); // Initialize other things. bool precon = true; double PDitns = 0; //bool converged = false; double atol = atol1; atol2 = CoinMax( atol2, atolmin ); atolmin = atol2; // pdDDD2 = d2; // Global vector for diagonal matrix D2 // Iteration log. int nf = 0; int itncg = 0; int nfail = 0; printf("\n\nItn mu stepx stepz Pinf Dinf"); printf(" Cinf Objective nf center"); if (direct) { printf("\n"); } else { printf(" atol solver Inexact\n"); } double regx = (d1 * x).twoNorm(); double regy = (d2 * y).twoNorm(); // regterm = twoNorm(d1.*x)^2 + norm(d2.*y)^2; double regterm = regx * regx + regy * regy; double objreg = obj + 0.5 * regterm; double objtrue = objreg * theta; printf("\n%3g ", PDitns ); printf("%6.1f%6.1f" , log10(Pinf ), log10(Dinf)); printf("%6.1f%15.7e", log10(Cinf0), objtrue ); printf(" %8.1f\n" , center ); /* if kminor printf("\n\nStart of first minor itn...\n"); keyboard end */ //--------------------------------------------------------------------- // Main loop. //--------------------------------------------------------------------- // Lsqr ClpLsqr thisLsqr(this); // while (converged) { while(PDitns < maxitn) { PDitns = PDitns + 1; // 31 Jan 2001: Set atol according to progress, a la Inexact Newton. // 07 Feb 2001: 0.1 not small enough for Satellite problem. Try 0.01. // 25 Apr 2001: 0.01 seems wasteful for Star problem. // Now that starting conditions are better, go back to 0.1. double r3norm = CoinMax(Pinf, CoinMax(Dinf, Cinf)); atol = CoinMin(atol, r3norm * 0.1); atol = CoinMax(atol, atolmin ); info.r3norm = r3norm; //------------------------------------------------------------------- // Define a damped Newton iteration for solving f = 0, // keeping x1, x2, z1, z2 > 0. We eliminate dx1, dx2, dz1, dz2 // to obtain the system // // [-H2 A" ] [ dx ] = [ w ], H2 = H + D1^2 + X1inv Z1 + X2inv Z2, // [ A D2^2] [ dy ] = [ r1] w = r2 - X1inv(cL + Z1 rL) // + X2inv(cU + Z2 rU), // // which is equivalent to the least-squares problem // // min || [ D A"]dy - [ D w ] ||, D = H2^{-1/2}. (*) // || [ D2 ] [D2inv r1] || //------------------------------------------------------------------- for (int k = 0; k < nlow; k++) H_elts[low[k]] = H_elts[low[k]] + z1[low[k]] / x1[low[k]]; for (int k = 0; k < nupp; k++) H[upp[k]] = H[upp[k]] + z2[upp[k]] / x2[upp[k]]; w = r2; for (int k = 0; k < nlow; k++) w[low[k]] = w[low[k]] - (cL[low[k]] + z1[low[k]] * rL[low[k]]) / x1[low[k]]; for (int k = 0; k < nupp; k++) w[upp[k]] = w[upp[k]] + (cU[upp[k]] + z2[upp[k]] * rU[upp[k]]) / x2[upp[k]]; if (LSproblem == 1) { //----------------------------------------------------------------- // Solve (*) for dy. //----------------------------------------------------------------- H = 1.0 / H; // H is now Hinv (NOTE!) for (int k = 0; k < nfix; k++) H[fix[k]] = 0; for (int k = 0; k < n; k++) D_elts[k] = sqrt(H_elts[k]); thisLsqr.borrowDiag1(D_elts); thisLsqr.diag2_ = d2; if (direct) { // Omit direct option for now } else {// Iterative solve using LSQR. //rhs = [ D.*w; r1./d2 ]; for (int k = 0; k < n; k++) rhs[k] = D_elts[k] * w_elts[k]; for (int k = 0; k < m; k++) rhs[n+k] = r1_elts[k] * (1.0 / d2); double damp = 0; if (precon) { // Construct diagonal preconditioner for LSQR matPrecon(d2, Pr, D); } /* rw(7) = precon; info.atolmin = atolmin; info.r3norm = fmerit; // Must be the 2-norm here. [ dy, istop, itncg, outfo ] = ... pdxxxlsqr( nb,m,"pdxxxlsqrmat",Aname,rw,rhs,damp, ... atol,btol,conlim,itnlim,show,info ); thisLsqr.input->rhs_vec = &rhs; thisLsqr.input->sol_vec = &dy; thisLsqr.input->rel_mat_err = atol; thisLsqr.do_lsqr(this); */ // New version of lsqr int istop; dy.clear(); show = false; info.atolmin = atolmin; info.r3norm = fmerit; // Must be the 2-norm here. thisLsqr.do_lsqr( rhs, damp, atol, btol, conlim, itnlim, show, info, dy , &istop, &itncg, &outfo, precon, Pr); if (precon) dy = dy * Pr; if (!precon && itncg > 999999) precon = true; if (istop == 3 || istop == 7 ) // conlim or itnlim printf("\n LSQR stopped early: istop = //%d", istop); atolold = outfo.atolold; atol = outfo.atolnew; r3ratio = outfo.r3ratio; }// LSproblem 1 // grad = pdxxxmat( Aname,2,m,n,dy ); // grad = A"dy grad.clear(); matVecMult(2, grad, dy); for (int k = 0; k < nfix; k++) grad[fix[k]] = 0; // grad is a work vector dx = H * (grad - w); } else { perror( "This LSproblem not yet implemented\n" ); } //------------------------------------------------------------------- CGitns += itncg; //------------------------------------------------------------------- // dx and dy are now known. Get dx1, dx2, dz1, dz2. //------------------------------------------------------------------- for (int k = 0; k < nlow; k++) { dx1[low[k]] = - rL[low[k]] + dx[low[k]]; dz1[low[k]] = (cL[low[k]] - z1[low[k]] * dx1[low[k]]) / x1[low[k]]; } for (int k = 0; k < nupp; k++) { dx2[upp[k]] = - rU[upp[k]] - dx[upp[k]]; dz2[upp[k]] = (cU[upp[k]] - z2[upp[k]] * dx2[upp[k]]) / x2[upp[k]]; } //------------------------------------------------------------------- // Find the maximum step. //-------------------------------------------------------------------- double stepx1 = pdxxxstep(nlow, low, x1, dx1 ); double stepx2 = inf; if (nupp > 0) stepx2 = pdxxxstep(nupp, upp, x2, dx2 ); double stepz1 = pdxxxstep( z1 , dz1 ); double stepz2 = inf; if (nupp > 0) stepz2 = pdxxxstep( z2 , dz2 ); double stepx = CoinMin( stepx1, stepx2 ); double stepz = CoinMin( stepz1, stepz2 ); stepx = CoinMin( steptol * stepx, 1.0 ); stepz = CoinMin( steptol * stepz, 1.0 ); if (stepSame) { // For NLPs, force same step stepx = CoinMin( stepx, stepz ); // (true Newton method) stepz = stepx; } //------------------------------------------------------------------- // Backtracking linesearch. //------------------------------------------------------------------- bool fail = true; nf = 0; while (nf < maxf) { nf = nf + 1; x = x + stepx * dx; y = y + stepz * dy; for (int k = 0; k < nlow; k++) { x1[low[k]] = x1[low[k]] + stepx * dx1[low[k]]; z1[low[k]] = z1[low[k]] + stepz * dz1[low[k]]; } for (int k = 0; k < nupp; k++) { x2[upp[k]] = x2[upp[k]] + stepx * dx2[upp[k]]; z2[upp[k]] = z2[upp[k]] + stepz * dz2[upp[k]]; } // [obj,grad,hess] = feval( Fname, (x*beta) ); x.scale(beta); obj = getObj(x); getGrad(x, grad); getHessian(x, H); x.scale((1.0 / beta)); obj /= theta; grad = grad * (beta / theta) + d1 * d1 * x; H = H * (beta2 / theta) + d1 * d1; // [r1,r2,rL,rU,Pinf,Dinf] = ... pdxxxresid1( this, nlow, nupp, nfix, low, upp, fix, b, bl_elts, bu_elts, d1, d2, grad, rL, rU, x, x1, x2, y, z1, z2, r1, r2, &Pinf, &Dinf ); //double center, Cinf, Cinf0; // [cL,cU,center,Cinf,Cinf0] = ... pdxxxresid2( mu, nlow, nupp, low, upp, cL, cU, x1, x2, z1, z2, ¢er, &Cinf, &Cinf0); double fmeritnew = pdxxxmerit(nlow, nupp, low, upp, r1, r2, rL, rU, cL, cU ); double step = CoinMin( stepx, stepz ); if (fmeritnew <= (1 - eta * step)*fmerit) { fail = false; break; } // Merit function didn"t decrease. // Restore variables to previous values. // (This introduces a little error, but save lots of space.) x = x - stepx * dx; y = y - stepz * dy; for (int k = 0; k < nlow; k++) { x1[low[k]] = x1[low[k]] - stepx * dx1[low[k]]; z1[low[k]] = z1[low[k]] - stepz * dz1[low[k]]; } for (int k = 0; k < nupp; k++) { x2[upp[k]] = x2[upp[k]] - stepx * dx2[upp[k]]; z2[upp[k]] = z2[upp[k]] - stepz * dz2[upp[k]]; } // Back-track. // If it"s the first time, // make stepx and stepz the same. if (nf == 1 && stepx != stepz) { stepx = step; } else if (nf < maxf) { stepx = stepx / 2; } stepz = stepx; } if (fail) { printf("\n Linesearch failed (nf too big)"); nfail += 1; } else { nfail = 0; } //------------------------------------------------------------------- // Set convergence measures. //-------------------------------------------------------------------- regx = (d1 * x).twoNorm(); regy = (d2 * y).twoNorm(); regterm = regx * regx + regy * regy; objreg = obj + 0.5 * regterm; objtrue = objreg * theta; bool primalfeas = Pinf <= featol; bool dualfeas = Dinf <= featol; bool complementary = Cinf0 <= opttol; bool enough = PDitns >= 4; // Prevent premature termination. bool converged = primalfeas & dualfeas & complementary & enough; //------------------------------------------------------------------- // Iteration log. //------------------------------------------------------------------- char str1[100], str2[100], str3[100], str4[100], str5[100]; sprintf(str1, "\n%3g%5.1f" , PDitns , log10(mu) ); sprintf(str2, "%8.5f%8.5f" , stepx , stepz ); if (stepx < 0.0001 || stepz < 0.0001) { sprintf(str2, " %6.1e %6.1e" , stepx , stepz ); } sprintf(str3, "%6.1f%6.1f" , log10(Pinf) , log10(Dinf)); sprintf(str4, "%6.1f%15.7e", log10(Cinf0), objtrue ); sprintf(str5, "%3d%8.1f" , nf , center ); if (center > 99999) { sprintf(str5, "%3d%8.1e" , nf , center ); } printf("%s%s%s%s%s", str1, str2, str3, str4, str5); if (direct) { // relax } else { printf(" %5.1f%7d%7.3f", log10(atolold), itncg, r3ratio); } //------------------------------------------------------------------- // Test for termination. //------------------------------------------------------------------- if (kminor) { printf( "\nStart of next minor itn...\n"); // keyboard; } if (converged) { printf("\n Converged"); break; } else if (PDitns >= maxitn) { printf("\n Too many iterations"); inform = 1; break; } else if (nfail >= maxfail) { printf("\n Too many linesearch failures"); inform = 2; break; } else { // Reduce mu, and reset certain residuals. double stepmu = CoinMin( stepx , stepz ); stepmu = CoinMin( stepmu, steptol ); double muold = mu; mu = mu - stepmu * mu; if (center >= bigcenter) mu = muold; // mutrad = mu0*(sum(Xz)/n); // 24 May 1998: Traditional value, but // mu = CoinMin(mu,mutrad ); // it seemed to decrease mu too much. mu = CoinMax(mu, mulast); // 13 Jun 1998: No need for smaller mu. // [cL,cU,center,Cinf,Cinf0] = ... pdxxxresid2( mu, nlow, nupp, low, upp, cL, cU, x1, x2, z1, z2, ¢er, &Cinf, &Cinf0 ); fmerit = pdxxxmerit( nlow, nupp, low, upp, r1, r2, rL, rU, cL, cU ); // Reduce atol for LSQR (and SYMMLQ). // NOW DONE AT TOP OF LOOP. atolold = atol; // if atol > atol2 // atolfac = (mu/mufirst)^0.25; // atol = CoinMax( atol*atolfac, atol2 ); // end // atol = CoinMin( atol, mu ); // 22 Jan 2001: a la Inexact Newton. // atol = CoinMin( atol, 0.5*mu ); // 30 Jan 2001: A bit tighter // If the linesearch took more than one function (nf > 1), // we assume the search direction needed more accuracy // (though this may be true only for LPs). // 12 Jun 1998: Ask for more accuracy if nf > 2. // 24 Nov 2000: Also if the steps are small. // 30 Jan 2001: Small steps might be ok with warm start. // 06 Feb 2001: Not necessarily. Reinstated tests in next line. if (nf > 2 || CoinMin( stepx, stepz ) <= 0.01) atol = atolold * 0.1; } //--------------------------------------------------------------------- // End of main loop. //--------------------------------------------------------------------- } for (int k = 0; k < nfix; k++) x[fix[k]] = bl[fix[k]]; z = z1; if (nupp > 0) z = z - z2; printf("\n\nmax |x| =%10.3f", x.infNorm() ); printf(" max |y| =%10.3f", y.infNorm() ); printf(" max |z| =%10.3f", z.infNorm() ); printf(" scaled"); x.scale(beta); y.scale(zeta); z.scale(zeta); // Unscale x, y, z. printf( "\nmax |x| =%10.3f", x.infNorm() ); printf(" max |y| =%10.3f", y.infNorm() ); printf(" max |z| =%10.3f", z.infNorm() ); printf(" unscaled\n"); time = CoinCpuTime() - time; char str1[100], str2[100]; sprintf(str1, "\nPDitns =%10g", PDitns ); sprintf(str2, "itns =%10d", CGitns ); // printf( [str1 " " solver str2] ); printf(" time =%10.1f\n", time); /* pdxxxdistrib( abs(x),abs(z) ); // Private function if (wait) keyboard; */ //----------------------------------------------------------------------- // End function pdco.m //----------------------------------------------------------------------- /* printf("Solution x values:\n\n"); for (int k=0; k<n; k++) printf(" %d %e\n", k, x[k]); */ // Print distribution double thresh[9] = { 0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.00001}; int counts[9] = {0}; for (int ij = 0; ij < n; ij++) { for (int j = 0; j < 9; j++) { if(x[ij] < thresh[j]) { counts[j] += 1; break; } } } printf ("Distribution of Solution Values\n"); for (int j = 8; j > 1; j--) printf(" %g to %g %d\n", thresh[j-1], thresh[j], counts[j]); printf(" Less than %g %d\n", thresh[2], counts[0]); return inform; }
QString ShaderFactory::genXRayShader(int maxSteps, bool firstHit, bool nearest, bool useMask) { QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "uniform sampler3D maskTex;\n"; shader += "uniform sampler1D tagTex;\n"; shader += "uniform sampler3D dataTex;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect exitTex;\n"; shader += "uniform float stepSize;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 viewDir;\n"; shader += "uniform vec3 vcorner;\n"; shader += "uniform vec3 vsize;\n"; shader += "uniform float minZ;\n"; shader += "uniform float maxZ;\n"; shader += "uniform bool saveCoord;\n"; shader += "uniform int skipLayers;\n"; shader += "uniform sampler2DRect entryTex;\n"; shader += "uniform vec3 bgcolor;\n"; shader += "void main(void)\n"; shader += "{\n"; shader += "vec4 exP = texture2DRect(exitTex, gl_FragCoord.st);\n"; shader += "vec4 enP = texture2DRect(entryTex, gl_FragCoord.st);\n"; shader += "if (exP.a < 0.001 || enP.a < 0.001) discard;\n"; shader += "vec3 exitPoint = exP.rgb;\n"; shader += "vec3 entryPoint = enP.rgb;\n"; shader += "vec3 dir = (exitPoint-entryPoint);\n"; shader += "float len = length(dir);\n"; shader += "if (len < 0.001) discard;\n"; shader += "vec3 normDir = normalize(dir);\n"; shader += "vec3 deltaDir = normalize(dir)*stepSize;\n"; shader += "float deltaDirLen = length(deltaDir);\n"; shader += "vec3 voxelCoord = entryPoint;\n"; shader += "vec4 colorAcum = vec4(0.0);\n"; // The dest color shader += "float lengthAcum = 0.0;\n"; // backgroundColor shader += "vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);\n"; shader += "bool gotFirstHit = false;\n"; shader += "int nskipped = 0;\n"; shader += "bool solid = false;\n"; shader += QString("for(int i=0; i<%1; i++)\n").arg(maxSteps); shader += "{\n"; // -- get exact texture coordinate so we don't get tag interpolation -- shader += " vec3 vC = voxelCoord*vsize;\n"; shader += " bvec3 vclt = lessThan(floor(vC+0.5), vC);\n"; shader += " vC += vec3(vclt)*vec3(0.5);\n"; shader += " vC -= vec3(not(vclt))*vec3(0.5);\n"; shader += " vC /= vsize;\n"; if (nearest) shader += " float val = texture3D(dataTex, vC).x;\n"; else shader += " float val = texture3D(dataTex, voxelCoord).x;\n"; shader += " vec4 colorSample = texture2D(lutTex, vec2(val,0.0));\n"; if (useMask) { shader += " float tag = texture3D(maskTex, vC).x;\n"; shader += " vec4 tagcolor = texture1D(tagTex, tag);\n"; shader += " if (tag < 0.001) tagcolor.rgb = colorSample.rgb;\n"; shader += " colorSample.rgb = mix(colorSample.rgb, tagcolor.rgb, 0.5);\n"; // so that we can use tag opacity to hide certain tagged regions // tagcolor.a should either 0 or 1 shader += " colorSample *= tagcolor.a;\n"; } else shader += " float tag = 0;\n"; shader += " if (!gotFirstHit && colorSample.a > 0.001) gotFirstHit = true;\n"; shader += " if (gotFirstHit && nskipped > skipLayers)\n"; shader += " {\n"; shader += " if (saveCoord && colorSample.a > 0.001)"; shader += " {\n"; shader += " gl_FragColor = vec4(vC,1.0);\n"; shader += " return;\n"; shader += " }\n"; if (firstHit) { shader += " if (colorSample.a > 0.001 )\n"; shader += " {\n"; shader += " vec3 voxpos = vcorner + voxelCoord*vsize;"; shader += " vec3 I = voxpos - eyepos;\n"; shader += " float z = dot(I, normalize(dir));\n"; shader += " z = (z-minZ)/(maxZ-minZ);\n"; shader += " z = clamp(z, 0.0, 1.0);\n"; shader += " gl_FragColor = vec4(z,val,tag,1.0);\n"; shader += " return;\n"; shader += " }\n"; } // modulate opacity by angle wrt view direction shader += getGrad(); shader += "if (length(grad) > 0.1)\n"; shader += " {\n"; shader += " grad = normalize(grad);\n"; shader += " colorSample.a *= (0.3+0.9*(1.0-abs(dot(grad,normDir))));\n"; shader += " }\n"; shader += "else\n"; shader += " colorSample.a *= 0.2;\n"; // reduce the opacity shader += " colorSample.a *= 0.1;\n"; shader += " colorSample.rgb *= colorSample.a;\n"; // just add up, don't composite shader += " colorAcum += colorSample;\n"; shader += " }\n"; // gotfirsthit && nskipped > skipLayers shader += " if (lengthAcum >= len )\n"; shader += " {\n"; shader += " colorAcum.rgb = colorAcum.rgb*colorAcum.a + (1.0 - colorAcum.a)*bgColor.rgb;\n"; shader += " break;\n"; // terminate if opacity > 1 or the ray is outside the volume shader += " }\n"; shader += " else if (colorAcum.a > 1.0)\n"; shader += " {\n"; shader += " colorAcum.a = 1.0;\n"; shader += " break;\n"; shader += " }\n"; shader += " voxelCoord += deltaDir;\n"; shader += " lengthAcum += deltaDirLen;\n"; shader += " if (gotFirstHit) \n"; shader += " {\n"; shader += " if (colorSample.a > 0.001)\n"; shader += " {\n"; shader += " if (!solid)\n"; shader += " {\n"; shader += " solid = true;\n"; shader += " nskipped++;\n"; shader += " }\n"; shader += " }\n"; shader += " else\n"; shader += " {\n"; shader += " if (solid)\n"; shader += " {\n"; shader += " solid = false;\n"; shader += " }\n"; shader += " }\n"; shader += " }\n"; shader += "}\n"; //shader += "gl_FragColor = colorAcum;\n"; shader += "gl_FragColor = mix(colorAcum, vec4(bgcolor,1.0), 1.0-colorAcum.a);\n"; shader += "}\n"; return shader; }
QString RcShaderFactory::genXRayShader(bool nearest, float raylenFrac) { QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "uniform sampler3D dataTex;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect exitTex;\n"; shader += "uniform float stepSize;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 viewDir;\n"; shader += "uniform vec3 vcorner;\n"; shader += "uniform vec3 vsize;\n"; shader += "uniform float minZ;\n"; shader += "uniform float maxZ;\n"; shader += "uniform bool saveCoord;\n"; shader += "uniform int skipLayers;\n"; shader += "uniform sampler2DRect entryTex;\n"; shader += "uniform vec3 bgcolor;\n"; shader += "void main(void)\n"; shader += "{\n"; shader += "vec4 exP = texture2DRect(exitTex, gl_FragCoord.st);\n"; shader += "vec4 enP = texture2DRect(entryTex, gl_FragCoord.st);\n"; shader += "if (exP.a < 0.001 || enP.a < 0.001) discard;\n"; shader += "vec3 exitPoint = exP.rgb;\n"; shader += "vec3 entryPoint = enP.rgb;\n"; shader += "vec3 dir = (exitPoint-entryPoint);\n"; shader += "float len = length(dir);\n"; shader += "if (len < 0.001) discard;\n"; shader += "vec3 normDir = normalize(dir);\n"; shader += "vec3 deltaDir = normalize(dir)*stepSize;\n"; shader += "float deltaDirLen = length(deltaDir);\n"; shader += "vec3 voxelCoord = entryPoint;\n"; shader += "vec4 colorAcum = vec4(0.0);\n"; // The dest color shader += "float lengthAcum = 0.0;\n"; // backgroundColor shader += "vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);\n"; shader += "bool gotFirstHit = false;\n"; shader += "int nskipped = 0;\n"; shader += "bool solid = false;\n"; shader += QString("for(int i=0; i<max(10,int(%1*length(exitPoint-entryPoint)/stepSize)); i++)\n").arg(raylenFrac); shader += "{\n"; // -- get exact texture coordinate so we don't get tag interpolation -- shader += " vec3 vC = voxelCoord*vsize;\n"; shader += " bvec3 vclt = lessThan(floor(vC+0.5), vC);\n"; shader += " vC += vec3(vclt)*vec3(0.5);\n"; shader += " vC -= vec3(not(vclt))*vec3(0.5);\n"; shader += " vC /= vsize;\n"; if (nearest) shader += " float val = texture3D(dataTex, vC).x;\n"; else shader += " float val = texture3D(dataTex, voxelCoord).x;\n"; shader += getGrad(); shader += " vec4 colorSample = texture2D(lutTex, vec2(val,length(grad)));\n"; shader += " if (!gotFirstHit && colorSample.a > 0.001) gotFirstHit = true;\n"; shader += " if (gotFirstHit && nskipped > skipLayers)\n"; shader += " {\n"; shader += " if (saveCoord && colorSample.a > 0.001)"; shader += " {\n"; shader += " gl_FragColor = vec4(vC,1.0);\n"; shader += " return;\n"; shader += " }\n"; // modulate opacity by angle wrt view direction shader += "if (length(grad) > 0.1)\n"; shader += " {\n"; shader += " grad = normalize(grad);\n"; shader += " colorSample.a *= (0.3+0.9*(1.0-abs(dot(grad,normDir))));\n"; shader += " }\n"; shader += "else\n"; shader += " colorSample.a *= 0.2;\n"; // reduce the opacity shader += " colorSample.a *= 0.1;\n"; shader += " colorSample.rgb *= colorSample.a;\n"; // just add up, don't composite shader += " colorAcum += colorSample;\n"; shader += " }\n"; // gotfirsthit && nskipped > skipLayers shader += " if (lengthAcum >= len )\n"; shader += " {\n"; shader += " colorAcum.rgb = colorAcum.rgb*colorAcum.a + (1.0 - colorAcum.a)*bgColor.rgb;\n"; shader += " break;\n"; // terminate if opacity > 1 or the ray is outside the volume shader += " }\n"; shader += " else if (colorAcum.a > 1.0)\n"; shader += " {\n"; shader += " colorAcum.a = 1.0;\n"; shader += " break;\n"; shader += " }\n"; shader += " voxelCoord += deltaDir;\n"; shader += " lengthAcum += deltaDirLen;\n"; shader += " if (gotFirstHit) \n"; shader += " {\n"; shader += " if (colorSample.a > 0.001)\n"; shader += " {\n"; shader += " if (!solid)\n"; shader += " {\n"; shader += " solid = true;\n"; shader += " nskipped++;\n"; shader += " }\n"; shader += " }\n"; shader += " else\n"; shader += " {\n"; shader += " if (solid)\n"; shader += " {\n"; shader += " solid = false;\n"; shader += " }\n"; shader += " }\n"; shader += " }\n"; shader += "}\n"; shader += "gl_FragColor = mix(colorAcum, vec4(bgcolor,1.0), 1.0-colorAcum.a);\n"; shader += "}\n"; return shader; }
QString RcShaderFactory::genIsoRaycastShader(bool nearest) { QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "uniform sampler3D dataTex;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect exitTex;\n"; shader += "uniform float stepSize;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 viewDir;\n"; shader += "uniform vec3 vcorner;\n"; shader += "uniform vec3 vsize;\n"; shader += "uniform float minZ;\n"; shader += "uniform float maxZ;\n"; shader += "uniform bool saveCoord;\n"; shader += "uniform int skipLayers;\n"; shader += "uniform sampler2DRect entryTex;\n"; shader += "uniform vec3 bgcolor;\n"; shader += "void main(void)\n"; shader += "{\n"; shader += "vec4 exP = texture2DRect(exitTex, gl_FragCoord.st);\n"; shader += "vec4 enP = texture2DRect(entryTex, gl_FragCoord.st);\n"; shader += "gl_FragData[0] = vec4(0.0);\n"; shader += "gl_FragData[1] = vec4(0.0);\n"; shader += "if (exP.a < 0.001 || enP.a < 0.001) discard;\n"; shader += "vec3 exitPoint = exP.rgb;\n"; shader += "vec3 entryPoint = enP.rgb;\n"; shader += "vec3 dir = (exitPoint-entryPoint);\n"; shader += "float len = length(dir);\n"; shader += "if (len < 0.001) discard;\n"; shader += "vec3 deltaDir = normalize(dir)*stepSize;\n"; shader += "float deltaDirLen = length(deltaDir);\n"; shader += "vec3 voxelCoord = entryPoint;\n"; // shader += "vec4 colorAcum = vec4(0.0);\n"; // The dest color shader += "float lengthAcum = 0.0;\n"; // backgroundColor shader += "vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);\n"; shader += "bool gotFirstHit = false;\n"; shader += "int nskipped = 0;\n"; shader += "bool solid = false;\n"; shader += "for(int i=0; i<int(length(exitPoint-entryPoint)/stepSize); i++)\n"; shader += "{\n"; // -- get exact texture coordinate so we don't get tag interpolation -- shader += " vec3 vC = voxelCoord*vsize;\n"; shader += " bvec3 vclt = lessThan(floor(vC+0.5), vC);\n"; shader += " vC += vec3(vclt)*vec3(0.5);\n"; shader += " vC -= vec3(not(vclt))*vec3(0.5);\n"; shader += " vC /= vsize;\n"; if (nearest) shader += " float val = texture3D(dataTex, vC).x;\n"; else shader += " float val = texture3D(dataTex, voxelCoord).x;\n"; shader += " vec4 colorSample = vec4(1.0);\n"; shader += getGrad(); shader += " float gradlen = length(grad);\n"; shader += " colorSample = texture2D(lutTex, vec2(val,gradlen));\n"; shader += " if (!gotFirstHit && colorSample.a > 0.001) gotFirstHit = true;\n"; shader += " if (gotFirstHit && nskipped > skipLayers)\n"; shader += " {\n"; shader += " if (saveCoord && colorSample.a > 0.001)"; shader += " {\n"; shader += " gl_FragData[0] = vec4(vC,1.0);\n"; shader += " return;\n"; shader += " }\n"; shader += " if (colorSample.a > 0.001 )\n"; shader += " {\n"; shader += " vec3 voxpos = vcorner + voxelCoord*vsize;"; shader += " vec3 I = voxpos - eyepos;\n"; shader += " float z = dot(I, normalize(viewDir));\n"; shader += " z = (z-minZ)/(maxZ-minZ);\n"; shader += " z = clamp(z, 0.0, 1.0);\n"; shader += " gl_FragData[0] = vec4(z,val,gradlen,1.0);\n"; shader += " if (gradlen > 0.2)\n"; shader += " {\n"; shader += " grad = normalize(grad);\n"; shader += " vec3 lightVec = viewDir;\n"; shader += " float diff = abs(dot(lightVec, grad));\n"; shader += " vec3 reflecvec = reflect(lightVec, grad);\n"; shader += " float spec = pow(abs(dot(grad, reflecvec)), 512.0);\n"; shader += " gl_FragData[1] = vec4(1.0,diff,spec,1.0);\n"; shader += " }\n"; shader += " else\n"; shader += " gl_FragData[1] = vec4(1.0,0.0,0.0,1.0);\n"; shader += " return;\n"; shader += " }\n"; shader += " colorSample.rgb *= colorSample.a;\n"; shader += " }\n"; // gotfirsthit && nskipped > skipLayers shader += " if (lengthAcum >= len )\n"; shader += " break;\n"; // terminate if opacity > 1 or the ray is outside the volume shader += " voxelCoord += deltaDir;\n"; shader += " lengthAcum += deltaDirLen;\n"; shader += " if (gotFirstHit) \n"; shader += " {\n"; shader += " if (colorSample.a > 0.001)\n"; shader += " {\n"; shader += " if (!solid)\n"; shader += " {\n"; shader += " solid = true;\n"; shader += " nskipped++;\n"; shader += " }\n"; shader += " }\n"; shader += " else\n"; shader += " {\n"; shader += " if (solid)\n"; shader += " {\n"; shader += " solid = false;\n"; shader += " }\n"; shader += " }\n"; shader += " }\n"; shader += "}\n"; shader += "}\n"; return shader; }
QString RcShaderFactory::genFirstHitShader(bool nearest) { QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "uniform sampler3D dataTex;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect exitTex;\n"; shader += "uniform sampler2DRect entryTex;\n"; shader += "uniform float stepSize;\n"; shader += "uniform vec3 vsize;\n"; shader += "uniform int skipLayers;\n"; shader += "void main(void)\n"; shader += "{\n"; shader += "vec4 exP = texture2DRect(exitTex, gl_FragCoord.st);\n"; shader += "vec4 enP = texture2DRect(entryTex, gl_FragCoord.st);\n"; shader += "gl_FragColor = vec4(0.0);\n"; shader += "if (exP.a < 0.001 || enP.a < 0.001) discard;\n"; shader += "vec3 exitPoint = exP.rgb;\n"; shader += "vec3 entryPoint = enP.rgb;\n"; shader += "vec3 dir = (exitPoint-entryPoint);\n"; shader += "float len = length(dir);\n"; shader += "if (len < 0.001) discard;\n"; shader += "vec3 deltaDir = normalize(dir)*stepSize;\n"; shader += "float deltaDirLen = length(deltaDir);\n"; shader += "vec3 voxelCoord = entryPoint;\n"; shader += "vec4 colorAcum = vec4(0.0);\n"; // The dest color shader += "float lengthAcum = 0.0;\n"; shader += "bool gotFirstHit = false;\n"; shader += "int nskipped = 0;\n"; shader += "bool solid = false;\n"; shader += "for(int i=0; i<int(length(exitPoint-entryPoint)/stepSize); i++)\n"; //shader += QString("for(int i=0; i<%1; i++)\n").arg(maxSteps); shader += "{\n"; // -- get exact texture coordinate so we don't get tag interpolation -- if (nearest) { shader += " vec3 vC = voxelCoord*vsize;\n"; shader += " bvec3 vclt = lessThan(floor(vC+0.5), vC);\n"; shader += " vC += vec3(vclt)*vec3(0.5);\n"; shader += " vC -= vec3(not(vclt))*vec3(0.5);\n"; shader += " vC /= vsize;\n"; shader += " float val = texture3D(dataTex, vC).x;\n"; } else shader += " float val = texture3D(dataTex, voxelCoord).x;\n"; shader += " vec4 colorSample = vec4(1.0);\n"; shader += getGrad(); shader += " float gradlen = length(grad);\n"; shader += " colorSample = texture2D(lutTex, vec2(val,gradlen));\n"; shader += " if (!gotFirstHit && colorSample.a > 0.001) gotFirstHit = true;\n"; shader += " if (gotFirstHit && nskipped > skipLayers)\n"; shader += " {\n"; shader += " if (colorSample.a > 0.001 )\n"; shader += " {\n"; shader += " gl_FragColor = vec4(voxelCoord,1.0);\n"; shader += " return;\n"; shader += " }\n"; shader += " }\n"; // gotfirsthit && nskipped > skipLayers shader += " if (lengthAcum >= len )\n"; shader += " return;\n"; // terminate if opacity > 1 or the ray is outside the volume shader += " voxelCoord += deltaDir;\n"; shader += " lengthAcum += deltaDirLen;\n"; shader += " if (gotFirstHit) \n"; shader += " {\n"; shader += " if (colorSample.a > 0.001)\n"; shader += " {\n"; shader += " if (!solid)\n"; shader += " {\n"; shader += " solid = true;\n"; shader += " nskipped++;\n"; shader += " }\n"; shader += " }\n"; shader += " else\n"; shader += " {\n"; shader += " if (solid)\n"; shader += " solid = false;\n"; shader += " }\n"; shader += " }\n"; // got first hit shader += " }\n"; // loop over maxSteps shader += "}\n"; return shader; }
/* ******************************************************************************** */ int CalcConc(double *x, int **A, double *G, double *x0, int numSS, int numTotal, int MaxIters, double tol, double deltaBar, double eta, double kT, int MaxNoStep, int MaxTrial, double PerturbScale, int quiet, int WriteLogFile, char *logFile, double MolesWaterPerLiter, unsigned long seed) { /* Computes the equilbrium mole fractions of species in dilute solution using a trust region algorithm on the dual problem. Discussion of the method is in Dirks, et al., Thermodynamic analysis of interacting nucleic acid strands, SIAM Review, (2006), in press. The trust region algorithm for solving the dual problem is that in Nocedal and Wright, Numerical Optimization, 1999, page 68, with the dogleg method on page 71. Returns 1 if converged and 0 otherwise. */ int i,j; // Counters, i is over single-species and j is over all complexes int iters; // Number of iterations double *AbsTol; // The absolute tolerance on all values of gradient double rho; // Ratio of actual to predicted reduction in trust region method double delta; // Radius of trust region double *Grad; // The gradient of -g(lambda) double *lambda; // Lagrange multipliers (dual variables),x[j] = Q[j]*exp(lambda[j]) // for j \in \Psi^0 double *p; // The step we take toward minimization double **Hes; // The Hessian double FreeEnergy; // The free energy of the solution unsigned long rand_seed = 0; // Random number seed int nNoStep; // Number of iterations without taking a step int nTrial; // Number of times we've perturbed lambda int **AT; // Transpose of A int RunStats[6]; // Statistics on results from getSearchDir (see comments below) FILE *fplog; // Log file // Initialize iters just so compiler doesn't give a warning when optimization is on iters = 0; // Allocate memory AT = (int **) malloc(numTotal * sizeof(int *)); for (j = 0; j < numTotal; j++) { AT[j] = (int *) malloc(numSS * sizeof(int)); } Hes = (double **) malloc(numSS * sizeof(double *)); for (i = 0; i < numSS; i++) { Hes[i] = (double *) malloc(numSS * sizeof(double)); } AbsTol = (double *) malloc(numSS * sizeof(double)); Grad = (double *) malloc(numSS * sizeof(double)); lambda = (double *) malloc(numSS * sizeof(double)); p = (double *) malloc(numSS * sizeof(double)); // The absolute tolerance is a percentage of the entries in x0 for (i = 0; i < numSS; i++) { AbsTol[i] = tol * x0[i]; } // Compute AT (transpose of A), useful to have around. IntTranspose(AT,A,numSS,numTotal); nTrial = 0; for (i = 0; i < numSS; i++) { Grad[i] = AbsTol[i] + 1.0; // Initialize just to get started. } while (CheckTol(Grad,AbsTol,numSS) == 0 && nTrial < MaxTrial) { if (nTrial == 1) { // Seed the random number generator if necessary rand_seed = GetRandSeed(seed); init_genrand(rand_seed); } // Set initial guess getInitialGuess(x0,lambda,G,AT,A,numSS,numTotal,PerturbScale,rand_seed); // Calculate the counts of the species based on lambda if (getx(x,lambda,G,AT,numSS,numTotal) == 0) { // Should be fine; checked prev. if (quiet == 0) { printf("Overflow error in calcution of mole fractions.\n\n"); printf("Exiting....\n"); } exit(ERR_OVERFLOW); } // Calculate the gradient getGrad(Grad,x0,x,A,numSS,numTotal); // Initialize delta to be just less than deltaBar delta = 0.99 * deltaBar; // Initializations iters = 0; nNoStep = 0; RunStats[0] = 0; // Number of pure Newton steps (didn't hit trust region boundary) RunStats[1] = 0; // Number of pure Cauchy steps (hit trust region boundary) RunStats[2] = 0; // Number of dogleg steps (part Newton and part Cauchy) RunStats[3] = 0; // Number of steps with Cholesky failure forcing Cauchy step RunStats[4] = 0; // Number of steps with irrelevant Cholesky failures RunStats[5] = 0; // Number of failed dogleg calculations // Run trust region with these initial conditions while (iters < MaxIters && CheckTol(Grad,AbsTol,numSS) == 0 && nNoStep < MaxNoStep) { // Compute the Hessian (symmetric, positive, positive definite) getHes(Hes,x,A,numSS,numTotal); // Solve for the search direction (RunStats[getSearchDir(p,Grad,Hes,delta,numSS) - 1])++; // Calculate rho, ratio of actual to predicted reduction rho = getRho(lambda,p,Grad,x,Hes,x0,G,AT,numSS,numTotal); // Adjust delta and make step based on rho if (rho < 0.25) { delta /= 4.0; } else if (rho > 0.75 && fabs(norm(p,numSS) - delta) < NUM_PRECISION) { delta = min2(2.0*delta,deltaBar); } if (rho > eta) { for (i = 0; i < numSS; i++) { lambda[i] += p[i]; } nNoStep = 0; } else { nNoStep++; } // Calculate the mole fractions of the complexes based on lambda if (getx(x,lambda,G,AT,numSS,numTotal) == 0) {// Should be fine;checked prev. if (quiet == 0) { printf("Overflow error in calcution of mole fractions.\n\n"); printf("Exiting....\n"); } exit(ERR_OVERFLOW); } // Calculate the gradient getGrad(Grad,x0,x,A,numSS,numTotal); // Advance the iterations count iters++; } // Advance the number of perturbations we've tried nTrial++; } // Compute the free energy FreeEnergy = 0; // First the reference free energy for (i = 0; i < numSS; i++) { FreeEnergy += x0[i]*(1.0 - log(x0[i])); } // Now the free energy for (j = 0; j < numTotal; j++) { if (x[j] > 0) { FreeEnergy += x[j]*(log(x[j]) + G[j] - 1.0); } } // Convert to kcal/liter of solution FreeEnergy *= kT*MolesWaterPerLiter; /* **************** WRITE OUT RESULTS ********************************* */ if ( nTrial == MaxTrial && quiet == 0) { printf("\n\n TRUST REGION METHOD DID NOT CONVERGE DUE TO PRECISION ISSUES\n\n"); } // Report errors in conservation of mass to screen if (quiet == 0) { // Print out values of the gradient, which is the error in cons. of mass printf("Error in conservation of mass:\n"); for (i = 0; i < numSS; i++) { printf(" %8.6e Molar\n",Grad[i]*MolesWaterPerLiter); } printf("\n"); // Print out the free energy of the solution printf("Free energy = %8.6e kcal/litre of solution\n",FreeEnergy); } // Write out details of calculation to outfile if (WriteLogFile) { if ((fplog = fopen(logFile,"a")) == NULL) { if (quiet == 0) { printf("Error opening %s.\n\nExiting....\n",logFile); } exit(ERR_LOG); } if (nTrial == MaxTrial) { fprintf(fplog,"TRUST REGION DID NOT CONVERGE DUE TO PRECISION ISSUES\n\n"); } fprintf(fplog," --Trust region results:\n"); fprintf(fplog," No. of initial conditions tried: %d\n",nTrial); fprintf(fplog," Results from succesful trial:\n"); fprintf(fplog," No. of iterations: %d\n",iters); fprintf(fplog," No. of Newton steps: %d\n",RunStats[0]); fprintf(fplog," No. of Cauchy steps: %d\n",RunStats[1]); fprintf(fplog," No. of dogleg steps: %d\n",RunStats[2]); fprintf(fplog," No. of Cholesky failures resulting in Cauchy steps: %d\n" ,RunStats[3]); fprintf(fplog," No. of inconsequential Cholesky failures: %d\n", RunStats[4]); fprintf(fplog," No. of dogleg failures: %d\n",RunStats[5]); fprintf(fplog," Error in conservation of mass (units of molarity):\n"); fprintf(fplog," Error\tTolerance\n"); for (i = 0; i < numSS; i++) { fprintf(fplog, " %.14e\t%.14e\n",Grad[i]*MolesWaterPerLiter, AbsTol[i]*MolesWaterPerLiter); } fprintf(fplog," --Free energy of solution = %.14e kcal/litre of solution\n", FreeEnergy); fclose(fplog); } /* **************** END OF WRITING OUT RESULTS **************************** */ // Free memory for (j = 0; j < numTotal; j++) { free(AT[j]); } for (i = 0; i < numSS; i++) { free(Hes[i]); } free(AbsTol); free(AT); free(Hes); free(Grad); free(p); free(lambda); // Return convergence if (nTrial == MaxTrial) { return 0; } else { return 1; } }
QString ShaderFactory::genRaycastShader(int maxSteps, bool firstHit, bool nearest, bool useMask, bool bit16) { QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "uniform sampler3D maskTex;\n"; shader += "uniform sampler1D tagTex;\n"; shader += "uniform sampler3D dataTex;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect exitTex;\n"; shader += "uniform float stepSize;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 viewDir;\n"; shader += "uniform vec3 vcorner;\n"; shader += "uniform vec3 vsize;\n"; shader += "uniform float minZ;\n"; shader += "uniform float maxZ;\n"; shader += "uniform bool saveCoord;\n"; shader += "uniform int skipLayers;\n"; shader += "uniform sampler2DRect entryTex;\n"; shader += "uniform vec3 bgcolor;\n"; shader += "void main(void)\n"; shader += "{\n"; shader += "vec4 exP = texture2DRect(exitTex, gl_FragCoord.st);\n"; shader += "vec4 enP = texture2DRect(entryTex, gl_FragCoord.st);\n"; shader += "if (exP.a < 0.001 || enP.a < 0.001) discard;\n"; shader += "vec3 exitPoint = exP.rgb;\n"; shader += "vec3 entryPoint = enP.rgb;\n"; shader += "vec3 dir = (exitPoint-entryPoint);\n"; shader += "float len = length(dir);\n"; shader += "if (len < 0.001) discard;\n"; //shader += "vec3 normDir = normalize(dir);\n"; shader += "vec3 deltaDir = normalize(dir)*stepSize;\n"; shader += "float deltaDirLen = length(deltaDir);\n"; shader += "vec3 voxelCoord = entryPoint;\n"; shader += "vec4 colorAcum = vec4(0.0);\n"; // The dest color shader += "float lengthAcum = 0.0;\n"; // backgroundColor shader += "vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);\n"; shader += "bool gotFirstHit = false;\n"; shader += "int nskipped = 0;\n"; shader += "bool solid = false;\n"; shader += QString("for(int i=0; i<%1; i++)\n").arg(maxSteps); shader += "{\n"; // -- get exact texture coordinate so we don't get tag interpolation -- shader += " vec3 vC = voxelCoord*vsize;\n"; shader += " bvec3 vclt = lessThan(floor(vC+0.5), vC);\n"; shader += " vC += vec3(vclt)*vec3(0.5);\n"; shader += " vC -= vec3(not(vclt))*vec3(0.5);\n"; shader += " vC /= vsize;\n"; if (nearest) shader += " float val = texture3D(dataTex, vC).x;\n"; else shader += " float val = texture3D(dataTex, voxelCoord).x;\n"; shader += " vec4 colorSample = vec4(0.0);\n"; if (!bit16) shader += " colorSample = texture2D(lutTex, vec2(val,0.0));\n"; else { shader += " int h0 = int(65535.0*val);\n"; shader += " int h1 = h0 / 256;\n"; shader += " h0 = int(mod(float(h0),256.0));\n"; shader += " float fh0 = float(h0)/256.0;\n"; shader += " float fh1 = float(h1)/256.0;\n"; shader += " colorSample = texture2D(lutTex, vec2(fh0,fh1));\n"; } if (useMask) { shader += " float tag = texture3D(maskTex, vC).x;\n"; shader += " vec4 tagcolor = texture1D(tagTex, tag);\n"; shader += " if (tag < 0.001) tagcolor.rgb = colorSample.rgb;\n"; shader += " colorSample.rgb = mix(colorSample.rgb, tagcolor.rgb, 0.5);\n"; // so that we can use tag opacity to hide certain tagged regions // tagcolor.a should either 0 or 1 shader += " colorSample *= tagcolor.a;\n"; } else shader += " float tag = 0;\n"; shader += " if (!gotFirstHit && colorSample.a > 0.001) gotFirstHit = true;\n"; shader += " if (gotFirstHit && nskipped > skipLayers)\n"; shader += " {\n"; if (firstHit) { shader += " if (saveCoord && colorSample.a > 0.001)"; shader += " {\n"; shader += " gl_FragData[0] = vec4(vC,1.0);\n"; shader += " return;\n"; shader += " }\n"; shader += " if (colorSample.a > 0.001 )\n"; shader += " {\n"; shader += " vec3 voxpos = vcorner + voxelCoord*vsize;"; shader += " vec3 I = voxpos - eyepos;\n"; shader += " float z = dot(I, normalize(viewDir));\n"; shader += " z = (z-minZ)/(maxZ-minZ);\n"; shader += " z = clamp(z, 0.0, 1.0);\n"; shader += " gl_FragData[0] = vec4(z,val,tag,1.0);\n"; shader += getGrad(); shader += " if (length(grad) > 0.2)\n"; shader += " {\n"; shader += " grad = normalize(grad);\n"; shader += " vec3 lightVec = viewDir;\n"; shader += " float diff = abs(dot(lightVec, grad));\n"; shader += " vec3 reflecvec = reflect(lightVec, grad);\n"; shader += " float spec = pow(abs(dot(grad, reflecvec)), 512.0);\n"; shader += " gl_FragData[1] = vec4(1.0,diff,spec,1.0);\n"; shader += " }\n"; shader += " else\n"; shader += " gl_FragData[1] = vec4(1.0,0.0,0.0,1.0);\n"; shader += " return;\n"; shader += " }\n"; } else { shader += " if (saveCoord && colorSample.a > 0.001)"; shader += " {\n"; shader += " gl_FragColor = vec4(vC,1.0);\n"; shader += " return;\n"; shader += " }\n"; } shader += getGrad(); shader += addLighting(); shader += " colorSample.rgb *= colorSample.a;\n"; shader += " colorAcum += (1.0 - colorAcum.a) * colorSample;\n"; shader += " }\n"; // gotfirsthit && nskipped > skipLayers shader += " if (lengthAcum >= len )\n"; shader += " {\n"; shader += " colorAcum.rgb = colorAcum.rgb*colorAcum.a + (1.0 - colorAcum.a)*bgColor.rgb;\n"; shader += " break;\n"; // terminate if opacity > 1 or the ray is outside the volume shader += " }\n"; shader += " else if (colorAcum.a > 1.0)\n"; shader += " {\n"; shader += " colorAcum.a = 1.0;\n"; shader += " break;\n"; shader += " }\n"; ////------ // shader += " if (colorSample.a < 0.001)\n"; // skip a few steps // shader += " {\n"; // shader += " voxelCoord += 2*deltaDir;\n"; // shader += " lengthAcum += 2*deltaDirLen;\n"; // shader += " }\n"; ////------ shader += " voxelCoord += deltaDir;\n"; shader += " lengthAcum += deltaDirLen;\n"; shader += " if (gotFirstHit) \n"; shader += " {\n"; // shader += " phaseChanged = false;\n"; shader += " if (colorSample.a > 0.001)\n"; shader += " {\n"; shader += " if (!solid)\n"; shader += " {\n"; shader += " solid = true;\n"; shader += " nskipped++;\n"; // shader += " phaseChanged = true;\n"; shader += " }\n"; shader += " }\n"; shader += " else\n"; shader += " {\n"; shader += " if (solid)\n"; shader += " {\n"; // shader += " phaseChanged = true;\n"; shader += " solid = false;\n"; shader += " }\n"; shader += " }\n"; shader += " }\n"; shader += "}\n"; if (!firstHit) //shader += "gl_FragColor = colorAcum;\n"; shader += "gl_FragColor = mix(colorAcum, vec4(bgcolor,1.0), 1.0-colorAcum.a);\n"; else { shader += "gl_FragData[0] = colorAcum;\n"; shader += "gl_FragData[1] = vec4(0.0,0.0,0.0,1.0);\n"; } shader += "}\n"; return shader; }