void test1(){ std::cerr << "-------------------------------------" << std::endl; std::cerr << "Testing linear search." << std::endl; int dim=2; double oLoc[2],oVal; double grad[2],dir[2]; double nLoc[2],nVal; int resCode; double (*func)(double *); double (*gradFunc)(double *,double *); func = circ_0_0; gradFunc = circ_0_0_grad; oLoc[0] = 0;oLoc[1] = 1.0; oVal = func(oLoc); TEST_ASSERT(fabs(oVal-1.0)<1e-4); gradFunc(oLoc,grad); dir[0] = 0; dir[1] = -.5; BFGSOpt::linearSearch(dim,oLoc,oVal,grad,dir,nLoc,nVal,func,0.5,resCode); TEST_ASSERT(resCode==0); TEST_ASSERT(fabs(nVal-0.25)<1e-4); TEST_ASSERT(fabs(nLoc[0])<1e-4); TEST_ASSERT(fabs(nLoc[1]-0.5)<1e-4); oLoc[0] = 1.0;oLoc[1] = 1.0; oVal = func(oLoc); TEST_ASSERT(fabs(oVal-2.0)<1e-4); gradFunc(oLoc,grad); dir[0] = -.5; dir[1] = -.5; BFGSOpt::linearSearch(dim,oLoc,oVal,grad,dir,nLoc,nVal,func,1.0,resCode); TEST_ASSERT(resCode==0); TEST_ASSERT(fabs(nVal-0.5)<1e-4); TEST_ASSERT(fabs(nLoc[0]-0.5)<1e-4); TEST_ASSERT(fabs(nLoc[1]-0.5)<1e-4); // we go hugely too far, but the dir gets cut in half, so we // immediately hit the minimum func = circ_0_0; oLoc[0] = 0;oLoc[1] = 1.0; oVal = func(oLoc); TEST_ASSERT(fabs(oVal-1.0)<1e-4); gradFunc(oLoc,grad); dir[0] = 0; dir[1] = -2; BFGSOpt::linearSearch(dim,oLoc,oVal,grad,dir,nLoc,nVal,func,2.0,resCode); TEST_ASSERT(resCode==0); TEST_ASSERT(fabs(nVal)<1e-4); TEST_ASSERT(fabs(nLoc[0])<1e-4); TEST_ASSERT(fabs(nLoc[1])<1e-4); std::cerr << " done" << std::endl; }
// simplified evaluation for interactive render AColor Gradient::DispEvalFunc(float u, float v) { float a = gradFunc(u,v); if (a<center) { a = a/center; return col[2]*(1.0f-a) + col[1]*a; } else if (a>center) { a = (a-center)/(1.0f-center); return col[1]*(1.0f-a) + col[0]*a; } else return col[1]; }
Point3 Gradient::EvalNormalPerturb(ShadeContext& sc) { Point3 dPdu, dPdv; if (!sc.doMaps) return Point3(0,0,0); if (gbufID) sc.SetGBufferID(gbufID); Point2 dM = uvGen->EvalDeriv(sc,&mysamp); uvGen->GetBumpDP(sc,dPdu,dPdv); #if 0 // Blinn's algorithm Point3 N = sc.Normal(); Point3 uVec = CrossProd(N,dPdv); Point3 vVec = CrossProd(N,dPdu); Point3 np = -dM.x*uVec+dM.y*vVec; #else // Lazy algorithm Point3 np = dM.x*dPdu+dM.y*dPdv; // return texout->Filter(dM.x*dPdu+dM.y*dPdv); #endif Texmap* sub[3]; for (int i=0; i<3; i++) sub[i] = mapOn[i]?subTex[i]:NULL; if (sub[0]||sub[1]||sub[2]) { // d((1-k)*a + k*b ) = dk*(b-a) + k*(db-da) + da float a,b,k; Point3 da,db; Point2 UV, dUV; uvGen->GetUV(sc, UV,dUV); k = gradFunc(UV.x,UV.y); if (k<=center) { k = k/center; EVALSUBPERTURB(a,da,2); EVALSUBPERTURB(b,db,1); } else { k = (k-center)/(1.0f-center); EVALSUBPERTURB(a,da,1); EVALSUBPERTURB(b,db,0); } np = (b-a)*np + k*(db-da) + da; } return texout->Filter(np); }
AColor Gradient::EvalFunction( ShadeContext& sc, float u, float v, float du, float dv) { int n1=0, n2=0; float a = gradFunc(u,v); if (a<center) { a = a/center; n1 = 2; n2 = 1; } else if (a>center) { a = (a-center)/(1.0f-center); n1 = 1; n2 = 0; } else { return (mapOn[1]&&subTex[1]) ? subTex[1]->EvalColor(sc): col[1]; } Color c1, c2; c1 = mapOn[n1]&&subTex[n1] ? subTex[n1]->EvalColor(sc): col[n1]; c2 = mapOn[n2]&&subTex[n2] ? subTex[n2]->EvalColor(sc): col[n2]; return c1*(1.0f-a) + c2*a; }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) try { // Check to see if we have the correct number of input and output // arguments. if (nrhs < minNumInputArgs) throw MatlabException("Incorrect number of input arguments"); // Get the starting point for the variables. This is specified in // the first input argument. The variables must be either a single // matrix or a cell array of matrices. int k = 0; // The index of the current input argument. ArrayOfMatrices x0(prhs[k++]); // Create the output, which stores the solution obtained from // running IPOPT. There should be as many output arguments as cell // entries in X. if (nlhs != x0.length()) throw MatlabException("Incorrect number of output arguments"); ArrayOfMatrices x(plhs,x0); // Load the lower and upper bounds on the variables as // ArrayOfMatrices objects. They should have the same structure as // the ArrayOfMatrices object "x". ArrayOfMatrices lb(prhs[k++]); ArrayOfMatrices ub(prhs[k++]); // Check to make sure the bounds make sense. if (lb != x || ub != x) throw MatlabException("Input arguments LB and UB must have the same \ structure as X"); // Get the Matlab callback functions. MatlabString objFunc(prhs[k++]); MatlabString gradFunc(prhs[k++]); // Get the auxiliary data. const mxArray* auxData; const mxArray* ptr = prhs[k++]; if (nrhs > 5) { if (mxIsEmpty(ptr)) auxData = 0; else auxData = ptr; } else auxData = 0; // Get the intermediate callback function. MatlabString* iterFunc; ptr = prhs[k++]; if (nrhs > 6) { if (mxIsEmpty(ptr)) iterFunc = 0; else iterFunc = new MatlabString(ptr); } else iterFunc = 0; // Set the options for the L-BFGS algorithm to their defaults. int maxiter = defaultmaxiter; int m = defaultm; double factr = defaultfactr; double pgtol = defaultpgtol; // Process the remaining input arguments, which set options for // the IPOPT algorithm. while (k < nrhs) { // Get the option label from the Matlab input argument. MatlabString optionLabel(prhs[k++]); if (k < nrhs) { // Get the option value from the Matlab input argument. MatlabScalar optionValue(prhs[k++]); double value = optionValue; if (!strcmp(optionLabel,"maxiter")) maxiter = (int) value; else if (!strcmp(optionLabel,"m")) m = (int) value; else if (!strcmp(optionLabel,"factr")) factr = value / mxGetEps(); else if (!strcmp(optionLabel,"pgtol")) pgtol = value; else { if (iterFunc) delete iterFunc; throw MatlabException("Nonexistent option"); } } } // Create a new instance of the optimization problem. x = x0; MatlabProgram program(x,lb,ub,&objFunc,&gradFunc,iterFunc, (mxArray*) auxData,m,maxiter,factr,pgtol); // Run the L-BFGS-B solver. SolverExitStatus exitStatus = program.runSolver(); if (exitStatus == abnormalTermination) { if (iterFunc) delete iterFunc; throw MatlabException("Solver unable to satisfy convergence \ criteria due to abnormal termination"); } else if (exitStatus == errorOnInput) {