|
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 <math.h> 00032 00033 #define max(a,b) ( (a) > (b) ? (a) : (b) ) 00034 #define min(a,b) ( (a) < (b) ? (a) : (b) ) 00035 00036 #include "RTOp_ROp_max_inequ_viol.h" 00037 #include "RTOp_obj_null_vtbl.h" 00038 #include "RTOp_obj_value_vtbl.h" 00039 #include "RTOp_obj_free_free.h" 00040 #include "RTOp_get_reduct_op.hpp" 00041 00042 #include <stdlib.h> 00043 00044 /* */ 00045 /* Implementation functions */ 00046 /* */ 00047 00048 /* Functions for the reduction target object */ 00049 00050 static int get_targ_type_num_entries( 00051 const struct RTOp_obj_type_vtbl_t* vtbl 00052 ,const void* obj_data 00053 ,int* num_values 00054 ,int* num_indexes 00055 ,int* num_chars 00056 ) 00057 { 00058 *num_values = 3; 00059 *num_indexes = 2; 00060 *num_chars = 0; 00061 return 0; 00062 } 00063 00064 static int targ_obj_reinit( 00065 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00066 , RTOp_ReductTarget targ_obj ) 00067 { 00068 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00069 *targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00070 targ->max_viol = 0.0; /* None violated yet! */ 00071 targ->v_i = 0.0; /* arbitrary */ 00072 targ->vLU_i = 0.0; /* arbitrary */ 00073 targ->max_viol_i = 0; /* None violated yet! */ 00074 targ->bnd_type = -2; /* Invalid type (just in case used by accident) */ 00075 return 0; 00076 } 00077 00078 static int targ_obj_create( 00079 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00080 ,RTOp_ReductTarget* targ_obj 00081 ) 00082 { 00083 const int mem_size = sizeof(struct RTOp_ROp_max_inequ_viol_reduct_obj_t); 00084 *targ_obj = malloc( mem_size ); 00085 return targ_obj_reinit(vtbl,obj_data,*targ_obj); 00086 } 00087 00088 static int targ_extract_state( 00089 const struct RTOp_obj_type_vtbl_t* vtbl 00090 ,const void * obj_data 00091 ,void * reduct_obj 00092 ,int num_values 00093 ,RTOp_value_type value_data[] 00094 ,int num_indexes 00095 ,RTOp_index_type index_data[] 00096 ,int num_chars 00097 ,RTOp_char_type char_data[] 00098 ) 00099 { 00100 struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL; 00101 assert( reduct_obj ); 00102 assert( num_values == 3 ); 00103 assert( num_indexes == 3 ); 00104 assert( num_chars == 0 ); 00105 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)reduct_obj; 00106 value_data[0] = targ->max_viol; 00107 value_data[1] = targ->v_i; 00108 value_data[2] = targ->vLU_i; 00109 index_data[0] = targ->max_viol_i; 00110 index_data[1] = targ->bnd_type; 00111 return 0; 00112 } 00113 00114 static int targ_load_state( 00115 const struct RTOp_obj_type_vtbl_t* vtbl 00116 ,const void* obj_data 00117 ,int num_values 00118 ,const RTOp_value_type value_data[] 00119 ,int num_indexes 00120 ,const RTOp_index_type index_data[] 00121 ,int num_chars 00122 ,const RTOp_char_type char_data[] 00123 ,void ** reduct_obj 00124 ) 00125 { 00126 struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL; 00127 assert( *reduct_obj ); 00128 assert( num_values == 3 ); 00129 assert( num_indexes == 2 ); 00130 assert( num_chars == 0 ); 00131 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)*reduct_obj; 00132 targ->max_viol = value_data[0]; 00133 targ->v_i = value_data[1]; 00134 targ->vLU_i = value_data[2]; 00135 targ->max_viol_i = index_data[0]; 00136 targ->bnd_type = index_data[1]; 00137 return 0; 00138 } 00139 00140 static const struct RTOp_obj_type_vtbl_t targ_obj_vtbl = 00141 { 00142 get_targ_type_num_entries 00143 ,targ_obj_create 00144 ,targ_obj_reinit 00145 ,RTOp_obj_free_free 00146 ,targ_extract_state 00147 ,targ_load_state 00148 }; 00149 00150 /* Other functions */ 00151 00152 static int RTOp_ROp_max_inequ_viol_apply_op( 00153 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00154 ,const int num_vecs, const struct RTOp_SubVector vecs[] 00155 ,const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00156 ,RTOp_ReductTarget targ_obj 00157 ) 00158 { 00159 /* */ 00160 /* Declare local variables */ 00161 /* */ 00162 00163 /* targ */ 00164 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00165 *targ = NULL; 00166 /* global_off */ 00167 size_t global_offset; 00168 /* sub_dim */ 00169 size_t sub_dim; 00170 /* v */ 00171 const RTOp_value_type *v_val = NULL; 00172 ptrdiff_t v_val_s; 00173 /* vL */ 00174 const RTOp_value_type *vL_val = NULL; 00175 ptrdiff_t vL_val_s; 00176 /* vU */ 00177 const RTOp_value_type *vU_val = NULL; 00178 ptrdiff_t vU_val_s; 00179 00180 register size_t k; 00181 RTOp_index_type i; 00182 RTOp_value_type v_scale; 00183 RTOp_value_type violL; 00184 RTOp_value_type violU; 00185 00186 /* */ 00187 /* Validate the input */ 00188 /* */ 00189 if( num_vecs != 3 ) 00190 return RTOp_ERR_INVALID_NUM_VECS; 00191 if( num_targ_vecs != 0 ) 00192 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00193 if( vecs[0].global_offset != vecs[1].global_offset 00194 || vecs[0].sub_dim != vecs[1].sub_dim 00195 || vecs[0].global_offset != vecs[2].global_offset 00196 || vecs[0].sub_dim != vecs[2].sub_dim ) 00197 return RTOp_ERR_INCOMPATIBLE_VECS; 00198 00199 /* */ 00200 /* Get pointers to the data */ 00201 /* */ 00202 00203 /* targ */ 00204 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00205 /* global_off */ 00206 global_offset = vecs[0].global_offset; 00207 /* sub_dim */ 00208 sub_dim = vecs[0].sub_dim; 00209 /* v */ 00210 v_val = vecs[0].values; 00211 v_val_s = vecs[0].values_stride; 00212 /* vL */ 00213 vL_val = vecs[1].values; 00214 vL_val_s = vecs[1].values_stride; 00215 /* vU */ 00216 vU_val = vecs[2].values; 00217 vU_val_s = vecs[2].values_stride; 00218 00219 /* */ 00220 /* Perform the reduction operation. */ 00221 /* */ 00222 00223 i = global_offset + 1; 00224 for( k = 0; k < sub_dim; ++k, ++i, v_val += v_val_s, vL_val += vL_val_s, vU_val += vU_val_s ) { 00225 v_scale = 1.0 / (1.0 + fabs(*v_val)); 00226 /* (vL - v)*v_scale */ 00227 violL = (*vL_val - *v_val) * v_scale; 00228 /* (v - vU)*v_scale */ 00229 violU = (*v_val - *vU_val) * v_scale; 00230 /* Perform the reduction */ 00231 if( 00232 ( max(violL,violU) > targ->max_viol ) 00233 || 00234 ( max(violL,violU) == targ->max_viol && i < targ->max_viol_i ) 00235 ) 00236 { 00237 targ->bnd_type = ( violL > 0.0 00238 ? ( *vL_val == *vU_val 00239 ? 0 /* EQUALITY */ 00240 : -1 /* LOWER */ 00241 ) 00242 : +1 /* UPPER */ 00243 ); 00244 targ->max_viol = ( targ->bnd_type <= 0 ? violL : violU ); 00245 targ->v_i = *v_val; 00246 targ->vLU_i = ( targ->bnd_type <= 0 ? *vL_val : *vU_val ); 00247 targ->max_viol_i = i; 00248 } 00249 } 00250 00251 return 0; /* success? */ 00252 } 00253 00254 static int reduce_reduct_objs( 00255 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */ 00256 , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj ) 00257 { 00258 const struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00259 *i_targ = (const struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)in_reduct_obj; 00260 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00261 *io_targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)inout_reduct_obj; 00262 00263 if( 00264 ( i_targ->max_viol > io_targ->max_viol ) 00265 || 00266 ( i_targ->max_viol == io_targ->max_viol && i_targ->max_viol_i < io_targ->max_viol_i ) 00267 ) 00268 { 00269 io_targ->max_viol = i_targ->max_viol; 00270 io_targ->v_i = i_targ->v_i; 00271 io_targ->vLU_i = i_targ->vLU_i; 00272 io_targ->max_viol_i = i_targ->max_viol_i; 00273 io_targ->bnd_type = i_targ->bnd_type; 00274 } 00275 return 0; 00276 } 00277 00278 INSERT_GET_REDUCT_OP_FUNCS( 00279 3,2,0,RTOp_ROp_max_inequ_viol_reduct_obj_t,reduce_reduct_objs 00280 ,targ_load_state,targ_extract_state 00281 ,external_reduct_op,get_reduct_op) 00282 00283 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_inequ_viol_vtbl = 00284 { 00285 &RTOp_obj_null_vtbl 00286 ,&targ_obj_vtbl 00287 ,"ROp_max_inequ_viol" 00288 ,NULL 00289 ,RTOp_ROp_max_inequ_viol_apply_op 00290 ,reduce_reduct_objs 00291 ,get_reduct_op 00292 }; 00293 00294 /* Class specific functions */ 00295 00296 int RTOp_ROp_max_inequ_viol_construct( struct RTOp_RTOp* op ) 00297 { 00298 op->vtbl = &RTOp_ROp_max_inequ_viol_vtbl; 00299 op->obj_data = NULL; 00300 return 0; /* success? */ 00301 } 00302 00303 int RTOp_ROp_max_inequ_viol_destroy( struct RTOp_RTOp* op ) 00304 { 00305 op->vtbl = NULL; 00306 op->obj_data = NULL; 00307 return 0; /* success? */ 00308 } 00309 00310 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00311 RTOp_ROp_max_inequ_viol_val(RTOp_ReductTarget targ_obj) 00312 { 00313 return *(struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00314 }
1.7.4