MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MoochoPack_PBFGS_helpers.cpp
Go to the documentation of this file.
1 #if 0
2 
3 // @HEADER
4 // ***********************************************************************
5 //
6 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
7 // Copyright (2003) Sandia Corporation
8 //
9 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
10 // license for use of this work by or on behalf of the U.S. Government.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
40 //
41 // ***********************************************************************
42 // @HEADER
43 
44 #include <ostream>
45 #include <iomanip>
46 
49 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_SpVectorClass.hpp"
51 #include "MiWorkspacePack.h"
52 
53 namespace MoochoPack {
54 
56  const ActSetStats &stats
57  ,const value_type act_set_frac_proj_start
58  ,EJournalOutputLevel olevel
59  ,std::ostream &out
60  )
61 {
62  typedef ActSetStats ASS;
63  const size_type
64  num_active_indep = stats.num_active_indep(),
65  num_adds_indep = stats.num_adds_indep(),
66  num_drops_indep = stats.num_drops_indep();
67  const value_type
68  frac_same
69  = ( num_adds_indep == ASS::NOT_KNOWN || num_drops_indep == ASS::NOT_KNOWN || num_active_indep == 0
70  ? 0.0
71  : std::_MAX(((double)(num_active_indep)-num_adds_indep-num_drops_indep) / num_active_indep, 0.0 ) );
72  const bool act_set_calmed_down = ( num_active_indep > 0 && frac_same >= act_set_frac_proj_start );
73  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
74  out << "\nnum_active_indep = " << num_active_indep;
75  if( num_active_indep ) {
76  out << "\nmax(num_active_indep-num_adds_indep-num_drops_indep,0)/(num_active_indep) = "
77  << "max("<<num_active_indep<<"-"<<num_adds_indep<<"-"<<num_drops_indep<<",0)/("<<num_active_indep<<") = "
78  << frac_same;
79  if( act_set_calmed_down )
80  out << " >= ";
81  else
82  out << " < ";
83  out << "act_set_frac_proj_start = " << act_set_frac_proj_start;
84  if( act_set_calmed_down )
85  out << "\nThe active set has calmed down enough\n";
86  else
87  out << "\nThe active set has not calmed down enough\n";
88  }
89  }
90  return act_set_calmed_down;
91 }
92 
94  const SpVectorSlice &nu_indep
95  ,const DVectorSlice &s
96  ,const DVectorSlice &y
97  ,size_type *n_pz_R
98  ,size_type i_x_free[]
99  ,value_type *sRTsR
100  ,value_type *sRTyR
101  )
102 {
103  const size_type
104  n_pz = nu_indep.size();
105  SpVectorSlice::const_iterator
106  nu_indep_itr = nu_indep.begin(),
107  nu_indep_end = nu_indep.end();
108  const SpVectorSlice::difference_type
109  o = nu_indep.offset();
110  *n_pz_R = 0;
111  *sRTsR = 0.0;
112  *sRTyR = 0.0;
113  for( size_type i = 1; i <= n_pz; ++i ) {
114  if( nu_indep_itr != nu_indep_end && nu_indep_itr->indice() + o == i ) {
115  ++nu_indep_itr;
116  }
117  else {
118  ++(*n_pz_R);
119  *i_x_free++ = i;
120  const value_type s_i = s(i);
121  (*sRTsR) += s_i*s_i;
122  (*sRTyR) += s_i*y(i);
123  }
124  }
125 }
126 
128  const SpVectorSlice &nu_indep
129  ,const DVectorSlice &s
130  ,const DVectorSlice &y
131  ,const DVectorSlice &B_XX
132  ,const value_type sRTBRRsR
133  ,const value_type sRTyR
134  ,value_type *sXTBXXsX
135  ,value_type *sXTyX
136  ,size_type l_x_fixed_sorted[]
137  )
138 {
139  using Teuchos::Workspace;
141 
142  const size_type
143  n_pz = nu_indep.size();
144 
145  *sXTBXXsX = 0.0;
146  *sXTyX = 0.0;
147 
148  // Initial spare vector so we can sort this stuff
149  typedef SpVector::element_type ele_t;
150  Workspace<ele_t> sort_array(wss,nu_indep.nz());
151  {
152  SpVectorSlice::const_iterator
153  nu_indep_itr = nu_indep.begin();
154  ele_t
155  *itr = &sort_array[0];
156  for( size_type l = 1 ; l <= nu_indep.nz(); ++l, ++itr, ++nu_indep_itr ) {
157  const size_type i = nu_indep_itr->indice() + nu_indep.offset();
158  const value_type
159  s_i = s(i),
160  y_i = y(i),
161  B_ii = B_XX[l-1],
162  s_i_B_ii_s_i = s_i*B_ii*s_i,
163  s_i_y_i = s_i*y_i;
164  *sXTBXXsX += s_i_B_ii_s_i;
165  *sXTyX += s_i_y_i;
166  itr->initialize( l, s_i_B_ii_s_i/sRTBRRsR + ::fabs(s_i_y_i)/sRTyR );
167  }
168  }
169  // Sort this sparse vector in decending order
170  std::sort(
171  &sort_array[0], &sort_array[0] + sort_array.size()
173  );
174  // Extract this ordering
175  {
176  for( size_type l = 0; l < nu_indep.nz(); ++l )
177  l_x_fixed_sorted[l] = sort_array[l].indice();
178  }
179 }
180 
182  const value_type project_error_tol
183  ,const value_type super_basic_mult_drop_tol
184  ,const SpVectorSlice &nu_indep
185  ,const DVectorSlice &s
186  ,const DVectorSlice &y
187  ,const DVectorSlice &B_XX
188  ,const size_type l_x_fixed_sorted[]
189  ,EJournalOutputLevel olevel
190  ,std::ostream &out
191  ,value_type *sRTBRRsR
192  ,value_type *sRTyR
193  ,value_type *sXTBXXsX
194  ,value_type *sXTyX
195  ,size_type *n_pz_X
196  ,size_type *n_pz_R
197  ,size_type i_x_free[]
198  ,size_type i_x_fixed[]
199  ,ConstrainedOptPack::EBounds bnd_fixed[]
200  )
201 {
202  using std::setw;
203  using std::endl;
204  using std::right;
206  namespace COP = ConstrainedOptPack;
207  using Teuchos::Workspace;
209 
210  const size_type
211  n_pz = nu_indep.size();
212 
213  // Store the status of the variables so that we can put sorted i_x_free[]
214  // and i_x_fixed[] together at the end
215  Workspace<long int> i_x_status(wss,n_pz); // free if > 0 , fixed if < 0 , error if 0
216  std::fill_n( &i_x_status[0], n_pz, 0 );
217  {for( size_type l = 0; l < (*n_pz_R); ++l ) {
218  i_x_status[i_x_free[l]-1] = +1;
219  }
220  // Adjust i_x_free[] and i_x_fixed to meat the projection conditions
221  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
222  out << "\nDetermining which fixed variables to put in superbasis and which to leave out (must have at least one in superbasis)...\n";
223  }
224  const value_type
225  max_nu_indep = norm_inf(nu_indep);
226  const bool
227  all_fixed = n_pz == nu_indep.nz();
228  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ACTIVE_SET) ) {
229  out << "\nmax{|nu_k(indep)|,i=r+1...n} = " << max_nu_indep << std::endl
230  << "super_basic_mult_drop_tol = " << super_basic_mult_drop_tol << std::endl
231  << "project_error_tol = " << project_error_tol << std::endl;
232  }
233  if( super_basic_mult_drop_tol > 1.0 ) {
234  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
235  out << "super_basic_mult_drop_tol = " << super_basic_mult_drop_tol << " > 1"
236  << "\nNo variables will be removed from the super basis! (You might consider decreasing super_basic_mult_drop_tol < 1)\n";
237  }
238  }
239  else {
240  const int prec = out.precision();
241  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ACTIVE_SET) ) {
242  out << endl
243  << right << setw(10) << "i"
244  << right << setw(prec+12) << "nu_indep(i)"
245  << right << setw(1) << " "
246  << right << setw(prec+12) << "s(i)*B(ii)*s(i)"
247  << right << setw(prec+12) << "s_R'*B_RR*s_R"
248  << right << setw(prec+12) << "s_X'*B_XX*s_X"
249  << right << setw(1) << " "
250  << right << setw(prec+12) << "s(i)*y(i)"
251  << right << setw(prec+12) << "s_R'*y_R"
252  << right << setw(prec+12) << "s_X'*y_X"
253  << right << setw(1) << " "
254  << right << setw(14) << "status"
255  << endl
256  << right << setw(10) << "--------"
257  << right << setw(prec+12) << "---------------"
258  << right << setw(1) << " "
259  << right << setw(prec+12) << "---------------"
260  << right << setw(prec+12) << "---------------"
261  << right << setw(prec+12) << "---------------"
262  << right << setw(1) << " "
263  << right << setw(prec+12) << "---------------"
264  << right << setw(prec+12) << "---------------"
265  << right << setw(prec+12) << "---------------"
266  << right << setw(1) << " "
267  << right << setw(14) << "------------"
268  << endl;
269  }
270  // Loop through the fixed variables in decending order of the violation.
271  bool kept_one = false;
272  for( size_type k = 0; k < nu_indep.nz(); ++k ) {
273  const size_type
274  l = l_x_fixed_sorted[k];
275  const SpVectorSlice::element_type
276  &nu_i = *(nu_indep.begin() + (l-1));
277  const size_type
278  i = nu_i.indice() + nu_indep.offset();
279  const value_type
280  abs_val_nu = ::fabs(nu_i.value()),
281  rel_val_nu = abs_val_nu / max_nu_indep,
282  s_i = s(i),
283  y_i = y(i),
284  B_ii = B_XX[l-1],
285  s_i_B_ii_s_i = s_i*B_ii*s_i,
286  s_i_y_i = s_i*y_i;
287  const bool
288  nu_cond = rel_val_nu < super_basic_mult_drop_tol,
289  sXTBXXsX_cond = (*sXTBXXsX) / (*sRTBRRsR) > project_error_tol,
290  sXTyX_cond = ::fabs(*sXTyX) / ::fabs(*sRTyR) > project_error_tol,
291  keep = ( (all_fixed && abs_val_nu == max_nu_indep && !kept_one)
292  || nu_cond || sXTBXXsX_cond || nu_cond );
293  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ACTIVE_SET) ) {
294  out << right << setw(10) << i
295  << right << setw(prec+12) << nu_i.value()
296  << right << setw(1) << (nu_cond ? "*" : " ")
297  << right << setw(prec+12) << s_i_B_ii_s_i
298  << right << setw(prec+12) << (*sRTBRRsR)
299  << right << setw(prec+12) << (*sXTBXXsX)
300  << right << setw(1) << (sXTBXXsX_cond ? "*" : " ")
301  << right << setw(prec+12) << s_i_y_i
302  << right << setw(prec+12) << (*sRTyR)
303  << right << setw(prec+12) << (*sXTyX)
304  << right << setw(1) << (sXTyX_cond ? "*" : " ")
305  << right << setw(14) << (keep ? "superbasic" : "nonbasic")
306  << endl;
307  }
308  if(keep) {
309  kept_one = true;
310  *sRTBRRsR += s_i_B_ii_s_i;
311  *sXTBXXsX -= s_i_B_ii_s_i;
312  *sRTyR += s_i_y_i;
313  *sXTyX -= s_i_y_i;
314  i_x_status[i-1] = +1;
315  ++(*n_pz_R);
316  }
317  else {
318  i_x_status[i-1] = -1;
319  ++(*n_pz_X);
320  }
321  }}
322  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
323  out << "\nFinal selection: n_pz_X = " << (*n_pz_X) << " nonbasic variables and n_pz_R = " << (*n_pz_R) << " superbasic variables\n";
324  }
325  }
326  // Set the final set of i_x_free[] and i_x_fixed[]
327  SpVector::const_iterator
328  nu_itr = nu_indep.begin(),
329  nu_end = nu_indep.end();
330  SpVector::difference_type
331  nu_o = nu_indep.offset();
332  size_type
333  *i_x_free_itr = i_x_free,
334  *i_x_fixed_itr = i_x_fixed;
336  *bnd_fixed_itr = bnd_fixed;
337  {for( size_type i = 1; i <= n_pz; ++i ) {
338  long int status = i_x_status[i-1];
339  TEUCHOS_TEST_FOR_EXCEPT( !( status ) ); // should not be zero!
340  if( status > 0 ) {
341  // A superbasic variable
342  *i_x_free_itr++ = i;
343  }
344  else {
345  // A nonbasic variable
346  for( ; nu_itr->indice() + nu_o < i; ++nu_itr ); // Find the multiplier
347  TEUCHOS_TEST_FOR_EXCEPT( !( nu_itr != nu_end ) );
348  TEUCHOS_TEST_FOR_EXCEPT( !( nu_itr->indice() + nu_o == i ) );
349  *i_x_fixed_itr++ = i;
350  *bnd_fixed_itr++ = ( nu_itr->value() > 0.0 ? COP::UPPER : COP::LOWER );
351  }
352  }}
353  TEUCHOS_TEST_FOR_EXCEPT( !( i_x_free_itr - i_x_free == *n_pz_R ) );
354  TEUCHOS_TEST_FOR_EXCEPT( !( i_x_fixed_itr - i_x_fixed == *n_pz_X ) );
355  TEUCHOS_TEST_FOR_EXCEPT( !( bnd_fixed_itr - bnd_fixed == *n_pz_X ) );
356 }
357 
358 } // end namespace MoochoPack
359 
360 #endif // 0
AbstractLinAlgPack::size_type size_type
void choose_fixed_free(const value_type project_error_tol, const value_type super_basic_mult_drop_tol, const SpVectorSlice &nu_indep, const DVectorSlice &s, const DVectorSlice &y, const DVectorSlice &B_XX, const size_type l_x_fixed_sorted[], EJournalOutputLevel olevel, std::ostream &out, value_type *sRTBRRsR, value_type *sRTyR, value_type *sXTBXXsX, value_type *sXTyX, size_type *n_pz_X, size_type *n_pz_R, size_type i_x_free[], size_type i_x_fixed[], ConstrainedOptPack::EBounds bnd_fixed[])
Choose the rest of i_x_free[] and i_x_fixed[].
void init_i_x_free_sRTsR_sRTyR(const SpVectorSlice &nu_indep, const DVectorSlice &s, const DVectorSlice &y, size_type *n_pz_R, size_type i_x_free[], value_type *sRTsR, value_type *sRTyR)
Initialize i_x_free[], s_R'*s_R and s_R'*y_R for free variables not in nu_indep.
EJournalOutputLevel
enum for journal output.
std::ostream * out
value_type norm_inf(const SparseVectorSlice< T_Ele > &sv_rhs)
result = ||sv_rhs||inf (BLAS IxAMAX)
bool act_set_calmed_down(const ActSetStats &act_set_stats, const value_type act_set_frac_proj_start, EJournalOutputLevel olevel, std::ostream &out)
Determine if the active set has calmed down enough and print this test.
void sort_fixed_max_cond_viol(const SpVectorSlice &nu_indep, const DVectorSlice &s, const DVectorSlice &y, const DVectorSlice &B_XX, const value_type sRTBRRsR, const value_type sRTyR, value_type *sXTBXXsX, value_type *sXTyX, size_type l_x_fixed_sorted[])
Sort fixed variables according to the condition:
SparseVectorSlice< SparseElement< index_type, value_type > > SpVectorSlice
DenseLinAlgPack::VectorSliceTmpl< value_type > DVectorSlice
AbstractLinAlgPack::value_type value_type
Function object class for sorting a sparse vectors in descending order by abs(v(i)).
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()