Plif.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <string.h>
00014
00015 #include "lib/config.h"
00016 #include "lib/io.h"
00017 #include "structure/Plif.h"
00018
00019
00020
00021 CPlif::CPlif(int32_t l)
00022 : CPlifBase()
00023 {
00024 limits=NULL;
00025 penalties=NULL;
00026 cum_derivatives=NULL;
00027 id=-1;
00028 transform=T_LINEAR;
00029 name=NULL;
00030 max_value=0;
00031 min_value=0;
00032 cache=NULL;
00033 use_svm=0;
00034 use_cache=false;
00035 len=0;
00036 do_calc = true;
00037 if (l>0)
00038 set_plif_length(l);
00039 }
00040
00041 CPlif::~CPlif()
00042 {
00043 delete[] limits;
00044 delete[] penalties;
00045 delete[] name;
00046 delete[] cache;
00047 delete[] cum_derivatives;
00048 }
00049
00050 bool CPlif::set_transform_type(const char *type_str)
00051 {
00052 invalidate_cache();
00053
00054 if (strcmp(type_str, "linear")==0)
00055 transform = T_LINEAR ;
00056 else if (strcmp(type_str, "")==0)
00057 transform = T_LINEAR ;
00058 else if (strcmp(type_str, "log")==0)
00059 transform = T_LOG ;
00060 else if (strcmp(type_str, "log(+1)")==0)
00061 transform = T_LOG_PLUS1 ;
00062 else if (strcmp(type_str, "log(+3)")==0)
00063 transform = T_LOG_PLUS3 ;
00064 else if (strcmp(type_str, "(+3)")==0)
00065 transform = T_LINEAR_PLUS3 ;
00066 else
00067 {
00068 SG_ERROR( "unknown transform type (%s)\n", type_str) ;
00069 return false ;
00070 }
00071 return true ;
00072 }
00073
00074 void CPlif::init_penalty_struct_cache()
00075 {
00076 if (!use_cache)
00077 return ;
00078 if (cache || use_svm)
00079 return ;
00080 if (max_value<=0)
00081 return ;
00082
00083 float64_t* local_cache=new float64_t[ ((int32_t) max_value) + 2] ;
00084
00085 if (local_cache)
00086 {
00087 for (int32_t i=0; i<=max_value; i++)
00088 {
00089 if (i<min_value)
00090 local_cache[i] = -CMath::INFTY ;
00091 else
00092 local_cache[i] = lookup_penalty(i, NULL) ;
00093 }
00094 }
00095 this->cache=local_cache ;
00096 }
00097
00098 void CPlif::set_plif_name(char *p_name)
00099 {
00100 delete[] name ;
00101 name=new char[strlen(p_name)+1] ;
00102 strcpy(name,p_name) ;
00103 }
00104
00105 void delete_penalty_struct(CPlif** PEN, int32_t P)
00106 {
00107 for (int32_t i=0; i<P; i++)
00108 delete PEN[i] ;
00109 delete[] PEN ;
00110 }
00111
00112 float64_t CPlif::lookup_penalty_svm(
00113 float64_t p_value, float64_t *d_values) const
00114 {
00115 ASSERT(use_svm>0);
00116 float64_t d_value=d_values[use_svm-1] ;
00117 #ifdef PLIF_DEBUG
00118 SG_PRINT("%s.lookup_penalty_svm(%f)\n", get_name(), d_value) ;
00119 #endif
00120
00121 if (!do_calc)
00122 return d_value;
00123 switch (transform)
00124 {
00125 case T_LINEAR:
00126 break ;
00127 case T_LOG:
00128 d_value = log(d_value) ;
00129 break ;
00130 case T_LOG_PLUS1:
00131 d_value = log(d_value+1) ;
00132 break ;
00133 case T_LOG_PLUS3:
00134 d_value = log(d_value+3) ;
00135 break ;
00136 case T_LINEAR_PLUS3:
00137 d_value = d_value+3 ;
00138 break ;
00139 default:
00140 SG_ERROR("unknown transform\n");
00141 break ;
00142 }
00143
00144 int32_t idx = 0 ;
00145 float64_t ret ;
00146 for (int32_t i=0; i<len; i++)
00147 if (limits[i]<=d_value)
00148 idx++ ;
00149 else
00150 break ;
00151
00152 #ifdef PLIF_DEBUG
00153 SG_PRINT(" -> idx = %i ", idx) ;
00154 #endif
00155
00156 if (idx==0)
00157 ret=penalties[0] ;
00158 else if (idx==len)
00159 ret=penalties[len-1] ;
00160 else
00161 {
00162 ret = (penalties[idx]*(d_value-limits[idx-1]) + penalties[idx-1]*
00163 (limits[idx]-d_value)) / (limits[idx]-limits[idx-1]) ;
00164 #ifdef PLIF_DEBUG
00165 SG_PRINT(" -> (%1.3f*%1.3f, %1.3f*%1.3f)", (d_value-limits[idx-1])/(limits[idx]-limits[idx-1]), penalties[idx], (limits[idx]-d_value)/(limits[idx]-limits[idx-1]), penalties[idx-1]) ;
00166 #endif
00167 }
00168 #ifdef PLIF_DEBUG
00169 SG_PRINT(" -> ret=%1.3f\n", ret) ;
00170 #endif
00171
00172 return ret ;
00173 }
00174
00175 float64_t CPlif::lookup_penalty(int32_t p_value, float64_t* svm_values) const
00176 {
00177 if (use_svm)
00178 return lookup_penalty_svm(p_value, svm_values) ;
00179
00180 if ((p_value<min_value) || (p_value>max_value))
00181 return -CMath::INFTY ;
00182 if (!do_calc)
00183 return p_value;
00184 if (cache!=NULL && (p_value>=0) && (p_value<=max_value))
00185 {
00186 float64_t ret=cache[p_value] ;
00187 return ret ;
00188 }
00189 return lookup_penalty((float64_t) p_value, svm_values) ;
00190 }
00191
00192 float64_t CPlif::lookup_penalty(float64_t p_value, float64_t* svm_values) const
00193 {
00194 if (use_svm)
00195 return lookup_penalty_svm(p_value, svm_values) ;
00196
00197 #ifdef PLIF_DEBUG
00198 SG_PRINT("%s.lookup_penalty(%f)\n", get_name(), p_value) ;
00199 #endif
00200
00201
00202 if ((p_value<min_value) || (p_value>max_value))
00203 return -CMath::INFTY ;
00204
00205 if (!do_calc)
00206 return p_value;
00207
00208 float64_t d_value = (float64_t) p_value ;
00209 switch (transform)
00210 {
00211 case T_LINEAR:
00212 break ;
00213 case T_LOG:
00214 d_value = log(d_value) ;
00215 break ;
00216 case T_LOG_PLUS1:
00217 d_value = log(d_value+1) ;
00218 break ;
00219 case T_LOG_PLUS3:
00220 d_value = log(d_value+3) ;
00221 break ;
00222 case T_LINEAR_PLUS3:
00223 d_value = d_value+3 ;
00224 break ;
00225 default:
00226 SG_ERROR( "unknown transform\n") ;
00227 break ;
00228 }
00229
00230 #ifdef PLIF_DEBUG
00231 SG_PRINT(" -> value = %1.4f ", d_value) ;
00232 #endif
00233
00234 int32_t idx = 0 ;
00235 float64_t ret ;
00236 for (int32_t i=0; i<len; i++)
00237 if (limits[i]<=d_value)
00238 idx++ ;
00239 else
00240 break ;
00241
00242 #ifdef PLIF_DEBUG
00243 SG_PRINT(" -> idx = %i ", idx) ;
00244 #endif
00245
00246 if (idx==0)
00247 ret=penalties[0] ;
00248 else if (idx==len)
00249 ret=penalties[len-1] ;
00250 else
00251 {
00252 ret = (penalties[idx]*(d_value-limits[idx-1]) + penalties[idx-1]*
00253 (limits[idx]-d_value)) / (limits[idx]-limits[idx-1]) ;
00254 #ifdef PLIF_DEBUG
00255 SG_PRINT(" -> (%1.3f*%1.3f, %1.3f*%1.3f) ", (d_value-limits[idx-1])/(limits[idx]-limits[idx-1]), penalties[idx], (limits[idx]-d_value)/(limits[idx]-limits[idx-1]), penalties[idx-1]) ;
00256 #endif
00257 }
00258
00259
00260 #ifdef PLIF_DEBUG
00261 SG_PRINT(" -> ret=%1.3f\n", ret) ;
00262 #endif
00263
00264 return ret ;
00265 }
00266
00267 void CPlif::penalty_clear_derivative()
00268 {
00269 for (int32_t i=0; i<len; i++)
00270 cum_derivatives[i]=0.0 ;
00271 }
00272
00273 void CPlif::penalty_add_derivative(float64_t p_value, float64_t* svm_values)
00274 {
00275 if (use_svm)
00276 {
00277 penalty_add_derivative_svm(p_value, svm_values) ;
00278 return ;
00279 }
00280
00281 if ((p_value<min_value) || (p_value>max_value))
00282 {
00283 return ;
00284 }
00285 float64_t d_value = (float64_t) p_value ;
00286 switch (transform)
00287 {
00288 case T_LINEAR:
00289 break ;
00290 case T_LOG:
00291 d_value = log(d_value) ;
00292 break ;
00293 case T_LOG_PLUS1:
00294 d_value = log(d_value+1) ;
00295 break ;
00296 case T_LOG_PLUS3:
00297 d_value = log(d_value+3) ;
00298 break ;
00299 case T_LINEAR_PLUS3:
00300 d_value = d_value+3 ;
00301 break ;
00302 default:
00303 SG_ERROR( "unknown transform\n") ;
00304 break ;
00305 }
00306
00307 int32_t idx = 0 ;
00308 for (int32_t i=0; i<len; i++)
00309 if (limits[i]<=d_value)
00310 idx++ ;
00311 else
00312 break ;
00313
00314 if (idx==0)
00315 cum_derivatives[0]+=1 ;
00316 else if (idx==len)
00317 cum_derivatives[len-1]+=1 ;
00318 else
00319 {
00320 cum_derivatives[idx]+=(d_value-limits[idx-1])/(limits[idx]-limits[idx-1]) ;
00321 cum_derivatives[idx-1]+=(limits[idx]-d_value)/(limits[idx]-limits[idx-1]) ;
00322 }
00323 }
00324
00325 void CPlif::penalty_add_derivative_svm(float64_t p_value, float64_t *d_values)
00326 {
00327 ASSERT(use_svm>0);
00328 float64_t d_value=d_values[use_svm-1] ;
00329
00330 if (d_value<-1e+20)
00331 return;
00332
00333 switch (transform)
00334 {
00335 case T_LINEAR:
00336 break ;
00337 case T_LOG:
00338 d_value = log(d_value) ;
00339 break ;
00340 case T_LOG_PLUS1:
00341 d_value = log(d_value+1) ;
00342 break ;
00343 case T_LOG_PLUS3:
00344 d_value = log(d_value+3) ;
00345 break ;
00346 case T_LINEAR_PLUS3:
00347 d_value = d_value+3 ;
00348 break ;
00349 default:
00350 SG_ERROR( "unknown transform\n") ;
00351 break ;
00352 }
00353
00354 int32_t idx = 0 ;
00355 for (int32_t i=0; i<len; i++)
00356 if (limits[i]<=d_value)
00357 idx++ ;
00358 else
00359 break ;
00360
00361 if (idx==0)
00362 cum_derivatives[0]+=1 ;
00363 else if (idx==len)
00364 cum_derivatives[len-1]+=1 ;
00365 else
00366 {
00367 cum_derivatives[idx]+=(d_value-limits[idx-1])/(limits[idx]-limits[idx-1]) ;
00368 cum_derivatives[idx-1]+=(limits[idx]-d_value)/(limits[idx]-limits[idx-1]) ;
00369 }
00370 }
00371
00372 void CPlif::get_used_svms(int32_t* num_svms, int32_t* svm_ids)
00373 {
00374 if (use_svm)
00375 {
00376 svm_ids[(*num_svms)] = use_svm;
00377 (*num_svms)++;
00378 }
00379 SG_PRINT("->use_svm:%i plif_id:%i name:%s trans_type:%s ",use_svm, get_id(), get_name(), get_transform_type());
00380 }
00381
00382 bool CPlif::get_do_calc()
00383 {
00384 return do_calc;
00385 }
00386
00387 void CPlif::set_do_calc(bool b)
00388 {
00389 do_calc = b;;
00390 }