|
RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators Version of the Day
|
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 <math.h> 00032 00033 #include "RTOp_ROp_norms.h" 00034 #include "RTOp_obj_null_vtbl.h" 00035 #include "RTOp_obj_value_vtbl.h" 00036 #include "RTOp_reduct_sum_value.h" 00037 #include "RTOp_reduct_max_value.h" 00038 00039 #define MY_MAX(a,b) a > b ? a : b 00040 00041 /* One norm reduction operator class. */ 00042 00043 static int RTOp_ROp_norms_apply_op_norm_1( 00044 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00045 , const int num_vecs, const struct RTOp_SubVector vecs[] 00046 , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00047 , RTOp_ReductTarget targ_obj ) 00048 { 00049 RTOp_index_type sub_dim; 00050 const RTOp_value_type *v0_val; 00051 ptrdiff_t v0_val_s; 00052 register RTOp_index_type k; 00053 RTOp_value_type *norm = NULL; 00054 00055 /* */ 00056 /* Validate the input */ 00057 /* */ 00058 if( num_vecs != 1 ) 00059 return RTOp_ERR_INVALID_NUM_VECS; 00060 if( num_targ_vecs != 0 ) 00061 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00062 assert(targ_obj); 00063 assert(vecs); 00064 00065 /* */ 00066 /* Get pointers to data */ 00067 /* */ 00068 00069 /* v0 */ 00070 sub_dim = vecs[0].sub_dim; 00071 v0_val = vecs[0].values; 00072 v0_val_s = vecs[0].values_stride; 00073 00074 /* */ 00075 /* Perform the reduction */ 00076 /* */ 00077 norm = (RTOp_value_type*)targ_obj; 00078 for( k = 0; k < sub_dim; ++k, v0_val += v0_val_s ) { 00079 *norm += fabs(*v0_val); /* ||v[0]||_1 */ 00080 } 00081 00082 return 0; /* success? */ 00083 } 00084 00085 const struct RTOp_RTOp_vtbl_t RTOp_ROp_norm_1_vtbl = 00086 { 00087 &RTOp_obj_null_vtbl /* use null type for instance data */ 00088 ,&RTOp_obj_value_vtbl /* use simple scalar type for target object */ 00089 ,"RTOp_ROp_norm_1" 00090 ,NULL 00091 ,RTOp_ROp_norms_apply_op_norm_1 00092 ,RTOp_reduct_sum_value 00093 ,RTOp_get_reduct_sum_value_op 00094 }; 00095 00096 int RTOp_ROp_norm_1_construct( struct RTOp_RTOp* op ) 00097 { 00098 op->vtbl = &RTOp_ROp_norm_1_vtbl; 00099 op->obj_data = NULL; 00100 return 0; 00101 } 00102 00103 RTOp_value_type RTOp_ROp_norm_1_val(RTOp_ReductTarget targ_obj) 00104 { 00105 #ifdef RTOp_DEBUG 00106 assert(targ_obj != RTOp_REDUCT_OBJ_NULL ); 00107 #endif 00108 return *(RTOp_value_type*)targ_obj; 00109 } 00110 00111 /* Two norm reduction operator class. */ 00112 00113 static int RTOp_ROp_norms_apply_op_norm_2( 00114 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00115 , const int num_vecs, const struct RTOp_SubVector vecs[] 00116 , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00117 , RTOp_ReductTarget targ_obj ) 00118 { 00119 RTOp_index_type sub_dim; 00120 const RTOp_value_type *v0_val; 00121 ptrdiff_t v0_val_s; 00122 register RTOp_index_type k; 00123 RTOp_value_type *norm = NULL; 00124 00125 /* */ 00126 /* Validate the input */ 00127 /* */ 00128 if( num_vecs != 1 ) 00129 return RTOp_ERR_INVALID_NUM_VECS; 00130 if( num_targ_vecs != 0 ) 00131 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00132 assert(targ_obj); 00133 assert(vecs); 00134 00135 /* */ 00136 /* Get pointers to data */ 00137 /* */ 00138 00139 /* v0 */ 00140 sub_dim = vecs[0].sub_dim; 00141 v0_val = vecs[0].values; 00142 v0_val_s = vecs[0].values_stride; 00143 00144 /* */ 00145 /* Perform the reduction */ 00146 /* */ 00147 norm = (RTOp_value_type*)targ_obj; 00148 for( k = 0; k < sub_dim; ++k, v0_val += v0_val_s ) 00149 *norm += (*v0_val)*(*v0_val); /* (||v[0]||_2)^2 */ 00150 00151 return 0; /* success? */ 00152 } 00153 00154 const struct RTOp_RTOp_vtbl_t RTOp_ROp_norm_2_vtbl = 00155 { 00156 &RTOp_obj_null_vtbl /* use null type for instance data */ 00157 ,&RTOp_obj_value_vtbl /* use simple scalar type for target object */ 00158 ,"RTOp_ROp_norm_2" 00159 ,NULL 00160 ,RTOp_ROp_norms_apply_op_norm_2 00161 ,RTOp_reduct_sum_value 00162 ,RTOp_get_reduct_sum_value_op 00163 }; 00164 00165 int RTOp_ROp_norm_2_construct( struct RTOp_RTOp* op ) 00166 { 00167 op->vtbl = &RTOp_ROp_norm_2_vtbl; 00168 op->obj_data = NULL; 00169 return 0; 00170 } 00171 00172 RTOp_value_type RTOp_ROp_norm_2_val(RTOp_ReductTarget targ_obj) 00173 { 00174 #ifdef RTOp_DEBUG 00175 assert(targ_obj != RTOp_REDUCT_OBJ_NULL ); 00176 #endif 00177 return sqrt(*(RTOp_value_type*)targ_obj); 00178 } 00179 00180 /* Infinity norm reduction operator class. */ 00181 00182 static int RTOp_ROp_norms_apply_op_norm_inf( 00183 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00184 , const int num_vecs, const struct RTOp_SubVector vecs[] 00185 , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00186 , RTOp_ReductTarget targ_obj ) 00187 { 00188 RTOp_index_type sub_dim; 00189 const RTOp_value_type *v0_val; 00190 ptrdiff_t v0_val_s; 00191 register RTOp_index_type k; 00192 RTOp_value_type *norm = NULL; 00193 00194 /* */ 00195 /* Validate the input */ 00196 /* */ 00197 if( num_vecs != 1 ) 00198 return RTOp_ERR_INVALID_NUM_VECS; 00199 if( num_targ_vecs != 0 ) 00200 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00201 assert(targ_obj); 00202 assert(vecs); 00203 00204 /* */ 00205 /* Get pointers to data */ 00206 /* */ 00207 00208 /* v0 */ 00209 sub_dim = vecs[0].sub_dim; 00210 v0_val = vecs[0].values; 00211 v0_val_s = vecs[0].values_stride; 00212 00213 /* */ 00214 /* Perform the reduction */ 00215 /* */ 00216 norm = (RTOp_value_type*)targ_obj; 00217 for( k = 0; k < sub_dim; ++k, v0_val += v0_val_s ) 00218 *norm = MY_MAX( fabs(*v0_val), (*(RTOp_value_type*)targ_obj) ); /* ||v[0]||_inf */ 00219 00220 return 0; /* success? */ 00221 } 00222 00223 const struct RTOp_RTOp_vtbl_t RTOp_ROp_norm_inf_vtbl = 00224 { 00225 &RTOp_obj_null_vtbl /* use null type for instance data */ 00226 ,&RTOp_obj_value_vtbl /* use simple scalar type for target object */ 00227 ,"RTOp_ROp_norm_inf" 00228 ,NULL 00229 ,RTOp_ROp_norms_apply_op_norm_inf 00230 ,RTOp_reduct_max_value 00231 ,RTOp_get_reduct_max_value_op 00232 }; 00233 00234 int RTOp_ROp_norm_inf_construct( struct RTOp_RTOp* op ) 00235 { 00236 op->vtbl = &RTOp_ROp_norm_inf_vtbl; 00237 op->obj_data = NULL; 00238 return 0; 00239 } 00240 00241 RTOp_value_type RTOp_ROp_norm_inf_val(RTOp_ReductTarget targ_obj) 00242 { 00243 #ifdef RTOp_DEBUG 00244 assert(targ_obj != RTOp_REDUCT_OBJ_NULL ); 00245 #endif 00246 return *(RTOp_value_type*)targ_obj; 00247 } 00248 00249 /* Common functions */ 00250 00251 int RTOp_ROp_norm_destroy( struct RTOp_RTOp* op ) 00252 { 00253 op->vtbl = NULL; 00254 return 0; 00255 }
1.7.4