libsvm matlab インタフェースで目的関数の値を得る Get an objective value in the libsvm Matlab interface

[libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/)のmatlabインタフェースですが，Version 3.14, November 2012 の段階では，学習結果の構造体に目的関数の値が入っていません．

[ここ](http://stackoverflow.com/questions/10627125/compute-objective-value-libsvm-matlab)のページに修正方法が記載されておりましたので，実際にどこをどのように修正するかをメモしておきます．
環境はMac OS 10.7.5, Matlab 2012b 64bit, i686-apple-darwin11-llvm-g++-4.2 です

[libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) provides its matlab interface. However, in the current version (Version 3.14, November 2012), the output structure generated by svmtrain does NOT include an objective value.

Referring to [here](http://stackoverflow.com/questions/10627125/compute-objective-value-libsvm-matlab), this article shows a concrete instruction to modify libsvm.

NOTE: confirmed in Mac OS 10.7.5, Matlab 2012b 64bit, i686-apple-darwin11-llvm-g++-4.2 for compilation

``` c++:svm.cpp
//
// decision_function
//
struct decision_function
{
	double *alpha;
	double rho;
	// ADD THE FIELD "OBJ"
	double obj;
        //
};

...

static decision_function svm_train_one(
	const svm_problem *prob, const svm_parameter *param,
	double Cp, double Cn)
{

...
	decision_function f;
	f.alpha = alpha;
	f.rho = si.rho;
	// COPY THE OBJECTIVE VALUE TO THE ADDED FIELD
	f.obj=si.obj;
	// 
	return f;
}

...

svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)
{

...
		decision_function f = svm_train_one(prob,param,0,0);
		model->rho = Malloc(double,1);
		model->rho[0] = f.rho;
		
		// COPY THE OBJECTIVE VALUE TO A MODEL INSTANCE
		model->obj = Malloc(double ,1);
		model->obj[0]=f.obj;
                // 
...

		// build output

		model->nr_class = nr_class;
		
		// COPY THE OBJECTIVE VALUE TO A MODEL INSTANCE
		model->obj = Malloc(double,p);
		for(i=0;i<p;i++)
			model->obj[i]=f[i].obj;
		// 

```

``` c++:svm.h

struct svm_model
{

...
	int free_sv;		/* 1 if svm_model is created by svm_load_model*/
				/* 0 if svm_model is created by svm_train */
	// ADD THE FIELD "OBJ"
	double* obj;
	// 
};

```

``` c++:svm_model_matlab.c

#define NUM_OF_RETURN_FIELD 12 // CHANGE # FILEDS FROM 11 TO 12
...
static const char *field_names[] = {
	"Parameters",
	"nr_class",
	"totalSV",
	"rho",
	// ADD THE FIELD "OBJ"
	"obj",
	// 
	"Label",
	"sv_indices",
	"ProbA",
	"ProbB",
	"nSV",
	"sv_coef",
	"SVs"
};

...

	// rho
	n = model->nr_class*(model->nr_class-1)/2;
	rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	for(i = 0; i < n; i++)
		ptr[i] = model->rho[i];
	out_id++;

	// COPY THE OBJECTIVE VALUE IN A MODEL INSTANCE
	n = model->nr_class*(model->nr_class-1)/2;
	rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	for(i = 0; i < n; i++)
		ptr[i] = model->obj[i];
	out_id++;
	// 

...

	model->rho = NULL;
	// INSERT NULL TO OBJ
	model->obj = NULL;
	// 

	// rho
	n = model->nr_class * (model->nr_class-1)/2;
	model->rho = (double*) malloc(n*sizeof(double));
	ptr = mxGetPr(rhs[id]);
	for(i=0;i<n;i++)
		model->rho[i] = ptr[i];
	id++;

	// COPY THE OBJECTIVE VALUE IN A MODEL INSTANCE
	n = model->nr_class * (model->nr_class-1)/2;
	model->obj = (double*) malloc(n*sizeof(double));
	ptr = mxGetPr(rhs[id]);
	for(i=0;i<n;i++)
		model->obj[i] = ptr[i];
	id++;
	// 
```