MOOCHO (Single Doxygen Collection) Version of the Day
RTOp_ROp_max_inequ_viol.c
Go to the documentation of this file.
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 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00039 // 
00040 // ***********************************************************************
00041 // @HEADER
00042 */
00043 
00044 #include <math.h>
00045 
00046 #define max(a,b) ( (a) > (b) ? (a) : (b) )
00047 #define min(a,b) ( (a) < (b) ? (a) : (b) )
00048 
00049 #include "RTOp_ROp_max_inequ_viol.h"
00050 #include "RTOp_obj_null_vtbl.h"
00051 #include "RTOp_obj_value_vtbl.h"
00052 #include "RTOp_obj_free_free.h"
00053 #include "RTOp_get_reduct_op.hpp"
00054 
00055 #include <stdlib.h>
00056 
00057 /* */
00058 /* Implementation functions */
00059 /* */
00060 
00061 /* Functions for the reduction target object */
00062 
00063 static int get_targ_type_num_entries(
00064   const struct RTOp_obj_type_vtbl_t* vtbl
00065   ,const void* obj_data
00066   ,int* num_values
00067   ,int* num_indexes
00068   ,int* num_chars
00069   )
00070 {
00071   *num_values  = 3;
00072   *num_indexes = 2;
00073   *num_chars   = 0;
00074   return 0;
00075 }
00076 
00077 static int targ_obj_reinit(
00078   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00079   , RTOp_ReductTarget targ_obj )
00080 {
00081   struct RTOp_ROp_max_inequ_viol_reduct_obj_t
00082     *targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj;
00083   targ->max_viol   = 0.0; /* None violated yet! */
00084   targ->v_i        = 0.0; /* arbitrary */
00085   targ->vLU_i      = 0.0; /* arbitrary */
00086   targ->max_viol_i = 0;   /* None violated yet! */
00087   targ->bnd_type   = -2;  /* Invalid type (just in case used by accident) */
00088   return 0;
00089 }
00090 
00091 static int targ_obj_create(
00092   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00093   ,RTOp_ReductTarget* targ_obj
00094   )
00095 {
00096   const int mem_size = sizeof(struct RTOp_ROp_max_inequ_viol_reduct_obj_t);
00097   *targ_obj = malloc( mem_size );
00098   return targ_obj_reinit(vtbl,obj_data,*targ_obj);
00099 }
00100 
00101 static int targ_extract_state(
00102   const struct RTOp_obj_type_vtbl_t* vtbl
00103   ,const void *       obj_data
00104   ,void *             reduct_obj
00105   ,int                num_values
00106   ,RTOp_value_type    value_data[]
00107   ,int                num_indexes
00108   ,RTOp_index_type    index_data[]
00109   ,int                num_chars
00110   ,RTOp_char_type     char_data[]
00111   )
00112 {
00113   struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL;
00114   assert( reduct_obj );
00115   assert( num_values  == 3 );
00116   assert( num_indexes == 3 );
00117   assert( num_chars   == 0 );
00118   targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)reduct_obj;
00119   value_data[0] = targ->max_viol;
00120   value_data[1] = targ->v_i;
00121   value_data[2] = targ->vLU_i;
00122   index_data[0] = targ->max_viol_i;
00123   index_data[1] = targ->bnd_type;
00124   return 0;
00125 }
00126 
00127 static int targ_load_state(
00128   const struct RTOp_obj_type_vtbl_t* vtbl
00129   ,const void*             obj_data
00130   ,int                     num_values
00131   ,const RTOp_value_type   value_data[]
00132   ,int                     num_indexes
00133   ,const RTOp_index_type   index_data[]
00134   ,int                     num_chars
00135   ,const RTOp_char_type    char_data[]
00136   ,void **                 reduct_obj
00137   )
00138 {
00139   struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL;
00140   assert( *reduct_obj );
00141   assert( num_values  == 3 );
00142   assert( num_indexes == 2 );
00143   assert( num_chars   == 0 );
00144   targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)*reduct_obj;
00145   targ->max_viol   = value_data[0];
00146   targ->v_i        = value_data[1];
00147   targ->vLU_i      = value_data[2];
00148   targ->max_viol_i = index_data[0];
00149   targ->bnd_type   = index_data[1];
00150   return 0;
00151 }
00152 
00153 static const struct RTOp_obj_type_vtbl_t targ_obj_vtbl =
00154 {
00155   get_targ_type_num_entries
00156   ,targ_obj_create
00157   ,targ_obj_reinit
00158   ,RTOp_obj_free_free
00159   ,targ_extract_state
00160   ,targ_load_state
00161 };
00162 
00163 /* Other functions */
00164 
00165 static int RTOp_ROp_max_inequ_viol_apply_op(
00166   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00167   ,const int num_vecs, const struct RTOp_SubVector vecs[]
00168   ,const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00169   ,RTOp_ReductTarget targ_obj
00170   )
00171 {
00172   /* */
00173   /* Declare local variables */
00174   /* */
00175 
00176   /* targ */
00177   struct RTOp_ROp_max_inequ_viol_reduct_obj_t
00178     *targ = NULL;
00179   /* global_off */
00180   size_t                 global_offset;
00181   /* sub_dim */
00182   size_t                 sub_dim;
00183   /* v */
00184   const RTOp_value_type  *v_val = NULL;
00185   ptrdiff_t              v_val_s;
00186   /* vL */
00187   const RTOp_value_type  *vL_val = NULL;
00188   ptrdiff_t              vL_val_s;
00189   /* vU */
00190   const RTOp_value_type  *vU_val = NULL;
00191   ptrdiff_t              vU_val_s;
00192 
00193   register size_t  k;
00194   RTOp_index_type  i;
00195   RTOp_value_type  v_scale;
00196   RTOp_value_type  violL;
00197   RTOp_value_type  violU;
00198 
00199   /* */
00200   /* Validate the input */
00201   /* */
00202   if( num_vecs != 3 )
00203     return RTOp_ERR_INVALID_NUM_VECS;
00204   if( num_targ_vecs != 0 )
00205     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00206   if(    vecs[0].global_offset != vecs[1].global_offset
00207     || vecs[0].sub_dim       != vecs[1].sub_dim
00208     || vecs[0].global_offset != vecs[2].global_offset
00209     || vecs[0].sub_dim       != vecs[2].sub_dim )
00210     return RTOp_ERR_INCOMPATIBLE_VECS;
00211 
00212   /* */
00213   /* Get pointers to the data */
00214   /* */
00215 
00216   /* targ */
00217   targ            = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj;
00218   /* global_off */
00219   global_offset   = vecs[0].global_offset;
00220   /* sub_dim */
00221   sub_dim         = vecs[0].sub_dim;
00222   /* v */
00223   v_val           = vecs[0].values;
00224   v_val_s         = vecs[0].values_stride;
00225   /* vL */
00226   vL_val          = vecs[1].values;
00227   vL_val_s        = vecs[1].values_stride;
00228   /* vU */
00229   vU_val          = vecs[2].values;
00230   vU_val_s        = vecs[2].values_stride;
00231 
00232   /* */
00233   /* Perform the reduction operation. */
00234   /* */
00235 
00236   i = global_offset + 1;
00237   for( k = 0; k < sub_dim; ++k, ++i, v_val += v_val_s, vL_val += vL_val_s, vU_val += vU_val_s ) {
00238     v_scale = 1.0 / (1.0 + fabs(*v_val));
00239     /* (vL - v)*v_scale */
00240     violL = (*vL_val - *v_val) * v_scale;
00241     /* (v - vU)*v_scale */
00242     violU = (*v_val - *vU_val) * v_scale;
00243     /* Perform the reduction */
00244     if(
00245       ( max(violL,violU) > targ->max_viol )
00246       ||
00247       ( max(violL,violU) == targ->max_viol && i < targ->max_viol_i )
00248       )
00249      {
00250       targ->bnd_type = ( violL > 0.0
00251                 ? ( *vL_val == *vU_val
00252                   ? 0  /* EQUALITY */
00253                   : -1 /* LOWER */
00254                   )
00255                 : +1 /* UPPER */
00256                 );
00257       targ->max_viol   = ( targ->bnd_type <= 0 ? violL : violU );
00258       targ->v_i        = *v_val;
00259       targ->vLU_i      = ( targ->bnd_type <= 0 ? *vL_val : *vU_val );
00260       targ->max_viol_i = i;
00261     }
00262   }
00263 
00264   return 0; /* success? */
00265 }
00266 
00267 static int reduce_reduct_objs(
00268   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */
00269   , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj )
00270 {
00271   const struct RTOp_ROp_max_inequ_viol_reduct_obj_t
00272     *i_targ = (const struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)in_reduct_obj;
00273   struct RTOp_ROp_max_inequ_viol_reduct_obj_t
00274     *io_targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)inout_reduct_obj;
00275 
00276   if(
00277     ( i_targ->max_viol > io_targ->max_viol )
00278     ||
00279     ( i_targ->max_viol == io_targ->max_viol && i_targ->max_viol_i < io_targ->max_viol_i )
00280     )
00281   {
00282     io_targ->max_viol     = i_targ->max_viol;
00283     io_targ->v_i          = i_targ->v_i;
00284     io_targ->vLU_i        = i_targ->vLU_i;
00285     io_targ->max_viol_i   = i_targ->max_viol_i;
00286     io_targ->bnd_type     = i_targ->bnd_type;
00287   }
00288   return 0;
00289 }
00290 
00291 INSERT_GET_REDUCT_OP_FUNCS(
00292   3,2,0,RTOp_ROp_max_inequ_viol_reduct_obj_t,reduce_reduct_objs
00293   ,targ_load_state,targ_extract_state
00294   ,external_reduct_op,get_reduct_op)
00295 
00296 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_inequ_viol_vtbl =
00297 {
00298   &RTOp_obj_null_vtbl
00299   ,&targ_obj_vtbl
00300   ,"ROp_max_inequ_viol"
00301   ,NULL
00302   ,RTOp_ROp_max_inequ_viol_apply_op
00303   ,reduce_reduct_objs
00304   ,get_reduct_op
00305 };
00306 
00307 /* Class specific functions */
00308 
00309 int RTOp_ROp_max_inequ_viol_construct( struct RTOp_RTOp* op )
00310 {
00311   op->vtbl     = &RTOp_ROp_max_inequ_viol_vtbl;
00312   op->obj_data = NULL;
00313   return 0; /* success? */
00314 }
00315 
00316 int RTOp_ROp_max_inequ_viol_destroy( struct RTOp_RTOp* op )
00317 {
00318   op->vtbl     = NULL;
00319   op->obj_data = NULL;
00320   return 0; /* success? */
00321 }
00322 
00323 struct RTOp_ROp_max_inequ_viol_reduct_obj_t
00324 RTOp_ROp_max_inequ_viol_val(RTOp_ReductTarget targ_obj)
00325 {
00326   return *(struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj;
00327 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines