def train_dual(self):
		"""Trains an one-class svm in dual with kernel."""
		if (self.samples<1):
			print('Invalid training data.')
			return OCSVM.MSG_ERROR

		# number of training examples
		N = self.samples

		# generate a kernel matrix
		P = self.kernel
		# there is no linear part of the objective
		q = matrix(0.0, (N,1))

		# sum_i alpha_i = A alpha = b = 1.0
		A = matrix(1.0, (1,N))
		b = matrix(1.0, (1,1))

		# 0 <= alpha_i <= h = C
		G1 = spmatrix(1.0, range(N), range(N))
		G = sparse([G1,-G1])
		h1 = matrix(self.C, (N,1))
		h2 = matrix(0.0, (N,1))
		h = matrix([h1,h2])

		sol = qp(P,-q,G,h,A,b)

		# mark dual as solved
		self.isDualTrained = True

		# store solution
		self.alphas = sol['x']

		# find support vectors
		self.svs = []
		for i in range(N):
			if self.alphas[i]>OCSVM.PRECISION:
				self.svs.append(i)

		# find support vectors with alpha < C for threshold calculation
		#self.threshold = 10**8
		#flag = False
		#for i in self.svs:
		#	if self.alphas[i]<(C-OCSVM.PRECISION) and flag==False:
		#		(self.threshold, MSG) = self.apply_dual(self.kernel[i,self.svs])
		#		flag=True
		#		break

		# no threshold set yet?
		#if (flag==False):
		#	(thres, MSG) = self.apply_dual(self.kernel[self.svs,self.svs])
		#	self.threshold = matrix(max(thres))

		(thres, MSG) = self.apply_dual(self.kernel[self.svs,self.svs])
		self.threshold = matrix(max(thres))

		T = np.single(self.threshold)
		cnt = 0
		for i in range(len(self.svs)):
			if thres[i,0]<(T-OCSVM.PRECISION):
				cnt += 1

		#print(self.alphas)
		print('Found {0} support vectors. {1} of them are outliers.'.format(len(self.svs),cnt))
		print('Threshold is {0}'.format(self.threshold))
		return OCSVM.MSG_OK
dataset/ETHPy150Open nicococo/tilitools/ocsvm.py/OCSVM.train_dual/original