Algorithm-LibLinear

 view release on metacpan or  search on metacpan

src/liblinear/linear.cpp  view on Meta::CPAN

	int get_nr_variable(void);

protected:
	virtual double C_times_loss(int i, double wx_i) = 0;
	void Xv(double *v, double *Xv);
	void XTv(double *v, double *XTv);

	double *C;
	const problem *prob;
	double *wx;
	double *tmp; // a working array
	double wTw;
	int regularize_bias;
};

l2r_erm_fun::l2r_erm_fun(const problem *prob, const parameter *param, double *C)
{
	int l=prob->l;

	this->prob = prob;

	wx = new double[l];
	tmp = new double[l];
	this->C = C;
	this->regularize_bias = param->regularize_bias;
}

l2r_erm_fun::~l2r_erm_fun()
{
	delete[] wx;
	delete[] tmp;
}

double l2r_erm_fun::fun(double *w)
{
	int i;
	double f=0;
	int l=prob->l;
	int w_size=get_nr_variable();

	wTw = 0;
	Xv(w, wx);

	for(i=0;i<w_size;i++)
		wTw += w[i]*w[i];
	if(regularize_bias == 0)
		wTw -= w[w_size-1]*w[w_size-1];
	for(i=0;i<l;i++)
		f += C_times_loss(i, wx[i]);
	f = f + 0.5 * wTw;

	return f;
}

int l2r_erm_fun::get_nr_variable(void)
{
	return prob->n;
}

// On entry *f must be the function value of w
// On exit w is updated and *f is the new function value
double l2r_erm_fun::linesearch_and_update(double *w, double *s, double *f, double *g, double alpha)
{
	int i;
	int l = prob->l;
	double sTs = 0;
	double wTs = 0;
	double gTs = 0;
	double eta = 0.01;
	int w_size = get_nr_variable();
	int max_num_linesearch = 20;
	double fold = *f;
	Xv(s, tmp);

	for (i=0;i<w_size;i++)
	{
		sTs += s[i] * s[i];
		wTs += s[i] * w[i];
		gTs += s[i] * g[i];
	}
	if(regularize_bias == 0)
	{
		// bias not used in calculating (w + \alpha s)^T (w + \alpha s)
		sTs -= s[w_size-1] * s[w_size-1];
		wTs -= s[w_size-1] * w[w_size-1];
	}

	int num_linesearch = 0;
	for(num_linesearch=0; num_linesearch < max_num_linesearch; num_linesearch++)
	{
		double loss = 0;
		for(i=0;i<l;i++)
		{
			double inner_product = tmp[i] * alpha + wx[i];
			loss += C_times_loss(i, inner_product);
		}
		*f = loss + (alpha * alpha * sTs + wTw) / 2.0 + alpha * wTs;
		if (*f - fold <= eta * alpha * gTs)
		{
			for (i=0;i<l;i++)
				wx[i] += alpha * tmp[i];
			break;
		}
		else
			alpha *= 0.5;
	}

	if (num_linesearch >= max_num_linesearch)
	{
		*f = fold;
		return 0;
	}
	else
		for (i=0;i<w_size;i++)
			w[i] += alpha * s[i];

	wTw += alpha * alpha * sTs + 2* alpha * wTs;
	return alpha;
}

void l2r_erm_fun::Xv(double *v, double *Xv)



( run in 0.649 second using v1.01-cache-2.11-cpan-524268b4103 )