Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.LibSVM/1.6.3/LibSVM-1.6.3/Kernel.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 4.9 KB
Line 
1using System;
2
3namespace SVM {
4  internal interface IQMatrix {
5    float[] GetQ(int column, int len);
6    float[] GetQD();
7    void SwapIndex(int i, int j);
8  }
9
10  internal abstract class Kernel : IQMatrix {
11    private Node[][] _x;
12    private double[] _xSquare;
13
14    private KernelType _kernelType;
15    private int _degree;
16    private double _gamma;
17    private double _coef0;
18
19    public abstract float[] GetQ(int column, int len);
20    public abstract float[] GetQD();
21
22    public virtual void SwapIndex(int i, int j) {
23      _x.SwapIndex(i, j);
24
25      if (_xSquare != null) {
26        _xSquare.SwapIndex(i, j);
27      }
28    }
29
30    private static double powi(double value, int times) {
31      double tmp = value, ret = 1.0;
32
33      for (int t = times; t > 0; t /= 2) {
34        if (t % 2 == 1) ret *= tmp;
35        tmp = tmp * tmp;
36      }
37      return ret;
38    }
39
40    public double KernelFunction(int i, int j) {
41      switch (_kernelType) {
42        case KernelType.LINEAR:
43          return dot(_x[i], _x[j]);
44        case KernelType.POLY:
45          return powi(_gamma * dot(_x[i], _x[j]) + _coef0, _degree);
46        case KernelType.RBF:
47          return Math.Exp(-_gamma * (_xSquare[i] + _xSquare[j] - 2 * dot(_x[i], _x[j])));
48        case KernelType.SIGMOID:
49          return Math.Tanh(_gamma * dot(_x[i], _x[j]) + _coef0);
50        case KernelType.PRECOMPUTED:
51          return _x[i][(int)(_x[j][0].Value)].Value;
52        default:
53          return 0;
54      }
55    }
56
57    public Kernel(int l, Node[][] x_, Parameter param) {
58      _kernelType = param.KernelType;
59      _degree = param.Degree;
60      _gamma = param.Gamma;
61      _coef0 = param.Coefficient0;
62
63      _x = (Node[][])x_.Clone();
64
65      if (_kernelType == KernelType.RBF) {
66        _xSquare = new double[l];
67        for (int i = 0; i < l; i++)
68          _xSquare[i] = dot(_x[i], _x[i]);
69      } else _xSquare = null;
70    }
71
72    private static double dot(Node[] xNodes, Node[] yNodes) {
73      double sum = 0;
74      int xlen = xNodes.Length;
75      int ylen = yNodes.Length;
76      int i = 0;
77      int j = 0;
78      Node x = xNodes[0];
79      Node y = yNodes[0];
80      while (true) {
81        if (x._index == y._index) {
82          sum += x._value * y._value;
83          i++;
84          j++;
85          if (i < xlen && j < ylen) {
86            x = xNodes[i];
87            y = yNodes[j];
88          } else if (i < xlen) {
89            x = xNodes[i];
90            break;
91          } else if (j < ylen) {
92            y = yNodes[j];
93            break;
94          } else break;
95        } else {
96          if (x._index > y._index) {
97            ++j;
98            if (j < ylen)
99              y = yNodes[j];
100            else break;
101          } else {
102            ++i;
103            if (i < xlen)
104              x = xNodes[i];
105            else break;
106          }
107        }
108      }
109      return sum;
110    }
111
112    private static double computeSquaredDistance(Node[] xNodes, Node[] yNodes) {
113      Node x = xNodes[0];
114      Node y = yNodes[0];
115      int xLength = xNodes.Length;
116      int yLength = yNodes.Length;
117      int xIndex = 0;
118      int yIndex = 0;
119      double sum = 0;
120
121      while (true) {
122        if (x._index == y._index) {
123          double d = x._value - y._value;
124          sum += d * d;
125          xIndex++;
126          yIndex++;
127          if (xIndex < xLength && yIndex < yLength) {
128            x = xNodes[xIndex];
129            y = yNodes[yIndex];
130          } else if (xIndex < xLength) {
131            x = xNodes[xIndex];
132            break;
133          } else if (yIndex < yLength) {
134            y = yNodes[yIndex];
135            break;
136          } else break;
137        } else if (x._index > y._index) {
138          sum += y._value * y._value;
139          if (++yIndex < yLength)
140            y = yNodes[yIndex];
141          else break;
142        } else {
143          sum += x._value * x._value;
144          if (++xIndex < xLength)
145            x = xNodes[xIndex];
146          else break;
147        }
148      }
149
150      for (; xIndex < xLength; xIndex++) {
151        double d = xNodes[xIndex]._value;
152        sum += d * d;
153      }
154
155      for (; yIndex < yLength; yIndex++) {
156        double d = yNodes[yIndex]._value;
157        sum += d * d;
158      }
159
160      return sum;
161    }
162
163    public static double KernelFunction(Node[] x, Node[] y, Parameter param) {
164      switch (param.KernelType) {
165        case KernelType.LINEAR:
166          return dot(x, y);
167        case KernelType.POLY:
168          return powi(param.Degree * dot(x, y) + param.Coefficient0, param.Degree);
169        case KernelType.RBF: {
170            double sum = computeSquaredDistance(x, y);
171            return Math.Exp(-param.Gamma * sum);
172          }
173        case KernelType.SIGMOID:
174          return Math.Tanh(param.Gamma * dot(x, y) + param.Coefficient0);
175        case KernelType.PRECOMPUTED:
176          return x[(int)(y[0].Value)].Value;
177        default:
178          return 0;
179      }
180    }
181  }
182}
Note: See TracBrowser for help on using the repository browser.