SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Math.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Written (W) 1999-2008 Gunnar Raetsch
9  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  */
11 #include <shogun/base/SGObject.h>
12 #include <shogun/lib/common.h>
13 #include <cmath>
16 #include <shogun/io/SGIO.h>
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <math.h>
21 
22 using namespace shogun;
23 
24 #ifdef USE_LOGCACHE
25 #ifdef USE_HMMDEBUG
26 #define MAX_LOG_TABLE_SIZE 10*1024*1024
27 #define LOG_TABLE_PRECISION 1e-6
28 #else //USE_HMMDEBUG
29 #define MAX_LOG_TABLE_SIZE 123*1024*1024
30 #define LOG_TABLE_PRECISION 1e-15
31 #endif //USE_HMMDEBUG
32 int32_t CMath::LOGACCURACY = 0; // 100000 steps per integer
33 #endif // USE_LOGCACHE
34 
35 int32_t CMath::LOGRANGE = 0; // range for logtable: log(1+exp(x)) -25 <= x <= 0
36 
37 const float64_t CMath::INFTY = -log(0.0); // infinity
38 const float64_t CMath::ALMOST_INFTY = +1e+20; //a large number
44 
45 #ifdef USE_LOGCACHE
46 float64_t* CMath::logtable = NULL;
47 #endif
48 uint32_t CMath::seed = 0;
49 
51 : CSGObject()
52 {
53 #ifdef USE_LOGCACHE
54  LOGRANGE=CMath::determine_logrange();
55  LOGACCURACY=CMath::determine_logaccuracy(LOGRANGE);
56  CMath::logtable=SG_MALLOC(float64_t, LOGRANGE*LOGACCURACY);
57  init_log_table();
58 #else
59  int32_t i=0;
60  while ((float64_t)log(1+((float64_t)exp(-float64_t(i)))))
61  i++;
62 
63  LOGRANGE=i;
64 #endif
65 }
66 
68 {
69 #ifdef USE_LOGCACHE
70  SG_FREE(CMath::logtable);
71  CMath::logtable=NULL;
72 #endif
73 }
74 
75 #ifdef USE_LOGCACHE
76 int32_t CMath::determine_logrange()
77 {
78  int32_t i;
79  float64_t acc=0;
80  for (i=0; i<50; i++)
81  {
82  acc=((float64_t)log(1+((float64_t)exp(-float64_t(i)))));
83  if (acc<=(float64_t)LOG_TABLE_PRECISION)
84  break;
85  }
86 
87  SG_SINFO("determined range for x in table log(1+exp(-x)) is:%d (error:%G)\n",i,acc)
88  return i;
89 }
90 
91 int32_t CMath::determine_logaccuracy(int32_t range)
92 {
93  range=MAX_LOG_TABLE_SIZE/range/((int)sizeof(float64_t));
94  SG_SINFO("determined accuracy for x in table log(1+exp(-x)) is:%d (error:%G)\n",range,1.0/(double) range)
95  return range;
96 }
97 
98 //init log table of form log(1+exp(x))
99 void CMath::init_log_table()
100 {
101  for (int32_t i=0; i< LOGACCURACY*LOGRANGE; i++)
102  logtable[i]=log(1+exp(float64_t(-i)/float64_t(LOGACCURACY)));
103 }
104 #endif
105 
106 void CMath::sort(int32_t *a, int32_t cols, int32_t sort_col)
107 {
108  int32_t changed=1;
109  if (a[0]==-1) return ;
110  while (changed)
111  {
112  changed=0; int32_t i=0 ;
113  while ((a[(i+1)*cols]!=-1) && (a[(i+1)*cols+1]!=-1)) // to be sure
114  {
115  if (a[i*cols+sort_col]>a[(i+1)*cols+sort_col])
116  {
117  for (int32_t j=0; j<cols; j++)
118  CMath::swap(a[i*cols+j],a[(i+1)*cols+j]) ;
119  changed=1 ;
120  } ;
121  i++ ;
122  } ;
123  } ;
124 }
125 
126 void CMath::sort(float64_t *a, int32_t* idx, int32_t N)
127 {
128  int32_t changed=1;
129  while (changed)
130  {
131  changed=0;
132  for (int32_t i=0; i<N-1; i++)
133  {
134  if (a[i]>a[i+1])
135  {
136  swap(a[i],a[i+1]) ;
137  swap(idx[i],idx[i+1]) ;
138  changed=1 ;
139  } ;
140  } ;
141  } ;
142 
143 }
144 
146  char* seq1, char* seq2, int32_t l1, int32_t l2, float64_t gapCost)
147 {
148  float64_t actCost=0 ;
149  int32_t i1, i2 ;
150  float64_t* const gapCosts1 = SG_MALLOC(float64_t, l1 );
151  float64_t* const gapCosts2 = SG_MALLOC(float64_t, l2 );
152  float64_t* costs2_0 = SG_MALLOC(float64_t, l2 + 1 );
153  float64_t* costs2_1 = SG_MALLOC(float64_t, l2 + 1 );
154 
155  // initialize borders
156  for( i1 = 0; i1 < l1; ++i1 ) {
157  gapCosts1[ i1 ] = gapCost * i1;
158  }
159  costs2_1[ 0 ] = 0;
160  for( i2 = 0; i2 < l2; ++i2 ) {
161  gapCosts2[ i2 ] = gapCost * i2;
162  costs2_1[ i2+1 ] = costs2_1[ i2 ] + gapCosts2[ i2 ];
163  }
164  // compute alignment
165  for( i1 = 0; i1 < l1; ++i1 ) {
166  swap( costs2_0, costs2_1 );
167  actCost = costs2_0[ 0 ] + gapCosts1[ i1 ];
168  costs2_1[ 0 ] = actCost;
169  for( i2 = 0; i2 < l2; ++i2 ) {
170  const float64_t actMatch = costs2_0[ i2 ] + ( seq1[i1] == seq2[i2] );
171  const float64_t actGap1 = costs2_0[ i2+1 ] + gapCosts1[ i1 ];
172  const float64_t actGap2 = actCost + gapCosts2[ i2 ];
173  const float64_t actGap = min( actGap1, actGap2 );
174  actCost = min( actMatch, actGap );
175  costs2_1[ i2+1 ] = actCost;
176  }
177  }
178 
179  SG_FREE(gapCosts1);
180  SG_FREE(gapCosts2);
181  SG_FREE(costs2_0);
182  SG_FREE(costs2_1);
183 
184  // return the final cost
185  return actCost;
186 }
187 
188 void CMath::linspace(float64_t* output, float64_t start, float64_t end, int32_t n)
189 {
190  float64_t delta = (end-start) / (n-1);
191  float64_t v = start;
192  index_t i = 0;
193  while ( v <= end )
194  {
195  output[i++] = v;
196  v += delta;
197  }
198  output[n-1] = end;
199 }
200 
201 
202 int CMath::is_nan(double f)
203 {
204  return std::isnan(f);
205 }
206 
207 int CMath::is_infinity(double f)
208 {
209  return std::isinf(f);
210 }

SHOGUN Machine Learning Toolbox - Documentation