MOOCHO (Single Doxygen Collection) Version of the Day
ExampleNLPDirectRTOps.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 "Teuchos_ConfigDefs.hpp"
00045 #include "ExampleNLPDirectRTOps.h"
00046 #include "RTOp_obj_null_vtbl.h"
00047 #include "RTOp_obj_index_vtbl.h"
00048 
00049 /* Implementation for RTOp_TOp_explnlp2_c_eval */
00050 
00051 static int explnlp2_c_eval_apply_op(
00052   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00053   , const int num_vecs, const struct RTOp_SubVector vecs[]
00054   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00055   , RTOp_ReductTarget targ_obj )
00056 {
00057   /* c */
00058   size_t                 sub_dim;
00059   RTOp_value_type        *c_val;
00060   ptrdiff_t              c_val_s;
00061   /* xD */
00062   const RTOp_value_type  *xD_val;
00063   ptrdiff_t              xD_val_s;
00064   /* xI */
00065   const RTOp_value_type  *xI_val;
00066   ptrdiff_t              xI_val_s;
00067 
00068   register RTOp_index_type  k;
00069 
00070   /*
00071    *Validate the input
00072    */
00073   if( num_vecs != 2 || vecs == NULL )
00074     return RTOp_ERR_INVALID_NUM_VECS;
00075   if( num_targ_vecs != 1 || targ_vecs == NULL )
00076     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00077   if( targ_vecs[0].sub_dim != vecs[0].sub_dim
00078     || targ_vecs[0].sub_dim != vecs[1].sub_dim
00079     || targ_vecs[0].global_offset != vecs[0].global_offset
00080     || targ_vecs[0].global_offset != vecs[1].global_offset )
00081     return RTOp_ERR_INCOMPATIBLE_VECS;
00082 
00083   /*
00084    * Get pointers to data
00085    */
00086 
00087   /* c */
00088   sub_dim       = targ_vecs[0].sub_dim;
00089   c_val         = targ_vecs[0].values;
00090   c_val_s       = targ_vecs[0].values_stride;
00091   /* xD */
00092   xD_val         = vecs[0].values;
00093   xD_val_s       = vecs[0].values_stride;
00094   /* xI */
00095   xI_val         = vecs[1].values;
00096   xI_val_s       = vecs[1].values_stride;
00097 
00098   /*
00099    * Compute c(j) = xI(i) * ( xD(i) - 1 ) - 10 * xD(i)
00100    */
00101 
00102   if( c_val_s == 1 && xD_val_s == 1 && xI_val_s == 1 ) {
00103     /* Slightly faster loop for unit stride vectors */
00104     for( k = 0; k < sub_dim; ++k, ++xI_val )
00105       *c_val++ = (*xD_val++) * (*xI_val - 1.0) - 10.0 * (*xI_val);
00106   }
00107   else {
00108     /* More general implementation for non-unit strides */
00109     for( k = 0; k < sub_dim; ++k, c_val+=c_val_s, xD_val+=xD_val_s, xI_val+=xI_val_s )
00110       *c_val = (*xD_val) * (*xI_val - 1.0) - 10.0 * (*xI_val);
00111   }
00112 
00113   return 0; /* success? */
00114 }
00115 
00116 const struct RTOp_RTOp_vtbl_t RTOp_TOp_explnlp2_c_eval_vtbl =
00117 {
00118   &RTOp_obj_null_vtbl
00119   ,&RTOp_obj_null_vtbl
00120   ,"TOp_explnlp2_c_eval"
00121   ,NULL
00122   ,explnlp2_c_eval_apply_op
00123   ,NULL
00124   ,NULL
00125 };
00126 
00127 int RTOp_TOp_explnlp2_c_eval_construct( struct RTOp_RTOp* op )
00128 {
00129   op->obj_data  = NULL;
00130   op->vtbl      = &RTOp_TOp_explnlp2_c_eval_vtbl;
00131   return 0;
00132 }
00133 
00134 int RTOp_TOp_explnlp2_c_eval_destroy( struct RTOp_RTOp* op )
00135 {
00136   op->obj_data  = NULL;
00137   op->vtbl      = NULL;
00138   return 0;
00139 }
00140 
00141 /* Implementation for RTOp_TOp_explnlp2_calc_py_D */
00142 
00143 static int explnlp2_calc_py_D_apply_op(
00144   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00145   , const int num_vecs, const struct RTOp_SubVector vecs[]
00146   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00147   , RTOp_ReductTarget targ_obj )
00148 {
00149   size_t                 sub_dim;
00150   /* xD */
00151   const RTOp_value_type  *xD_val;
00152   ptrdiff_t              xD_val_s;
00153   /* xI */
00154   const RTOp_value_type  *xI_val;
00155   ptrdiff_t              xI_val_s;
00156   /* c */
00157   const RTOp_value_type  *c_val;
00158   ptrdiff_t              c_val_s;
00159   /* d */
00160   RTOp_value_type        *d_val;
00161   ptrdiff_t              d_val_s;
00162   /* py */
00163   RTOp_value_type        *py_val;
00164   ptrdiff_t              py_val_s;
00165 
00166   register RTOp_index_type  k;
00167   int                       all_unit_stride = 0;
00168   RTOp_value_type           denom;
00169 
00170   /* task */
00171   int task;
00172   assert(obj_data);
00173   task = *(int*)obj_data;
00174   assert(0 <= task && task <= 2);
00175 
00176   /*
00177    * Validate the input
00178    */
00179   if( ( (task == 0 || task == 1) && num_vecs != 2 )
00180     || ( (task == 2) && num_vecs != 3 )
00181     || vecs == NULL )
00182     return RTOp_ERR_INVALID_NUM_VECS;
00183   if( ( (task == 0 || task == 1) && num_targ_vecs != 1 )
00184     || ( (task == 2) && num_targ_vecs != 2 )
00185     || targ_vecs == NULL )
00186     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00187   if( targ_vecs[0].sub_dim != vecs[0].sub_dim
00188     || targ_vecs[0].sub_dim != vecs[1].sub_dim
00189     || ( task == 2 && ( targ_vecs[0].sub_dim != vecs[2].sub_dim ) )
00190     || ( task == 2 && ( targ_vecs[0].sub_dim != targ_vecs[1].sub_dim ) )
00191     || targ_vecs[0].global_offset != vecs[0].global_offset
00192     || targ_vecs[0].global_offset != vecs[1].global_offset
00193     || ( task == 2 && (targ_vecs[0].global_offset != vecs[2].global_offset ) )
00194     || ( task == 2 && ( targ_vecs[0].global_offset != targ_vecs[1].global_offset ) ) )
00195     return RTOp_ERR_INCOMPATIBLE_VECS;
00196 
00197   /*
00198    * Get pointers to data
00199    */
00200 
00201   sub_dim = vecs[0].sub_dim;
00202 
00203   k = 0;
00204   /* xD */
00205   xD_val         = vecs[k].values;
00206   xD_val_s       = vecs[k].values_stride;
00207   ++k;
00208   if( task == 1 || task == 2 ) {
00209     /* xI */
00210     xI_val         = vecs[k].values;
00211     xI_val_s       = vecs[k].values_stride;
00212     ++k;
00213   }
00214   if( task == 0 || task == 2 ) {
00215     /* c */
00216     c_val         = vecs[k].values;
00217     c_val_s       = vecs[k].values_stride;
00218     ++k;
00219   }
00220   k = 0;
00221   if( task == 1 || task == 2 ) {
00222     /* d */
00223     d_val         = targ_vecs[k].values;
00224     d_val_s       = targ_vecs[k].values_stride;
00225     ++k;
00226   }
00227   if( task == 0 || task == 2 ) {
00228     /* py */
00229     py_val         = targ_vecs[k].values;
00230     py_val_s       = targ_vecs[k].values_stride;
00231     ++k;
00232   }
00233 
00234   /* Determine if all the vectors have unit stride! */
00235   all_unit_stride = 1;
00236   for( k = 0; k < num_vecs && !all_unit_stride; ++k )
00237     if( vecs[k].values_stride != 1 )
00238       all_unit_stride = 0;
00239   for( k = 0; k < num_targ_vecs && !all_unit_stride; ++k )
00240     if( targ_vecs[k].values_stride != 1 )
00241       all_unit_stride = 0;
00242 
00243   /*
00244    * Compute py and/or D
00245    */
00246 
00247   if( all_unit_stride) {
00248     if(task == 0) {
00249       /* Compute py only */
00250       for( k = 0; k < sub_dim; ++k )
00251         *py_val++ = *c_val++ / ( 1.0 - *xI_val++ );
00252     }
00253     if(task == 1) {
00254       /* Compute D only */
00255       for( k = 0; k < sub_dim; ++k )
00256         *d_val++ = ( *xD_val++ - 10.0 ) / ( 1.0 - *xI_val++ );
00257     }
00258     if(task == 2) {
00259       /* Compute py and D */
00260       for( k = 0; k < sub_dim; ++k ) {
00261         denom = ( 1.0 - *xI_val++ );
00262         *d_val++ = ( *xD_val++ - 10.0 ) / denom;
00263         *py_val++ = *c_val++ / denom;
00264       }
00265     }
00266   }
00267   else {
00268     assert(0); /* ToDo: Implement if needed! */
00269   }
00270 
00271   return 0;
00272 }
00273 
00274 const struct RTOp_RTOp_vtbl_t RTOp_TOp_explnlp2_calc_py_D_vtbl =
00275 {
00276   &RTOp_obj_index_vtbl
00277   ,&RTOp_obj_null_vtbl
00278   ,"TOp_explnlp2_calc_py_D"
00279   ,NULL
00280   ,explnlp2_calc_py_D_apply_op
00281   ,NULL
00282   ,NULL
00283 };
00284 
00285 int RTOp_TOp_explnlp2_calc_py_D_construct( int task, struct RTOp_RTOp* op )
00286 {
00287   int result;
00288 #ifdef RTOp_DEBUG
00289   assert( 0 <= task && task <= 2 );
00290 #endif  
00291   op->obj_data  = NULL;
00292   op->vtbl      = &RTOp_TOp_explnlp2_calc_py_D_vtbl;
00293   result = op->vtbl->obj_data_vtbl->obj_create( NULL, NULL, &op->obj_data );
00294   if(result != 0) return result;
00295 #ifdef RTOp_DEBUG
00296   assert(op->obj_data);
00297 #endif
00298   *((int*)op->obj_data) = task;
00299   return 0;
00300 }
00301 
00302 int RTOp_TOp_explnlp2_calc_py_D_set_task( int task, struct RTOp_RTOp* op )
00303 {
00304 #ifdef RTOp_DEBUG
00305   assert( 0 <= task && task <= 2 );
00306   assert(op->obj_data);
00307 #endif
00308   *((int*)op->obj_data) = task;
00309   return 0;
00310 }
00311 
00312 int RTOp_TOp_explnlp2_calc_py_D_destroy( struct RTOp_RTOp* op )
00313 {
00314   int result;
00315   result = op->vtbl->reduct_vtbl->obj_free( NULL, NULL, &op->obj_data );
00316   if(result != 0) return result;
00317   op->obj_data  = NULL;
00318   op->vtbl      = NULL;
00319   return 0;
00320 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines