//------------------------------------------------------------------------ // Generating Set Class - for use with OptGSS //------------------------------------------------------------------------ /*------------------------------------------------------------------------ Copyright (c) 2003, Ricardo Oliva (raoliva@lbl.gov) Lawrence Berkeley National Laboratory ------------------------------------------------------------------------*/ #include "GenSetBase.h" using Teuchos::SerialDenseVector; using Teuchos::SerialDenseMatrix; using std::cerr; using std::endl; namespace OPTPP { // // Methods for Generating Directions // bool GenSetBase::generateAll(SerialDenseMatrix& M, SerialDenseVector& X, double D){ if (Size<=0 || Vdim<=0) { cerr << "***ERROR: GenSetBase::generateAll(SerialDenseMatrix,...) " << "called with size=" << Size << ", vdim=" << Vdim << endl; return false; } if (M.numCols() != Size || M.numRows() != Vdim) { cerr << "***ERROR: GenSetBase::generateAll(SerialDenseMatrix,...) " << "dimesion of M expected to be " << Vdim << "-by-" << Size << " but is " << M.numRows() << "-by-" << M.numCols() << endl; return false; } SerialDenseVector xi(Vdim); for (int i=0; i& M, SerialDenseVector& X, double D){ if (Size<=0 || Vdim<=0 || nActive()<=0) { cerr << "***ERROR: GenSetBase::generateAllActive(SerialDenseMatrix,...) " << "called with size=" << Size << ", vdim=" << Vdim << " nActive = " << nActive() << endl; return false; } if (M.numCols() != nActive() || M.numRows() != Vdim ) { cerr << "***ERROR: GenSetBase::generateAllActive(SerialDenseMatrix,...) " << "dimesion of M expected to be " << Vdim << "-by-" << nActive() << " but is " << M.numRows() << "-by-" << M.numCols() << endl; return false; } SerialDenseVector xi(Vdim); for (int i=0; i GenSetBase::generate(int i) { ///< returns d_i, the ith basis element SerialDenseVector y(Vdim); y = 0; generate(i, 0, y, y); return y; } void GenSetBase::generate(int i, SerialDenseVector& y) { ///< Stores d_i in y y = 0; generate(i, 0, y, y); } SerialDenseVector GenSetBase::generate(int i, double a, SerialDenseVector& x) { ///< Returns x + a * d_i, with d_i = ith basis element SerialDenseVector y(Vdim); generate(i, a, x, y); return y; } */ // -- purely virtual-- to be defined in each derived class: // // generate(int i, double a, SerialDenseVector &x, SerialDenseVector &y) // // ///< Set y = x + a * d_i; should allow y and x to be same vector. // SerialDenseMatrix GenSetBase::pllMesh(int P, SerialDenseVector& xc, SerialDenseVector& xn, double r) // P : num points we want ( ~ num of processors) // xc: the current point; // xn: the "newton" point, tells the dir in which the mesh is grown // r: ||xc-xn||, if known. // // return matrix M with genset generated at y_k = xc+k(xn-xc) // with radius r_k = k^n*r_0, r_0=||xc-xn||/2 // // *** current implementation not optimized for efficiency *** // { int k = 0; SerialDenseVector xk(xn.length()); double rk; SerialDenseMatrix M, A, B; // SerialDenseVector ns = xn - xc; // newton step SerialDenseVector ns(xn.length()); ns = xn; ns -= xc; int m = Vdim; int n = Size; // return at least the base point M.reshape(xn.length(),1); M = xn; int nump = P-1; //-- // main loop: //-- if (r <= 0) r = std::sqrt(ns.dot(ns)); double r0 = 0.25*r; double pert = r0*.05; while (nump > 0) { // generate points xc + k*newton_step + r^k*d(i), i=1..size() ++k; xk = xc; SerialDenseVector AnotherTemp(ns.length()); AnotherTemp = ns.scale(k); xk += AnotherTemp; rk = k*r0; A.reshape(n,m); A = generateAll(xk,rk); // perturbation to avoid potential overlaps int RAND_HALF = RAND_MAX / 2; for (int i=0; i RAND_HALF)? 1 : -1; double amp = std::rand() / RAND_MAX * pert; A(j,i) = A(j,i) + sig * amp ; } // after the first iteration want to add xk to M if (k>1) { B.reshape(M.numRows(),M.numCols()); B=M; B.reshape(M.numRows(), M.numCols()+1); //B = M | xk; for(int i=0; i n) { B=M; B.reshape(M.numRows(), M.numCols()+A.numCols()); //B = M | A; for(int i = 0; i0) { //C = A.SubMatrix(1,m,1,nump); //B = M | C; B = M; B.reshape(M.numRows(), M.numCols()+nump); for(int i=0; i