1 //------------------------------------------------------------------------
2 // Generating Set Class - for use with OptGSS
3 //------------------------------------------------------------------------
4 
5 /*------------------------------------------------------------------------
6  Copyright (c) 2003,
7  Ricardo Oliva (raoliva@lbl.gov)
8  Lawrence Berkeley National Laboratory
9  ------------------------------------------------------------------------*/
10 
11 #include "GenSetBase.h"
12 
13 using Teuchos::SerialDenseVector;
14 using Teuchos::SerialDenseMatrix;
15 
16 using std::cerr;
17 using std::endl;
18 
19 namespace OPTPP {
20 //
21 // Methods for Generating Directions
22 //
23 
24 
generateAll(SerialDenseMatrix<int,double> & M,SerialDenseVector<int,double> & X,double D)25 bool GenSetBase::generateAll(SerialDenseMatrix<int,double>& M, SerialDenseVector<int,double>& X, double D){
26   if (Size<=0 || Vdim<=0) {
27     cerr << "***ERROR: GenSetBase::generateAll(SerialDenseMatrix<int,double>,...) "
28 	 << "called with size=" << Size << ", vdim=" << Vdim << endl;
29     return false;
30   }
31   if (M.numCols() != Size || M.numRows() != Vdim) {
32     cerr << "***ERROR: GenSetBase::generateAll(SerialDenseMatrix<int,double>,...) "
33 	 << "dimesion of M expected to be "
34 	 << Vdim << "-by-" << Size
35 	 << " but is " << M.numRows() << "-by-" << M.numCols()
36 	 << endl;
37     return false;
38   }
39   SerialDenseVector<int,double> xi(Vdim);
40   for (int i=0; i<Size; i++) {
41     std::cout<<"Calling generate from GenSetBase.C"<<std::endl;
42     generate(i+1, D, X, xi);
43     // M.Column(i) = xi;
44     for(int j=0; j< xi.length(); j++)
45       {M(j,i) = xi(j);}
46 
47   }
48   return true;
49 }
50 
generateAllActive(SerialDenseMatrix<int,double> & M,SerialDenseVector<int,double> & X,double D)51 bool GenSetBase::generateAllActive(SerialDenseMatrix<int,double>& M, SerialDenseVector<int,double>& X, double D){
52   if (Size<=0 || Vdim<=0 || nActive()<=0) {
53     cerr << "***ERROR: GenSetBase::generateAllActive(SerialDenseMatrix<int,double>,...) "
54 	 << "called with size=" << Size << ", vdim=" << Vdim
55 	 << " nActive = " << nActive()
56 	 << endl;
57     return false;
58   }
59   if (M.numCols() != nActive() || M.numRows() != Vdim ) {
60     cerr << "***ERROR: GenSetBase::generateAllActive(SerialDenseMatrix<int,double>,...) "
61 	 << "dimesion of M expected to be "
62 	 << Vdim << "-by-" << nActive()
63 	 << " but is " << M.numRows() << "-by-" << M.numCols()
64 	 << endl;
65     return false;
66   }
67   SerialDenseVector<int,double> xi(Vdim);
68   for (int i=0; i<nActive(); i++) {
69     generateActive(i, D, X, xi);
70     //M.Column(i) = xi;
71 for(int j=0; j< xi.length(); j++)
72       {M(j,i) = xi(j);}
73   }
74   return true;
75 }
76 /*
77 SerialDenseVector<int,double> GenSetBase::generate(int i) {
78   ///< returns d_i, the ith basis element
79   SerialDenseVector<int,double> y(Vdim);
80   y = 0;
81   generate(i, 0, y, y);
82   return y;
83 }
84 
85 void GenSetBase::generate(int i, SerialDenseVector<int,double>& y) {
86   ///< Stores d_i in y
87   y = 0;
88   generate(i, 0, y, y);
89 }
90 
91 SerialDenseVector<int,double> GenSetBase::generate(int i, double a, SerialDenseVector<int,double>& x) {
92   ///< Returns  x + a * d_i, with d_i = ith basis element
93   SerialDenseVector<int,double> y(Vdim);
94   generate(i, a, x, y);
95   return y;
96 }
97 */
98 // -- purely virtual--  to be defined in  each derived class:
99 //
100 // generate(int i, double a, SerialDenseVector<int,double> &x, SerialDenseVector<int,double> &y)
101 //
102 // ///< Set  y = x + a * d_i; should allow y and x to be same vector.
103 //
104 
105 
pllMesh(int P,SerialDenseVector<int,double> & xc,SerialDenseVector<int,double> & xn,double r)106 SerialDenseMatrix<int,double> GenSetBase::pllMesh(int P, SerialDenseVector<int,double>& xc, SerialDenseVector<int,double>& xn, double r)
107   // P : num points we want ( ~ num of processors)
108   // xc: the current point;
109   // xn: the "newton" point, tells the dir in which the mesh is grown
110   //  r: ||xc-xn||, if known.
111   //
112   // return matrix M with genset generated at y_k = xc+k(xn-xc)
113   // with radius r_k = k^n*r_0, r_0=||xc-xn||/2
114   //
115   // *** current implementation not optimized for efficiency ***
116   //
117 {
118 
119     int k = 0;
120     SerialDenseVector<int,double> xk(xn.length());
121     double       rk;
122     SerialDenseMatrix<int,double> M, A, B;
123 
124     // SerialDenseVector<int,double> ns = xn - xc;  // newton step
125     SerialDenseVector<int,double> ns(xn.length());
126     ns = xn;
127     ns -= xc;
128 
129     int m = Vdim;
130     int n = Size;
131 
132     // return at least the base point
133     M.reshape(xn.length(),1);
134     M = xn;
135     int nump = P-1;
136 
137     //--
138     // main loop:
139     //--
140     if (r <= 0) r = std::sqrt(ns.dot(ns));
141     double r0 = 0.25*r;
142     double pert = r0*.05;
143     while (nump > 0) {
144 
145       // generate points xc + k*newton_step + r^k*d(i), i=1..size()
146       ++k;
147       xk = xc;
148       SerialDenseVector<int,double> AnotherTemp(ns.length());
149       AnotherTemp = ns.scale(k);
150       xk +=  AnotherTemp;
151       rk = k*r0;
152       A.reshape(n,m);
153       A = generateAll(xk,rk);
154 
155       // perturbation to avoid potential overlaps
156       int RAND_HALF = RAND_MAX / 2;
157       for (int i=0; i<n; i++)
158 	for (int j=0; j<m; j++) {
159 	  int sig = (std::rand() > RAND_HALF)? 1 : -1;
160 	  double amp = std::rand() / RAND_MAX * pert;
161 	  A(j,i) = A(j,i) + sig * amp ;
162 	}
163 
164       // after the first iteration want to add xk to M
165       if (k>1) {
166 	B.reshape(M.numRows(),M.numCols());
167 	B=M;
168 	B.reshape(M.numRows(), M.numCols()+1);
169 	//B = M | xk;
170 	for(int i=0; i<xk.length(); i++)
171 	  B(i,M.numCols()) = xk(i);
172 	M.reshape(B.numRows(),B.numCols());
173 	M = B;
174 	--nump;
175       }
176 
177       // addd to M as many columns as we can afford
178       if (nump > n) {
179 	B=M;
180 	B.reshape(M.numRows(), M.numCols()+A.numCols());
181 	//B = M | A;
182 	for(int i = 0; i<M.numRows(); i++)
183 	  for(int j=M.numCols(); j< M.numCols() + A.numCols(); j++)
184 	    {B(i,j) = A(i,j);}
185 
186       }
187       else if (nump>0) {
188 	//C = A.SubMatrix(1,m,1,nump);
189 	//B = M | C;
190 	B = M;
191 	B.reshape(M.numRows(), M.numCols()+nump);
192 	for(int i=0; i<M.numRows();i++)
193 	  for(int j=M.numRows(); j<B.numCols(); j++)
194 	    {B(i,j) = A(i,j-M.numCols());}
195       }
196 
197       M = B;
198       nump = nump - n;
199 
200     }
201     return M;
202 }
203 
204 } // namespace OPTPP
205