RTOp_ROp_max_inequ_viol.c

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

Generated on Tue Jul 13 09:28:39 2010 for RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators by  doxygen 1.4.7