Algorithm-LBFGS

 view release on metacpan or  search on metacpan

lbfgs.c  view on Meta::CPAN

	lbfgsfloatval_t stx, fx, dgx;
	lbfgsfloatval_t sty, fy, dgy;
	lbfgsfloatval_t fxm, dgxm, fym, dgym, fm, dgm;
	lbfgsfloatval_t finit, ftest1, dginit, dgtest;
	lbfgsfloatval_t width, prev_width;
	lbfgsfloatval_t stmin, stmax;

	/* Check the input parameters for errors. */
	if (*stp <= 0.) {
		return LBFGSERR_INVALIDPARAMETERS;
	}

	/* Compute the initial gradient in the search direction. */
	if (param->orthantwise_c != 0.) {
		/* Use psuedo-gradients for orthant-wise updates. */
		dginit = 0.;
		for (i = 0;i < n;++i) {
			/* Notice that:
				(-s[i] < 0)  <==>  (g[i] < -param->orthantwise_c)
				(-s[i] > 0)  <==>  (param->orthantwise_c < g[i])
			   as the result of the lbfgs() function for orthant-wise updates.
			 */
			if (s[i] != 0.) {
				if (x[i] < 0.) {
					/* Differentiable. */
					dginit += s[i] * (g[i] - param->orthantwise_c);
				} else if (0. < x[i]) {
					/* Differentiable. */
					dginit += s[i] * (g[i] + param->orthantwise_c);
				} else if (s[i] < 0.) {
					/* Take the left partial derivative. */
					dginit += s[i] * (g[i] - param->orthantwise_c);
				} else if (0. < s[i]) {
					/* Take the right partial derivative. */
					dginit += s[i] * (g[i] + param->orthantwise_c);
				}
			}
		}
	} else {
		vecdot(&dginit, g, s, n);
	}

	/* Make sure that s points to a descent direction. */
	if (0 < dginit) {
		return LBFGSERR_INCREASEGRADIENT;
	}

	/* Initialize local variables. */
	brackt = 0;
	stage1 = 1;
	finit = *f;
	dgtest = param->ftol * dginit;
	width = param->max_step - param->min_step;
	prev_width = 2.0 * width;

	/* Copy the value of x to the work area. */
	veccpy(wa, x, n);

	/*
		The variables stx, fx, dgx contain the values of the step,
		function, and directional derivative at the best step.
		The variables sty, fy, dgy contain the value of the step,
		function, and derivative at the other endpoint of
		the interval of uncertainty.
		The variables stp, f, dg contain the values of the step,
		function, and derivative at the current step.
	*/
	stx = sty = 0.;
	fx = fy = finit;
	dgx = dgy = dginit;

	for (;;) {
		/*
			Set the minimum and maximum steps to correspond to the
			present interval of uncertainty.
		 */
		if (brackt) {
			stmin = min2(stx, sty);
			stmax = max2(stx, sty);
		} else {
			stmin = stx;
			stmax = *stp + 4.0 * (*stp - stx);
		}

		/* Clip the step in the range of [stpmin, stpmax]. */
		if (*stp < param->min_step) *stp = param->min_step;
		if (param->max_step < *stp) *stp = param->max_step;

		/*
			If an unusual termination is to occur then let
			stp be the lowest point obtained so far.
		 */
		if ((brackt && ((*stp <= stmin || stmax <= *stp) || param->max_linesearch <= count + 1 || uinfo != 0)) || (brackt && (stmax - stmin <= param->xtol * stmax))) {
			*stp = stx;
		}

		/*
			Compute the current value of x:
				x <- x + (*stp) * s.
		 */
		veccpy(x, wa, n);
		vecadd(x, s, *stp, n);

		if (param->orthantwise_c != 0.) {
			/* The current point is projected onto the orthant of the previous one. */
			for (i = 0;i < n;++i) {
				if (x[i] * wa[i] < 0.) {
					x[i] = 0.;
				}
			}
		}

		/* Evaluate the function and gradient values. */
		*f = proc_evaluate(instance, x, g, n, *stp);
		if (0. < param->orthantwise_c) {
			/* Compute L1-regularization factor and add it to the object value. */
			norm = 0.;
			for (i = 0;i < n;++i) {
				norm += fabs(x[i]);
			}
			*f += norm * param->orthantwise_c;



( run in 0.476 second using v1.01-cache-2.11-cpan-e1769b4cff6 )