RTOp_TOp_force_in_bounds.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 // 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_TOp_force_in_bounds.h"
00032 #include "RTOp_obj_null_vtbl.h"
00033 #include "RTOp_obj_value_value_vtbl.h"  /* vtbl for operator object instance data */
00034 
00035 #define max(a,b) ( (a) > (b) ? (a) : (b) )
00036 #define min(a,b) ( (a) < (b) ? (a) : (b) )
00037 
00038 /* Implementation functions for RTOp_RTOp TOp_force_in_bounds */
00039 
00040 static int RTOp_TOp_force_in_bounds_apply_op(
00041   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00042   , const int num_vecs, const struct RTOp_SubVector vecs[]
00043   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00044   , RTOp_ReductTarget targ_obj )
00045 {
00046   RTOp_index_type        sub_dim;
00047   RTOp_value_type        *x_val;
00048   ptrdiff_t              x_val_s;
00049   const RTOp_value_type  *xl_val;
00050   ptrdiff_t              xl_val_s;
00051   const RTOp_value_type  *xu_val;
00052   ptrdiff_t              xu_val_s;
00053   register RTOp_index_type k;
00054 
00055   /* */
00056   /* Validate the input */
00057   /* */
00058   if( num_vecs != 2 || vecs == NULL )
00059     return RTOp_ERR_INVALID_NUM_VECS;
00060   if( num_targ_vecs != 1 || targ_vecs == NULL )
00061     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00062   if( targ_vecs[0].sub_dim != vecs[0].sub_dim
00063     || targ_vecs[0].sub_dim != vecs[1].sub_dim )
00064     return RTOp_ERR_INCOMPATIBLE_VECS;
00065 
00066   /* */
00067   /* Get pointers to data */
00068   /* */
00069 
00070   /* x */
00071   sub_dim       = targ_vecs[0].sub_dim;
00072   x_val         = targ_vecs[0].values;
00073   x_val_s       = targ_vecs[0].values_stride;
00074   /* xl */
00075   xl_val         = vecs[0].values;
00076   xl_val_s       = vecs[0].values_stride;
00077   /* xu */
00078   xu_val         = vecs[1].values;
00079   xu_val_s       = vecs[1].values_stride;
00080 
00081   /* */
00082   /* Force in bounds */
00083   /* */
00084 
00085   if( x_val_s == 1 && xl_val_s == 1 && xu_val_s == 1 ) {
00086     /* Slightly faster loop for unit stride vectors */
00087     for( k = 0; k < sub_dim; ++k, ++x_val, ++xl_val, ++xu_val ) {
00088       if( *x_val < *xl_val )
00089         *x_val = *xl_val;
00090       else if( *x_val > *xu_val )
00091         *x_val = *xu_val;
00092     }
00093   }
00094   else {
00095     /* More general implementation for non-unit strides */
00096     for( k = 0; k < sub_dim; ++k, x_val+=x_val_s, xl_val+=xl_val_s, xu_val+=xu_val_s ) {
00097       if( *x_val < *xl_val )
00098         *x_val = *xl_val;
00099       else if( *x_val > *xu_val )
00100         *x_val = *xu_val;
00101     }
00102   }
00103 
00104   return 0; /* success? */
00105 }
00106 
00107 /* Virtual function table */
00108 const struct RTOp_RTOp_vtbl_t RTOp_TOp_force_in_bounds_vtbl =
00109 {
00110   &RTOp_obj_null_vtbl  /* Use a null object for instance data */
00111   ,&RTOp_obj_null_vtbl /* use null type for target object */
00112   ,"TOp_force_in_bounds"
00113   ,NULL /* use default from reduct_vtbl */
00114   ,RTOp_TOp_force_in_bounds_apply_op
00115   ,NULL
00116   ,NULL
00117 };
00118 
00119 /* Class specific functions */
00120 
00121 int RTOp_TOp_force_in_bounds_construct( struct RTOp_RTOp* op )
00122 {
00123   op->obj_data  = NULL;
00124   op->vtbl      = &RTOp_TOp_force_in_bounds_vtbl;
00125   return 0; /* success? */
00126 }
00127 
00128 int RTOp_TOp_force_in_bounds_destroy( struct RTOp_RTOp* op )
00129 {
00130   op->obj_data  = NULL;
00131   op->vtbl      = NULL;
00132   return 0; /* success? */
00133 }
00134 
00135 /* Implementation functions for RTOp_RTOp for TOp_force_in_bounds_buffer */
00136 
00137 static int RTOp_TOp_force_in_bounds_buffer_apply_op(
00138   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00139   , const int num_vecs, const struct RTOp_SubVector vecs[]
00140   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00141   , RTOp_ReductTarget reduct_obj )
00142 {
00143   /* */
00144   /* Declare local variables */
00145   /* */
00146 
00147   /* Access to the operator object instance data */
00148   struct RTOp_value_value_type *data_cntr = (struct RTOp_value_value_type*)obj_data;
00149   RTOp_value_type *rel_push = &data_cntr->value1;
00150   RTOp_value_type *abs_push = &data_cntr->value2;
00151   /* Vector data */
00152   RTOp_index_type           sub_dim;
00153   /* z0 */
00154   RTOp_value_type           *z0_val;
00155   ptrdiff_t                 z0_val_s;
00156   /* v0 */
00157   const RTOp_value_type     *v0_val;
00158   ptrdiff_t                 v0_val_s;
00159   /* v1 */
00160   const RTOp_value_type     *v1_val;
00161   ptrdiff_t                 v1_val_s;
00162 
00163   /* Automatic temporary variables */
00164   register RTOp_index_type  k;
00165   /* User defined temporary variables */
00166   RTOp_value_type xl_sb;
00167   RTOp_value_type xu_sb;
00168 
00169   /* */
00170   /* Validate the input */
00171   /* */
00172   if( num_vecs != 2 || ( num_vecs && vecs == NULL ) )
00173     return RTOp_ERR_INVALID_NUM_VECS;
00174   if( num_targ_vecs != 1 || ( num_targ_vecs && targ_vecs == NULL ) )
00175     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00176   if( /* Validate sub_dim */
00177     vecs[1].sub_dim != vecs[0].sub_dim
00178     || targ_vecs[0].sub_dim != vecs[0].sub_dim
00179     )
00180     return RTOp_ERR_INCOMPATIBLE_VECS;
00181   assert(obj_data);
00182 
00183 
00184   /* */
00185   /* Get pointers to data */
00186   /* */
00187   sub_dim       = vecs[0].sub_dim;
00188   /* z0 */
00189   z0_val        = targ_vecs[0].values;
00190   z0_val_s      = targ_vecs[0].values_stride;
00191   /* v0 */
00192   v0_val        = vecs[0].values;
00193   v0_val_s      = vecs[0].values_stride;
00194   /* v1 */
00195   v1_val        = vecs[1].values;
00196   v1_val_s      = vecs[1].values_stride;
00197 
00198 
00199   /* */
00200   /* Apply the operator: */
00201   /* */
00202   for( k = 0; k < sub_dim; ++k, v0_val += v0_val_s, v1_val += v1_val_s, z0_val += z0_val_s )
00203   {
00204     /* Element-wise transformation */
00205     xl_sb = min((*v0_val) + (*rel_push)*((*v1_val)-(*v0_val)), (*v0_val) + (*abs_push));
00206     xu_sb = max((*v1_val) - (*rel_push)*((*v1_val)-(*v0_val)), (*v1_val) - (*abs_push));
00207     if (xl_sb >= xu_sb)
00208         {
00209         (*z0_val) = (*v0_val) + ((*v1_val)-(*v0_val))/2.0;
00210         }
00211     else if ((*z0_val) < xl_sb)
00212         { (*z0_val) = xl_sb; }
00213     else if ((*z0_val) > xu_sb)
00214         { (*z0_val) = xu_sb; }
00215     /* Otherwise, leave it */
00216   }
00217 
00218   return 0; /* success? */
00219 }
00220 
00221 /* Virtual function table */
00222 const struct RTOp_RTOp_vtbl_t RTOp_TOp_force_in_bounds_buffer_vtbl =
00223 {
00224   &RTOp_obj_value_value_vtbl
00225   ,&RTOp_obj_null_vtbl
00226   ,"TOp_force_in_bounds_buffer"
00227   ,NULL
00228   ,RTOp_TOp_force_in_bounds_buffer_apply_op
00229   ,NULL
00230   ,NULL
00231 };
00232 
00233 /* Class specific functions */
00234 
00235 int RTOp_TOp_force_in_bounds_buffer_construct( RTOp_value_type rel_push, RTOp_value_type abs_push,  struct RTOp_RTOp* op )
00236 {
00237 #ifdef RTOp_DEBUG
00238   assert(op);
00239 #endif
00240   op->obj_data  = NULL;
00241   op->vtbl      = &RTOp_TOp_force_in_bounds_buffer_vtbl;
00242   op->vtbl->obj_data_vtbl->obj_create(NULL,NULL,&op->obj_data);
00243   return RTOp_TOp_force_in_bounds_buffer_init(rel_push,abs_push,op);
00244 }
00245 
00246 int RTOp_TOp_force_in_bounds_buffer_destroy( struct RTOp_RTOp* op )
00247 {
00248   op->vtbl->obj_data_vtbl->obj_free(NULL,NULL,&op->obj_data);
00249   op->obj_data  = NULL;
00250   op->vtbl      = NULL;
00251   return 0;
00252 }
00253 
00254 int RTOp_TOp_force_in_bounds_buffer_init( RTOp_value_type rel_push, RTOp_value_type abs_push, struct RTOp_RTOp* op )
00255 {
00256   struct RTOp_value_value_type *ptr_data_cntr = (struct RTOp_value_value_type*)op->obj_data;
00257   RTOp_value_type *ptr_rel_push = &ptr_data_cntr->value1;
00258   RTOp_value_type *ptr_abs_push = &ptr_data_cntr->value2;
00259   *ptr_rel_push = rel_push;
00260   *ptr_abs_push = abs_push;
00261   return 0;
00262 }
00263 

Generated on Tue Jul 13 09:30:54 2010 for MOOCHO (Single Doxygen Collection) by  doxygen 1.4.7