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 )