File: util.cpp

package info (click to toggle)
mldemos 0.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 32,224 kB
  • ctags: 46,525
  • sloc: cpp: 306,887; ansic: 167,718; ml: 126; sh: 109; makefile: 2
file content (161 lines) | stat: -rw-r--r-- 3,171 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

#include "util.h"
using namespace std;

void VectorMatrixMultipy(double *VectorA, double **MatrixB, double *Result, int cols, int rows)	//m=1
{
	for(int i=0; i<cols; i++)
	{
		Result[i] = 0;
		for(int j=0; j<rows; j++)
		{
			Result[i] += VectorA[j]*MatrixB[j][i];
		}
	}
}

void MatrixVectorMultipy(double **MatrixB, double *VectorA, double *Result, int cols, int rows)	//m=1
{
	for(int i=0; i<rows; i++)
	{
		Result[i] = 0;
		for(int j=0; j<cols; j++)
		{
			Result[i] += VectorA[j]*MatrixB[i][j];
		}
	}
}

double arraydot(double *x, double *y, int m)
{
	double dot = 0.0;
	for(int i =0; i<m; i++)
		dot += x[i]*y[i];
	return dot;
}

double norm(double *x, int m)
{
	double sum = 0.0;
	for(int i=0; i<m; i++)
		sum += x[i]*x[i];

	return sqrt(sum);
}

double norm2(double *x, int m)
{
	double sum = 0.0;
	for(int i=0; i<m; i++)
		sum += x[i]*x[i];

	return sum;
}

double getkernel(double *x1, double *x2, double lambda, const char* type, int n)
{
	double ker_val = 0.0;
	double *diff = new double[n];

	for(int i =0; i<n; i++)
	{
		diff[i] = x1[i] - x2[i];
	}
	if(strcmp(type, "poly") == 0)
		ker_val = pow((arraydot(x1, x2, n)+1),lambda);
	else if(strcmp(type, "rbf") == 0)
	{
		ker_val = exp(-lambda*norm2(diff, n));
	}
	else
		cout<<"\nInvalid kernel type specified in getkernel function!";
	delete diff;
	return ker_val;
}

bool getfirstkernelderivative(double *x1, double *x2, double lambda, const char* type, int der_wrt, double* der_val, int n)
{
	double temp = 0.0;

	if(strcmp(type, "poly") == 0)
	{
		temp = lambda*pow((arraydot(x1, x2, n)+1),(lambda-1));
		if(der_wrt == 1)
		{
			for(int i=0; i<n; i++)
				der_val[i] = temp*x2[i];
		}
		else
		{
			for(int i=0; i<n; i++)
				der_val[i] = temp*x1[i];
		}

		return true;
	}
	else if(strcmp(type, "rbf") == 0)
	{
		double *diff;
		diff = new double[n];
		for(int i =0; i<n; i++)
			diff[i] = x1[i] - x2[i];

		if(der_wrt == 1)
		{
			temp = -2*lambda*exp(-lambda*norm2(diff, n));
		}
		else
		{
			temp = 2*lambda*exp(-lambda*norm2(diff, n));
		}

		for(int i =0; i<n; i++)
			der_val[i] = temp*diff[i];
		delete diff;
		return true;
	}
	else
	{
		cout<<"\nInvalid kernel type specified in getkernel function!";
		return false;
	}
}

bool getsecondkernelderivative(double *x1, double *x2, int n, double lambda, const char *type, double **hesval)
{
	if(strcmp(type, "poly") == 0)
	{
		double tmp = arraydot(x1, x2, n) + 1;
		for(int i =0; i< n; i++)
			for(int j=0; j< n; j++)
			{
				if(i == j)
					hesval[i][j] = lambda* pow(tmp,(lambda-2))*( tmp + (lambda-1)*x2[i]*x1[j]);
				else
					hesval[i][j] = lambda* pow(tmp,(lambda-2))*((lambda-1)*x2[i]*x1[j]);
			}
		return true;
	}
	else if(strcmp(type, "rbf") == 0)
	{
		double *tmp1 = new double[n];
		for(int i =0; i<n; i++)
			tmp1[i] = x1[i] - x2[i];

		for(int i = 0; i<n; i++)
			for(int j =0; j<n; j++)
				if(i == j)
					hesval[i][j] = 2*lambda*exp(-lambda*norm2(tmp1,n)) * ( 1 - 2*lambda*(tmp1[i]*tmp1[j]));
				else
					hesval[i][j] = 2*lambda*exp(-lambda*norm2(tmp1, n)) * (- 2*lambda*(tmp1[i]*tmp1[j]));
		delete tmp1;
		return true;
	}
	else
	{
		cout<<"\nInvalid type specified in the getsecondkernelderivative";
		return false;
	}
}