/*
  Copyright(C) 2007-2012 National Institute of Information and Communications Technology
*/

/*
  svmtools
  Kernel module
*/


#ifndef _SVM_KERNEL_H_
#define _SVM_KERNEL_H_


#include "svm_common.h"


#define SVM_KFUNC_POLYNOMIAL_1O 4
#define SVM_KFUNC_POLYNOMIAL_2O 5
#define SVM_KFUNC_POLYNOMIAL_3O 6
#define SVM_KFUNC_POLYNOMIAL_4O 7
#define SVM_KFUNC_POLYNOMIAL_5O 8


/* カーネル計算用の作業用データ */
typedef struct Svm_kwrk {
  int kfunc;	/* 使用するカーネル関数 */
  int num;	/* 計算対象のベクトルの個数 */
  SVM_SV **sv;	/* 学習事例 */
  float *sqnorm;	/* RBFカーネル用 */
  float sqnorm2;	/* RBFカーネル用 */
  int max;	/* 素性の数 */
  int *tbl;	/* 内積計算用の索引表 */
  int *inv_eid;	/* 転置インデックスの事例id */
  float *inv_val;	/* 転置インデックスのベクトル値 */
} SVM_KWRK;

/* Kernel cache */
typedef struct Svm_kc {
  SVM_KPRM kprm;
  int col;	/* キャッシュ行列の列の数 */
  int row;	/* キャッシュの数(キャッシュ行列の行数) */
  int size;	/* キャッシュのサイズ */
  float *cache;	/* キャッシュデータ */
  int *e2r;	/* 索引(事例id→キャッシュの行) */
  unsigned int *r2e;	/* 逆索引(キャッシュの行→事例id)(最上位ビットは使用フラグ) */
  int nxt;	/* clock algorithmで次に調べる行 */
  int *gen;	/* 各行の世代(使われる時点になってから世代の調整を行う) */
  int hst_num;	/* 現在の世代 */
  int *hst;	/* これまでに削除してきたインデックスの履歴 */
  int *label;	/* 学習事例のラベル */
  SVM_KWRK *kwrk;	/* 作業用データ */
} SVM_KC;


SVM_KC *svm_knl_kcinit(SVM_KPRM *kprm, int num, int *label, SVM_SV **sv, int size);
void svm_knl_kcdelete(SVM_KC *kc);
float *svm_knl_kckernel(SVM_KC *kc, int p, float *rsv);
void svm_knl_kchide(SVM_KC *kc, int p);
void svm_knl_kcexpand(SVM_KC *kc);
SVM_KWRK *svm_knl_kwrkinit(SVM_KPRM *kprm, int num, SVM_SV **sv);
SVM_KWRK *svm_knl_kwrkinit_inv(SVM_KPRM *kprm, int num, SVM_SV **sv);
void svm_knl_kwrkdelete(SVM_KWRK *kwrk);
void svm_knl_kwrkkernel(SVM_KPRM *kprm, SVM_KWRK *kwrk, SVM_SV *v, float *q);


#endif
