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