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 /* */
00037 /* Implementation functions */
00038 /* */
00039 
00040 /* Functions for the reduction target object */
00041 
00042 static int get_targ_type_num_entries(
00043   const struct RTOp_obj_type_vtbl_t* vtbl
00044   ,const void* obj_data
00045   ,int* num_values
00046   ,int* num_indexes
00047   ,int* num_chars
00048   )
00049 {
00050   *num_values  = 2;
00051   *num_indexes = 0;
00052   *num_chars   = 0;
00053   return 0;
00054 }
00055 
00056 static int targ_obj_create(
00057   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00058   , RTOp_ReductTarget* targ_obj )
00059 {
00060   const int mem_size = sizeof(struct RTOp_ROp_max_near_feas_step_reduct_obj_t);
00061   *targ_obj = malloc( mem_size );
00062   return vtbl->obj_reinit(vtbl,obj_data,*targ_obj);
00063 }
00064 
00065 static int targ_obj_reinit(
00066   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00067   , RTOp_ReductTarget targ_obj )
00068 {
00069   struct RTOp_ROp_max_near_feas_step_reduct_obj_t
00070     *targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj;
00071   targ->alpha_pos = +1e+50; /* big enough? */
00072   targ->alpha_neg = -1e+50; /* big enough? */
00073   return 0;
00074 }
00075 
00076 static int targ_extract_state(
00077   const struct RTOp_obj_type_vtbl_t* vtbl
00078   ,const void *       obj_data
00079   ,void *             reduct_obj
00080   ,int                num_values
00081   ,RTOp_value_type    value_data[]
00082   ,int                num_indexes
00083   ,RTOp_index_type    index_data[]
00084   ,int                num_chars
00085   ,RTOp_char_type     char_data[]
00086   )
00087 {
00088   struct RTOp_ROp_max_near_feas_step_reduct_obj_t *targ = NULL;
00089 #ifdef RTOp_DEBUG
00090   assert( reduct_obj );
00091   assert( num_values  == 2 );
00092   assert( num_indexes == 0 );
00093   assert( num_chars   == 0 );
00094   assert( value_data );
00095 #endif
00096   targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)reduct_obj;
00097   value_data[0] = targ->alpha_pos;
00098   value_data[1] = targ->alpha_neg;
00099   return 0;
00100 }
00101 
00102 static int targ_load_state(
00103   const struct RTOp_obj_type_vtbl_t* vtbl
00104   ,const void*             obj_data
00105   ,int                     num_values
00106   ,const RTOp_value_type   value_data[]
00107   ,int                     num_indexes
00108   ,const RTOp_index_type   index_data[]
00109   ,int                     num_chars
00110   ,const RTOp_char_type    char_data[]
00111   ,void **                 reduct_obj
00112   )
00113 {
00114   struct RTOp_ROp_max_near_feas_step_reduct_obj_t *targ = NULL;
00115 #ifdef RTOp_DEBUG
00116   assert( *reduct_obj );
00117   assert( num_values  == 2 );
00118   assert( num_indexes == 0 );
00119   assert( num_chars   == 0 );
00120   assert( value_data );
00121 #endif
00122   targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)*reduct_obj;
00123   targ->alpha_pos = value_data[0];
00124   targ->alpha_neg = value_data[1];
00125   return 0;
00126 }
00127 
00128 static const struct RTOp_obj_type_vtbl_t targ_obj_vtbl =
00129 {
00130   get_targ_type_num_entries
00131   ,targ_obj_create
00132   ,targ_obj_reinit
00133   ,RTOp_obj_free_free
00134   ,targ_extract_state
00135   ,targ_load_state
00136 };
00137 
00138 /* Other functions */
00139 
00140 static int RTOp_ROp_max_near_feas_step_apply_op(
00141   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00142   , const int num_vecs, const struct RTOp_SubVector vecs[]
00143   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00144   , RTOp_ReductTarget targ_obj )
00145 {
00146   RTOp_value_type        beta;
00147   struct RTOp_ROp_max_near_feas_step_reduct_obj_t
00148     *targ = NULL;
00149   RTOp_index_type        sub_dim;
00150   const RTOp_value_type  *xl_val;
00151   ptrdiff_t              xl_val_s;
00152   const RTOp_value_type  *x_val;
00153   ptrdiff_t              x_val_s;
00154   const RTOp_value_type  *d_val;
00155   ptrdiff_t              d_val_s;
00156   const RTOp_value_type  *xu_val;
00157   ptrdiff_t              xu_val_s;
00158   register RTOp_index_type  k;
00159   RTOp_value_type  alpha;
00160 
00161   /* */
00162   /* Validate the input */
00163   /* */
00164   if( num_vecs != 4 )
00165     return RTOp_ERR_INVALID_NUM_VECS;
00166   assert(vecs);
00167   if( num_targ_vecs != 0 )
00168     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00169   if( vecs[0].global_offset != vecs[1].global_offset
00170     || vecs[0].sub_dim != vecs[1].sub_dim
00171     || vecs[0].global_offset != vecs[2].global_offset
00172     || vecs[0].sub_dim != vecs[2].sub_dim
00173     || vecs[0].global_offset != vecs[3].global_offset
00174     || vecs[0].sub_dim != vecs[3].sub_dim
00175     )
00176     return RTOp_ERR_INCOMPATIBLE_VECS;
00177 
00178   /* */
00179   /* Get pointers to data */
00180   /* */
00181 
00182   /* beta */
00183   beta = *(RTOp_value_type*)obj_data;
00184   /* targ */
00185   targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj;
00186   /* sub_dim */
00187   sub_dim        = vecs[0].sub_dim;
00188   /* xl */
00189   xl_val         = vecs[0].values;
00190   xl_val_s       = vecs[0].values_stride;
00191   /* x */
00192   x_val          = vecs[1].values;
00193   x_val_s        = vecs[1].values_stride;
00194   /* d */
00195   d_val          = vecs[2].values;
00196   d_val_s        = vecs[2].values_stride;
00197   /* xu */
00198   xu_val         = vecs[3].values;
00199   xu_val_s       = vecs[3].values_stride;
00200 
00201   /* */
00202   /* If x has already been found to be infeasible just return */
00203   /* */
00204   if(targ->alpha_pos < 0.0)
00205     return 0; /* success! */
00206 
00207   /* */
00208   /* Perform the reduction operation. */
00209   /* */
00210   /* max alpha_pos, min alpha_neg s.t. xl - beta <= x + alpha*d <= xu + beta */
00211   /* */
00212   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 ) {
00213     if( *x_val < *xl_val - beta || *x_val > *xu_val + beta ) {
00214       targ->alpha_pos = -1.0; /* x is infeasible as is */
00215       return 0; /* success! */
00216     }
00217     if( *d_val != 0.0 ) {
00218       /* check lower bound */
00219       alpha = (*xl_val - beta - *x_val) / *d_val;
00220       if( ( alpha > 0.0 && alpha < targ->alpha_pos )
00221         || ( alpha == 0.0 && *d_val < 0.0 ) )
00222         targ->alpha_pos = alpha;
00223       if( ( alpha < 0.0 && -alpha < -targ->alpha_neg )
00224         || ( alpha == 0.0 && *d_val > 0.0 ) )
00225         targ->alpha_neg = alpha;
00226       /* check upper bound */
00227       alpha = (*xu_val + beta - *x_val) / *d_val;
00228       if( (alpha > 0.0 && alpha < targ->alpha_pos )
00229         || ( alpha == 0.0 && *d_val > 0.0 ) )
00230         targ->alpha_pos = alpha;
00231       if( ( alpha < 0.0 && -alpha < -targ->alpha_neg )
00232         || ( alpha == 0.0 && *d_val < 0.0 ) )
00233         targ->alpha_neg = alpha;
00234     }
00235   }
00236 
00237   return 0; /* success? */
00238 }
00239 
00240 static int reduce_reduct_objs(
00241   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */
00242   , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj )
00243 {
00244   const struct RTOp_ROp_max_near_feas_step_reduct_obj_t
00245     *i_targ = (const struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)in_reduct_obj;
00246   struct RTOp_ROp_max_near_feas_step_reduct_obj_t
00247     *io_targ = (struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)inout_reduct_obj;
00248   if(  i_targ->alpha_pos <  io_targ->alpha_pos )
00249     io_targ->alpha_pos = i_targ->alpha_pos;
00250   if( -i_targ->alpha_neg < -io_targ->alpha_neg )
00251     io_targ->alpha_neg = i_targ->alpha_neg;
00252   return 0;
00253 }
00254 
00255 INSERT_GET_REDUCT_OP_FUNCS(
00256   2,0,0,RTOp_ROp_max_near_feas_step_reduct_obj_t,reduce_reduct_objs
00257   ,targ_load_state,targ_extract_state
00258   ,external_reduct_op,get_reduct_op)
00259 
00260 /* Virtual function table */
00261 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_near_feas_step_vtbl =
00262 {
00263   &RTOp_obj_value_vtbl /* use simple scalar value type for object instance data */
00264   ,&targ_obj_vtbl
00265   ,"ROp_max_near_feas_step"
00266   ,NULL
00267   ,RTOp_ROp_max_near_feas_step_apply_op
00268   ,reduce_reduct_objs
00269   ,get_reduct_op
00270 };
00271 
00272 /* Class specific functions */
00273 
00274 int RTOp_ROp_max_near_feas_step_construct( RTOp_value_type beta, struct RTOp_RTOp* op )
00275 {
00276   op->vtbl = &RTOp_ROp_max_near_feas_step_vtbl;
00277   op->vtbl->obj_data_vtbl->obj_create(NULL,NULL,&op->obj_data);
00278   *((RTOp_value_type*)op->obj_data) = beta;
00279   return 0; /* success? */
00280 }
00281 
00282 int RTOp_ROp_max_near_feas_step_destroy( struct RTOp_RTOp* op )
00283 {
00284   op->vtbl->obj_data_vtbl->obj_free(NULL,NULL,&op->obj_data);
00285   op->vtbl      = NULL;
00286   return 0; /* success? */
00287 }
00288 
00289 int RTOp_ROp_max_near_feas_step_set_beta( RTOp_value_type beta, struct RTOp_RTOp* op )
00290 {
00291   *((RTOp_value_type*)op->obj_data) = beta;
00292   return 0; /* success? */
00293 }
00294 
00295 struct RTOp_ROp_max_near_feas_step_reduct_obj_t
00296 RTOp_ROp_max_near_feas_step_val(RTOp_ReductTarget targ_obj)
00297 {
00298   return *(struct RTOp_ROp_max_near_feas_step_reduct_obj_t*)targ_obj;
00299 }

Generated on Thu Sep 18 12:33:38 2008 for RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators by doxygen 1.3.9.1