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