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