RTOp_ROp_max_near_feas_step.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 #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 }

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