SHOGUN
v3.2.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2008-2009 Soeren Sonnenburg 00008 * Copyright (C) 2008-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 */ 00010 00011 #ifndef _TANIMOTOKERNELNORMALIZER_H___ 00012 #define _TANIMOTOKERNELNORMALIZER_H___ 00013 00014 #include <shogun/kernel/normalizer/KernelNormalizer.h> 00015 #include <shogun/kernel/string/CommWordStringKernel.h> 00016 00017 namespace shogun 00018 { 00026 class CTanimotoKernelNormalizer : public CKernelNormalizer 00027 { 00028 public: 00033 CTanimotoKernelNormalizer(bool use_opt_diag=false) 00034 : CKernelNormalizer(), diag_lhs(NULL), diag_rhs(NULL), 00035 use_optimized_diagonal_computation(use_opt_diag) 00036 { 00037 } 00038 00040 virtual ~CTanimotoKernelNormalizer() 00041 { 00042 SG_FREE(diag_lhs); 00043 SG_FREE(diag_rhs); 00044 } 00045 00048 virtual bool init(CKernel* k) 00049 { 00050 ASSERT(k) 00051 int32_t num_lhs=k->get_num_vec_lhs(); 00052 int32_t num_rhs=k->get_num_vec_rhs(); 00053 ASSERT(num_lhs>0) 00054 ASSERT(num_rhs>0) 00055 00056 CFeatures* old_lhs=k->lhs; 00057 CFeatures* old_rhs=k->rhs; 00058 00059 k->lhs=old_lhs; 00060 k->rhs=old_lhs; 00061 bool r1=alloc_and_compute_diag(k, diag_lhs, num_lhs); 00062 00063 k->lhs=old_rhs; 00064 k->rhs=old_rhs; 00065 bool r2=alloc_and_compute_diag(k, diag_rhs, num_rhs); 00066 00067 k->lhs=old_lhs; 00068 k->rhs=old_rhs; 00069 00070 return r1 && r2; 00071 } 00072 00078 virtual float64_t normalize( 00079 float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00080 { 00081 float64_t diag_sum=diag_lhs[idx_lhs]*diag_rhs[idx_rhs]; 00082 return value/(diag_sum-value); 00083 } 00084 00089 virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00090 { 00091 SG_ERROR("linadd not supported with Tanimoto normalization.\n") 00092 return 0; 00093 } 00094 00099 virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00100 { 00101 SG_ERROR("linadd not supported with Tanimoto normalization.\n") 00102 return 0; 00103 } 00104 00110 virtual const char* get_name() const { 00111 return "TanimotoKernelNormalizer"; } 00112 00113 public: 00118 bool alloc_and_compute_diag(CKernel* k, float64_t* &v, int32_t num) 00119 { 00120 SG_FREE(v); 00121 v=SG_MALLOC(float64_t, num); 00122 00123 for (int32_t i=0; i<num; i++) 00124 { 00125 if (k->get_kernel_type() == K_COMMWORDSTRING) 00126 { 00127 if (use_optimized_diagonal_computation) 00128 v[i]=((CCommWordStringKernel*) k)->compute_diag(i); 00129 else 00130 v[i]=((CCommWordStringKernel*) k)->compute_helper(i,i, true); 00131 } 00132 else 00133 v[i]=k->compute(i,i); 00134 00135 if (v[i]==0.0) 00136 v[i]=1e-16; /* avoid divide by zero exception */ 00137 } 00138 00139 return (v!=NULL); 00140 } 00141 00142 protected: 00144 float64_t* diag_lhs; 00146 float64_t* diag_rhs; 00148 bool use_optimized_diagonal_computation; 00149 }; 00150 } 00151 #endif