|
RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00006 // Copyright (2003) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 */ 00030 00031 #include "RTOp_ROp_max_near_feas_step.h" 00032 #include "RTOp_obj_value_vtbl.h" 00033 #include "RTOp_obj_free_free.h" 00034 #include "RTOp_get_reduct_op.hpp" 00035 00036 #include <stdlib.h> 00037 00038 /* */ 00039 /* Implementation functions */ 00040 /* */ 00041 00042 /* Functions for the reduction target object */ 00043 00044 static int get_targ_type_num_entries( 00045 const struct RTOp_obj_type_vtbl_t* vtbl 00046 ,const void* obj_data 00047 ,int* num_values 00048 ,int* num_indexes 00049 ,int* num_chars 00050 ) 00051 { 00052 *num_values = 2; 00053 *num_indexes = 0; 00054 *num_chars = 0; 00055 return 0; 00056 } 00057 00058 static int targ_obj_create( 00059 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00060 , RTOp_ReductTarget* targ_obj ) 00061 { 00062 const int mem_size = sizeof(struct RTOp_ROp_max_near_feas_step_reduct_obj_t); 00063 *targ_obj = malloc( mem_size ); 00064 return vtbl->obj_reinit(vtbl,obj_data,*targ_obj); 00065 } 00066 00067 static int targ_obj_reinit( 00068 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00069 , RTOp_ReductTarget targ_obj ) 00070 { 00071 struct RTOp_ROp_max_near_feas_step_reduct_obj_t 00072 *targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj; 00073 targ->alpha_pos = +1e+50; /* big enough? */ 00074 targ->alpha_neg = -1e+50; /* big enough? */ 00075 return 0; 00076 } 00077 00078 static int targ_extract_state( 00079 const struct RTOp_obj_type_vtbl_t* vtbl 00080 ,const void * obj_data 00081 ,void * reduct_obj 00082 ,int num_values 00083 ,RTOp_value_type value_data[] 00084 ,int num_indexes 00085 ,RTOp_index_type index_data[] 00086 ,int num_chars 00087 ,RTOp_char_type char_data[] 00088 ) 00089 { 00090 struct RTOp_ROp_max_near_feas_step_reduct_obj_t *targ = NULL; 00091 #ifdef RTOp_DEBUG 00092 assert( reduct_obj ); 00093 assert( num_values == 2 ); 00094 assert( num_indexes == 0 ); 00095 assert( num_chars == 0 ); 00096 assert( value_data ); 00097 #endif 00098 targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)reduct_obj; 00099 value_data[0] = targ->alpha_pos; 00100 value_data[1] = targ->alpha_neg; 00101 return 0; 00102 } 00103 00104 static int targ_load_state( 00105 const struct RTOp_obj_type_vtbl_t* vtbl 00106 ,const void* obj_data 00107 ,int num_values 00108 ,const RTOp_value_type value_data[] 00109 ,int num_indexes 00110 ,const RTOp_index_type index_data[] 00111 ,int num_chars 00112 ,const RTOp_char_type char_data[] 00113 ,void ** reduct_obj 00114 ) 00115 { 00116 struct RTOp_ROp_max_near_feas_step_reduct_obj_t *targ = NULL; 00117 #ifdef RTOp_DEBUG 00118 assert( *reduct_obj ); 00119 assert( num_values == 2 ); 00120 assert( num_indexes == 0 ); 00121 assert( num_chars == 0 ); 00122 assert( value_data ); 00123 #endif 00124 targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)*reduct_obj; 00125 targ->alpha_pos = value_data[0]; 00126 targ->alpha_neg = value_data[1]; 00127 return 0; 00128 } 00129 00130 static const struct RTOp_obj_type_vtbl_t targ_obj_vtbl = 00131 { 00132 get_targ_type_num_entries 00133 ,targ_obj_create 00134 ,targ_obj_reinit 00135 ,RTOp_obj_free_free 00136 ,targ_extract_state 00137 ,targ_load_state 00138 }; 00139 00140 /* Other functions */ 00141 00142 static int RTOp_ROp_max_near_feas_step_apply_op( 00143 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00144 , const int num_vecs, const struct RTOp_SubVector vecs[] 00145 , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00146 , RTOp_ReductTarget targ_obj ) 00147 { 00148 RTOp_value_type beta; 00149 struct RTOp_ROp_max_near_feas_step_reduct_obj_t 00150 *targ = NULL; 00151 RTOp_index_type sub_dim; 00152 const RTOp_value_type *xl_val; 00153 ptrdiff_t xl_val_s; 00154 const RTOp_value_type *x_val; 00155 ptrdiff_t x_val_s; 00156 const RTOp_value_type *d_val; 00157 ptrdiff_t d_val_s; 00158 const RTOp_value_type *xu_val; 00159 ptrdiff_t xu_val_s; 00160 register RTOp_index_type k; 00161 RTOp_value_type alpha; 00162 00163 /* */ 00164 /* Validate the input */ 00165 /* */ 00166 if( num_vecs != 4 ) 00167 return RTOp_ERR_INVALID_NUM_VECS; 00168 assert(vecs); 00169 if( num_targ_vecs != 0 ) 00170 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00171 if( vecs[0].global_offset != vecs[1].global_offset 00172 || vecs[0].sub_dim != vecs[1].sub_dim 00173 || vecs[0].global_offset != vecs[2].global_offset 00174 || vecs[0].sub_dim != vecs[2].sub_dim 00175 || vecs[0].global_offset != vecs[3].global_offset 00176 || vecs[0].sub_dim != vecs[3].sub_dim 00177 ) 00178 return RTOp_ERR_INCOMPATIBLE_VECS; 00179 00180 /* */ 00181 /* Get pointers to data */ 00182 /* */ 00183 00184 /* beta */ 00185 beta = *(RTOp_value_type*)obj_data; 00186 /* targ */ 00187 targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj; 00188 /* sub_dim */ 00189 sub_dim = vecs[0].sub_dim; 00190 /* xl */ 00191 xl_val = vecs[0].values; 00192 xl_val_s = vecs[0].values_stride; 00193 /* x */ 00194 x_val = vecs[1].values; 00195 x_val_s = vecs[1].values_stride; 00196 /* d */ 00197 d_val = vecs[2].values; 00198 d_val_s = vecs[2].values_stride; 00199 /* xu */ 00200 xu_val = vecs[3].values; 00201 xu_val_s = vecs[3].values_stride; 00202 00203 /* */ 00204 /* If x has already been found to be infeasible just return */ 00205 /* */ 00206 if(targ->alpha_pos < 0.0) 00207 return 0; /* success! */ 00208 00209 /* */ 00210 /* Perform the reduction operation. */ 00211 /* */ 00212 /* max alpha_pos, min alpha_neg s.t. xl - beta <= x + alpha*d <= xu + beta */ 00213 /* */ 00214 for( k = 0; k < sub_dim; ++k, xl_val += xl_val_s, x_val += x_val_s, d_val += d_val_s, xu_val += xu_val_s ) { 00215 if( *x_val < *xl_val - beta || *x_val > *xu_val + beta ) { 00216 targ->alpha_pos = -1.0; /* x is infeasible as is */ 00217 return 0; /* success! */ 00218 } 00219 if( *d_val != 0.0 ) { 00220 /* check lower bound */ 00221 alpha = (*xl_val - beta - *x_val) / *d_val; 00222 if( ( alpha > 0.0 && alpha < targ->alpha_pos ) 00223 || ( alpha == 0.0 && *d_val < 0.0 ) ) 00224 targ->alpha_pos = alpha; 00225 if( ( alpha < 0.0 && -alpha < -targ->alpha_neg ) 00226 || ( alpha == 0.0 && *d_val > 0.0 ) ) 00227 targ->alpha_neg = alpha; 00228 /* check upper bound */ 00229 alpha = (*xu_val + beta - *x_val) / *d_val; 00230 if( (alpha > 0.0 && alpha < targ->alpha_pos ) 00231 || ( alpha == 0.0 && *d_val > 0.0 ) ) 00232 targ->alpha_pos = alpha; 00233 if( ( alpha < 0.0 && -alpha < -targ->alpha_neg ) 00234 || ( alpha == 0.0 && *d_val < 0.0 ) ) 00235 targ->alpha_neg = alpha; 00236 } 00237 } 00238 00239 return 0; /* success? */ 00240 } 00241 00242 static int reduce_reduct_objs( 00243 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */ 00244 , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj ) 00245 { 00246 const struct RTOp_ROp_max_near_feas_step_reduct_obj_t 00247 *i_targ = (const struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)in_reduct_obj; 00248 struct RTOp_ROp_max_near_feas_step_reduct_obj_t 00249 *io_targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)inout_reduct_obj; 00250 if( i_targ->alpha_pos < io_targ->alpha_pos ) 00251 io_targ->alpha_pos = i_targ->alpha_pos; 00252 if( -i_targ->alpha_neg < -io_targ->alpha_neg ) 00253 io_targ->alpha_neg = i_targ->alpha_neg; 00254 return 0; 00255 } 00256 00257 INSERT_GET_REDUCT_OP_FUNCS( 00258 2,0,0,RTOp_ROp_max_near_feas_step_reduct_obj_t,reduce_reduct_objs 00259 ,targ_load_state,targ_extract_state 00260 ,external_reduct_op,get_reduct_op) 00261 00262 /* Virtual function table */ 00263 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_near_feas_step_vtbl = 00264 { 00265 &RTOp_obj_value_vtbl /* use simple scalar value type for object instance data */ 00266 ,&targ_obj_vtbl 00267 ,"ROp_max_near_feas_step" 00268 ,NULL 00269 ,RTOp_ROp_max_near_feas_step_apply_op 00270 ,reduce_reduct_objs 00271 ,get_reduct_op 00272 }; 00273 00274 /* Class specific functions */ 00275 00276 int RTOp_ROp_max_near_feas_step_construct( RTOp_value_type beta, struct RTOp_RTOp* op ) 00277 { 00278 op->vtbl = &RTOp_ROp_max_near_feas_step_vtbl; 00279 op->vtbl->obj_data_vtbl->obj_create(NULL,NULL,&op->obj_data); 00280 *((RTOp_value_type*)op->obj_data) = beta; 00281 return 0; /* success? */ 00282 } 00283 00284 int RTOp_ROp_max_near_feas_step_destroy( struct RTOp_RTOp* op ) 00285 { 00286 op->vtbl->obj_data_vtbl->obj_free(NULL,NULL,&op->obj_data); 00287 op->vtbl = NULL; 00288 return 0; /* success? */ 00289 } 00290 00291 int RTOp_ROp_max_near_feas_step_set_beta( RTOp_value_type beta, struct RTOp_RTOp* op ) 00292 { 00293 *((RTOp_value_type*)op->obj_data) = beta; 00294 return 0; /* success? */ 00295 } 00296 00297 struct RTOp_ROp_max_near_feas_step_reduct_obj_t 00298 RTOp_ROp_max_near_feas_step_val(RTOp_ReductTarget targ_obj) 00299 { 00300 return *(struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj; 00301 }
1.7.4