コード例 #1
0
ファイル: ratio.c プロジェクト: rossetd0/QSopt_ex
void ILLratio_pI_test (lpinfo * lp,
											 int eindex,
											 int dir,
											 ratio_res * rs)
{
	int i = 0,
	  k = 0;
	int col,
	  ecol;
	int cbnd,
	  indx = 0;
	int tctr = 0;
	int *perm = lp->upd.perm;
	int *ix = lp->upd.ix;
	EGlpNum_t *pivtol = &(lp->tol->pivot_tol);
	EGlpNum_t *dftol = &(lp->tol->id_tol);
	 /*HHH*/ EGlpNum_t * t = lp->upd.t;
	EGlpNum_t t_i,
	  delta,
	  y_ij,
	  rcost,
	  nrcost,
	  ntmp;
	EGlpNum_t *x,
	 *l,
	 *u;
	 /*HHH*/ EGlpNumInitVar (t_i);
	EGlpNumInitVar (delta);
	EGlpNumInitVar (y_ij);
	EGlpNumInitVar (rcost);
	EGlpNumInitVar (nrcost);
	EGlpNumInitVar (ntmp);
	EGlpNumZero (t_i);
	EGlpNumZero (y_ij);
	EGlpNumZero (delta);
	rs->lindex = -1;
	EGlpNumZero (rs->tz);
	EGlpNumZero (rs->pivotval);
	rs->ratio_stat = RATIO_FAILED;
	rs->lvstat = -1;
	ecol = lp->nbaz[eindex];
	ILL_IFTRACE2 ("%s:%d:%d:%d:%d", __func__, eindex, dir, ecol,
								(VBOUNDED == lp->vtype[ecol]));
	if (lp->vtype[ecol] == VBOUNDED)
	{
		EGlpNumCopyDiff (t[0], lp->uz[ecol], lp->lz[ecol]);
		ix[0] = BBOUND;
		ILL_IFTRACE2 (":%d[%d](%la,%la,%la)\n", ix[tctr], tctr,
									EGlpNumToLf (t[tctr]), EGlpNumToLf (lp->uz[ecol]),
									EGlpNumToLf (lp->lz[ecol]));
		tctr++;
	}
	ILL_IFTRACE2 (":%d", lp->yjz.nzcnt);
	for (k = 0; k < lp->yjz.nzcnt; k++)
	{
		EGlpNumCopy (y_ij, lp->yjz.coef[k]);
		if (EGlpNumIsEqual (y_ij, zeroLpNum, *pivtol))
			continue;

		i = lp->yjz.indx[k];
		x = &(lp->xbz[i]);
		col = lp->baz[i];
		l = &(lp->lz[col]);
		u = &(lp->uz[col]);

		if ((dir == VINCREASE && EGlpNumIsLess (zeroLpNum, y_ij)) ||
				(dir == VDECREASE && EGlpNumIsLess (y_ij, zeroLpNum)))
		{
			if (EGlpNumIsLess (y_ij, zeroLpNum))
				EGlpNumSign (y_ij);
			ILL_IFTRACE2 (":%d", lp->bfeas[i]);
			if (lp->bfeas[i] > 0)
			{
				EGlpNumCopyDiffRatio (t[tctr], *x, *u, y_ij);
				ix[tctr] = 10 * k + BATOUPPER;
				ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr]));
				tctr++;
				if (EGlpNumIsNeqq (*l, NINFTY))
				{
					EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij);
					ix[tctr] = 10 * k + BATOLOWER;
					ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
												EGlpNumToLf (t[tctr]));
					tctr++;
				}
			}
			else if (lp->bfeas[i] == 0)
			{
				if (EGlpNumIsNeqq (*l, NINFTY))
				{
					EGlpNumCopyDiffRatio (t[tctr], *x, *l, y_ij);
					ix[tctr] = 10 * k + BATOLOWER;
					ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
												EGlpNumToLf (t[tctr]));
					tctr++;
				}
			}
		}
		else if ((dir == VINCREASE && EGlpNumIsLess (y_ij, zeroLpNum)) ||
						 (dir == VDECREASE && EGlpNumIsLess (zeroLpNum, y_ij)))
		{
			if (EGlpNumIsLess (y_ij, zeroLpNum))
				EGlpNumSign (y_ij);
			ILL_IFTRACE2 (":%d", lp->bfeas[i]);
			if (lp->bfeas[i] < 0)
			{
				EGlpNumCopyDiffRatio (t[tctr], *l, *x, y_ij);
				ix[tctr] = 10 * k + BBTOLOWER;
				ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr, EGlpNumToLf (t[tctr]));
				tctr++;
				if (EGlpNumIsNeqq (*u, INFTY))
				{
					EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij);
					ix[tctr] = 10 * k + BBTOUPPER;
					ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
												EGlpNumToLf (t[tctr]));
					tctr++;
				}
			}
			else if (lp->bfeas[i] == 0)
			{
				if (EGlpNumIsNeqq (*u, INFTY))
				{
					EGlpNumCopyDiffRatio (t[tctr], *u, *x, y_ij);
					ix[tctr] = 10 * k + BBTOUPPER;
					ILL_IFTRACE2 (":%d[%d](%la)\n", ix[tctr], tctr,
												EGlpNumToLf (t[tctr]));
					tctr++;
				}
			}
		}
	}
	if (tctr == 0)
	{
		rs->ratio_stat = RATIO_FAILED;
		ILL_CLEANUP;
	}

	for (i = 0; i < tctr; i++)
		perm[i] = i;
	ILLutil_EGlpNum_perm_quicksort (perm, t, tctr);

	EGlpNumZero (lp->upd.c_obj);
	EGlpNumCopy (rcost, lp->pIdz[eindex]);
	ILL_IFTRACE2 ("\n%s:%d:%lf", __func__, tctr, EGlpNumToLf (rcost));
	for (i = 0; i < tctr; i++)
	{
		EGlpNumCopy (t_i, t[perm[i]]);
		EGlpNumCopy (ntmp, t_i);
		EGlpNumSubTo (ntmp, delta);
		EGlpNumAddInnProdTo (lp->upd.c_obj, ntmp, rcost);
		EGlpNumCopy (delta, t_i);
		ILL_IFTRACE2 (":%d:%lf", perm[i], EGlpNumToLf (delta));
		 /*HHH*/ cbnd = ix[perm[i]] % 10;
		if (cbnd != BBOUND)
		{
			k = ix[perm[i]] / 10;
			EGlpNumCopy (y_ij, lp->yjz.coef[k]);
			indx = lp->yjz.indx[k];
			ILL_IFTRACE2 (":%d", indx);
		}

		switch (cbnd)
		{
		case BBOUND:
			rs->ratio_stat = RATIO_NOBCHANGE;
			EGlpNumCopy (rs->tz, t_i);
			if (dir != VINCREASE)
				EGlpNumSign (rs->tz);
			ILL_CLEANUP;

		case BATOLOWER:
		case BATOUPPER:
			EGlpNumAddTo (rcost, y_ij);
			break;
		case BBTOLOWER:
		case BBTOUPPER:
			EGlpNumSubTo (rcost, y_ij);
			break;
		}
		EGlpNumCopyNeg (nrcost, rcost);
		if ((dir == VINCREASE && EGlpNumIsLeq (nrcost, *dftol)) ||
				(dir == VDECREASE && EGlpNumIsLeq (rcost, *dftol)))
		{
			/* change 5 to -1 if t_i > 0 is required below */
			if (EGlpNumIsLess (t_i, zeroLpNum) && i > 5)
			{
				/* printf ("pIhell %.5f %d\n", t_i, i); */
				EGlpNumDivUiTo (t_i, 2);
				rs->ratio_stat = RATIO_NEGATIVE;
				EGlpNumZero (rs->tz);
				ILL_CLEANUP;
			}
			rs->lindex = indx;
			rs->ratio_stat = RATIO_BCHANGE;
			if (cbnd == BATOLOWER || cbnd == BBTOLOWER)
				rs->lvstat = STAT_LOWER;
			else
				rs->lvstat = STAT_UPPER;

			EGlpNumCopy (rs->pivotval, y_ij);
			EGlpNumCopy (rs->tz, t_i);
			if (dir != VINCREASE)
				EGlpNumSign (rs->tz);
			ILL_CLEANUP;
		}
	}

CLEANUP:
	ILLfct_update_counts (lp, CNT_PIPIV, 0, rs->pivotval);
	ILL_IFTRACE2 (":tctr %d:%d\n", tctr, rs->ratio_stat);
	lp->upd.tctr = tctr;
	lp->upd.i = i;
	EGlpNumCopy (lp->upd.tz, t_i);
	EGlpNumCopy (lp->upd.piv, rs->pivotval);
	if (dir == VDECREASE)
		EGlpNumSign (lp->upd.c_obj);
	if (rs->lindex != -1)
		lp->upd.fs = lp->bfeas[rs->lindex];
	EGlpNumClearVar (t_i);
	EGlpNumClearVar (delta);
	EGlpNumClearVar (y_ij);
	EGlpNumClearVar (rcost);
	EGlpNumClearVar (nrcost);
	EGlpNumClearVar (ntmp);
}
コード例 #2
0
ファイル: ratio.c プロジェクト: rossetd0/QSopt_ex
void ILLratio_dI_test (lpinfo * lp,
											 int lindex,
											 int lvstat,
											 ratio_res * rs)
{
	int j = 0,
	  k;
	int col;
	int cbnd,
	  indx;
	int tctr = 0;
	int *perm = lp->upd.perm;
	int *ix = lp->upd.ix;
	EGlpNum_t *t = lp->upd.t;
	EGlpNum_t *zAj,
	  x,
	  y,
	  t_j,
	  theta,
	  rcost,
	  delta;
	EGlpNum_t *pftol = &(lp->tol->ip_tol);
	EGlpNum_t *pivtol = &(lp->tol->pivot_tol);
	EGlpNumInitVar (x);
	EGlpNumInitVar (y);
	EGlpNumInitVar (t_j);
	EGlpNumInitVar (theta);
	EGlpNumInitVar (rcost);
	EGlpNumInitVar (delta);
	EGlpNumZero (delta);
	EGlpNumZero (t_j);
	EGlpNumZero (rs->tz);
	 /*HHH*/ rs->eindex = -1;
	rs->ratio_stat = RATIO_FAILED;
	EGlpNumZero (rs->pivotval);

	for (k = 0; k < lp->zA.nzcnt; k++)
	{
		zAj = &(lp->zA.coef[k]);
		if (EGlpNumIsEqual (*zAj, zeroLpNum, *pivtol))
			continue;

		EGlpNumCopy (t_j, INFTY);
		j = lp->zA.indx[k];
		col = lp->nbaz[j];

		if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
			continue;

		GET_XY_DRATIOTEST;

		if (EGlpNumIsLess (y, zeroLpNum))
		{
			if (lp->dfeas[j] != 0 && lp->vstat[col] != STAT_ZERO)
			{
				EGlpNumCopyFrac (t[tctr], x, y);
				ix[tctr] = 10 * k + BBTOLOWER;
				tctr++;
			}
			else if (lp->vstat[col] == STAT_ZERO)
			{
				if (lp->dfeas[j] < 0)
				{
					EGlpNumCopyFrac (t[tctr], x, y);
					ix[tctr] = 10 * k + BBTOLOWER;
					tctr++;
				}
				if (lp->dfeas[j] <= 0)
				{
					EGlpNumCopyFrac (t[tctr], x, y);
					ix[tctr] = 10 * k + BBTOUPPER;
					tctr++;
				}
			}
		}
		else
		{
			if (lp->dfeas[j] > 0)
			{
				if (lp->vstat[col] == STAT_ZERO)
				{
					EGlpNumCopyFrac (t[tctr], x, y);
					ix[tctr] = 10 * k + BATOUPPER;
					tctr++;
					EGlpNumCopyFrac (t[tctr], x, y);
					ix[tctr] = 10 * k + BATOLOWER;
					tctr++;
				}
			}
			else if (lp->dfeas[j] == 0)
			{
				EGlpNumCopyFrac (t[tctr], x, y);
				if (lp->vtype[col] == VBOUNDED)
					ix[tctr] = 10 * k + BSKIP;
				else
					ix[tctr] = 10 * k + BATOLOWER;
				tctr++;
			}
		}
	}

	if (tctr == 0)
	{
		rs->ratio_stat = RATIO_FAILED;
		ILL_CLEANUP;
	}

	for (j = 0; j < tctr; j++)
		perm[j] = j;
	ILLutil_EGlpNum_perm_quicksort (perm, t, tctr);

	EGlpNumZero (lp->upd.c_obj);
	EGlpNumCopy (rcost, lp->xbz[lindex]);
	if (lvstat == STAT_LOWER)
		EGlpNumSign (rcost);
	for (j = 0; j < tctr; j++)
	{
		cbnd = ix[perm[j]] % 10;
		if (cbnd == BSKIP)
			continue;

		EGlpNumCopy (t_j, t[perm[j]]);
		EGlpNumCopy (x, t_j);
		EGlpNumSubTo (x, delta);
		EGlpNumAddInnProdTo (lp->upd.c_obj, x, rcost);
		EGlpNumCopy (delta, t_j);
		k = ix[perm[j]] / 10;
		zAj = &(lp->zA.coef[k]);
		indx = lp->zA.indx[k];

		if (lp->vstat[lp->nbaz[indx]] == STAT_LOWER
				|| lp->vstat[lp->nbaz[indx]] == STAT_ZERO)
			EGlpNumCopyNeg (theta, *zAj);
		else
			EGlpNumCopy (theta, *zAj);

		if (lvstat == STAT_UPPER)
			EGlpNumSign (theta);

		switch (cbnd)
		{
		case BATOLOWER:
		case BATOUPPER:
			EGlpNumSubTo (rcost, theta);
			break;
		case BBTOLOWER:
		case BBTOUPPER:
			EGlpNumAddTo (rcost, theta);
			break;
		}
		if (EGlpNumIsLeq (rcost, *pftol))
		{
			/* if (t_j < 0.0) printf ("dIhell\n"); */
			rs->eindex = indx;
			EGlpNumCopy (rs->tz, t_j);
			EGlpNumCopy (rs->pivotval, *zAj);
			rs->ratio_stat = RATIO_BCHANGE;
			ILL_CLEANUP;
		}
	}

CLEANUP:
	ILLfct_update_counts (lp, CNT_DIPIV, 0, rs->pivotval);
	ILL_IFTRACE2 ("%s:tctr %d\n", __func__, tctr);
	lp->upd.tctr = tctr;
	lp->upd.i = j;
	EGlpNumCopyAbs (lp->upd.tz, t_j);
	EGlpNumCopy (lp->upd.piv, rs->pivotval);
	if (rs->eindex != -1)
		lp->upd.fs = lp->dfeas[rs->eindex];
	EGlpNumClearVar (x);
	EGlpNumClearVar (y);
	EGlpNumClearVar (t_j);
	EGlpNumClearVar (theta);
	EGlpNumClearVar (rcost);
	EGlpNumClearVar (delta);
}
コード例 #3
0
ファイル: eg_lpnum_ex.c プロジェクト: jonls/qsopt-ex
/** @brief Tester program for EGlpNum_t structure and functions
 * @return zero on success, non-zero otherwise 
 * @par Description:
 * Perform various tests on EGlpNum_t and their functions 
 * */
int main (int argc,
					char **argv)
{
	/* local variables */
	EGlpNum_t ntmp[4];
	double dtmp[5];
	char *strnum1,
	 *strnum2,
	 *strnum3;
	int rval=0;
	#ifdef HAVE_LIBGMP
	int n_char = 0;
	mpq_t qnum;
	#endif
	EGlpNumStart();
	/* set signal and limits */
	EGsigSet(rval,CLEANUP);
	EGsetLimits(3600.0,4294967295UL);
	#ifdef HAVE_LIBGMP
	EGlpNumSetPrecision (128);
	mpq_init (qnum);
	#endif
	EGlpNumInitVar (ntmp[0]);
	EGlpNumInitVar (ntmp[1]);
	EGlpNumInitVar (ntmp[2]);
	EGlpNumInitVar (ntmp[3]);
	/* the input should have at least two parameters, namelly the number where we
	 * will work on */
	if (argc < 3)
	{
		fprintf (stderr,
						 "usage: %s num1 num2\n\tWhere num1 and num2 are numbers in"
						 " the number format (either a/b or regular doubles)\n", argv[0]);
		exit (1);
	}

	/* we ask for two numbers and perform some basic operations and compare
	 * aganist double arithmetic */
	#ifdef HAVE_LIBGMP
	n_char = mpq_EGlpNumReadStrXc (qnum, argv[1]);
	#endif
	EGlpNumReadStr (ntmp[0], argv[1]);
	EGlpNumReadStr (ntmp[1], argv[2]);
	dtmp[0] = EGlpNumToLf (ntmp[0]);
	dtmp[1] = EGlpNumToLf (ntmp[1]);

	/* convert numbers */
	strnum1 = EGlpNumGetStr (ntmp[0]);
	strnum2 = EGlpNumGetStr (ntmp[1]);
	fprintf (stderr, "You Input %s (%lg) and %s (%lg)\n", strnum1, dtmp[0],
					 strnum2, dtmp[1]);
	#ifdef HAVE_LIBGMP
	strnum3 = mpq_EGlpNumGetStr (qnum);
	fprintf (stderr, "Your first number represented as exact rational is %s, "
					 "readed with %d chars\n", strnum3, n_char);
	free (strnum3);
	mpq_EGlpNumSet (qnum, dtmp[0]);
	strnum3 = mpq_EGlpNumGetStr (qnum);
	fprintf (stderr, "Your first number represented as continuous fraction "
					 "is %s, readed with %d chars\n", strnum3, n_char);
	free (strnum3);
	#endif

	/* internal constants */
	strnum3 = EGlpNumGetStr (oneLpNum);
	fprintf (stderr, "1.0 = %s\n", strnum3);
	EGfree (strnum3);
	strnum3 = EGlpNumGetStr (zeroLpNum);
	fprintf (stderr, "0.0 = %s\n", strnum3);
	EGfree (strnum3);
	strnum3 = EGlpNumGetStr (epsLpNum);
	fprintf (stderr, "eps = %s\n", strnum3);
	EGfree (strnum3);
	strnum3 = EGlpNumGetStr (MaxLpNum);
	fprintf (stderr, "Max = %s\n", strnum3);
	EGfree (strnum3);
	strnum3 = EGlpNumGetStr (MinLpNum);
	fprintf (stderr, "Min = %s\n", strnum3);
	EGfree (strnum3);

	/* copying functions */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = %s (%lg)\n", strnum3, strnum1, dtmp[0]);
	EGfree (strnum3);
	EGlpNumCopyDiff (ntmp[2], ntmp[0], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = %s - %s (%lg)\n", strnum3, strnum1, strnum2,
					 dtmp[0] - dtmp[1]);
	EGfree (strnum3);
	EGlpNumCopyDiffRatio (ntmp[2], ntmp[0], ntmp[1], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = (%s  - %s)/%s (%lg)\n", strnum3, strnum1, strnum2,
					 strnum1, (dtmp[0] - dtmp[1]) / dtmp[0]);
	EGfree (strnum3);
	EGlpNumCopySum (ntmp[2], ntmp[0], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = %s + %s (%lg)\n", strnum3, strnum1, strnum2,
					 dtmp[0] + dtmp[1]);
	EGfree (strnum3);
	EGlpNumCopySqrOver (ntmp[2], ntmp[1], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = %s^2/%s (%lg)\n", strnum3, strnum2, strnum1,
					 dtmp[1] * dtmp[1] / dtmp[0]);
	EGfree (strnum3);
	EGlpNumCopyAbs (ntmp[2], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = |%s| (%lg)\n", strnum3, strnum1, fabs (dtmp[0]));
	EGfree (strnum3);
	EGlpNumCopyNeg (ntmp[2], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = -1*%s (%lg)\n", strnum3, strnum1, -dtmp[0]);
	EGfree (strnum3);
	EGlpNumCopyFrac (ntmp[2], ntmp[1], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s = %s/%s (%lg)\n", strnum3, strnum2, strnum1,
					 dtmp[1] / dtmp[0]);
	EGfree (strnum3);

	/* add */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumAddTo (ntmp[2], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s + %s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 dtmp[0] + dtmp[1]);
	EGfree (strnum3);
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumAddUiTo (ntmp[2], 0xffU);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s + %u = %s (%lg)\n", strnum1, 0xffU, strnum3,
					 dtmp[0] + 0xffU);
	EGfree (strnum3);

	/* substract */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumSubTo (ntmp[2], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s - %s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 dtmp[0] - dtmp[1]);
	EGfree (strnum3);
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumSubUiTo (ntmp[2], 0xffU);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s - %u = %s (%lg)\n", strnum1, 0xffU, strnum3,
					 dtmp[0] - 0xffU);
	EGfree (strnum3);

	/* multiply */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumMultTo (ntmp[2], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s * %s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 dtmp[0] * dtmp[1]);
	EGfree (strnum3);

	/* multiply unsigned */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumMultUiTo (ntmp[2], 13);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s * 13 = %s (%lg)\n", strnum1, strnum3, dtmp[0] * 13);
	EGfree (strnum3);

	/* inverse */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumInv (ntmp[2]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "1/%s = %s (%lg)\n", strnum1, strnum3, 1.0 / dtmp[0]);
	EGfree (strnum3);

	/* floor and ceil */
	EGlpNumFloor (ntmp[2], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "floor(%s) = %s (%lg)\n", strnum1, strnum3, floor (dtmp[0]));
	EGfree (strnum3);
	EGlpNumCeil (ntmp[2], ntmp[0]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "ceil(%s) = %s (%lg)\n", strnum1, strnum3, ceil (dtmp[0]));
	EGfree (strnum3);

	/* negative and inner products */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumSign (ntmp[2]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "-(%s) = %s (%lg)\n", strnum1, strnum3, -dtmp[0]);
	EGfree (strnum3);
	EGlpNumOne (ntmp[2]);
	EGlpNumAddInnProdTo (ntmp[2], ntmp[0], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "1.0 + %s*%s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 1.0 + dtmp[1] * dtmp[0]);
	EGfree (strnum3);
	EGlpNumOne (ntmp[2]);
	EGlpNumSubInnProdTo (ntmp[2], ntmp[0], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "1.0 - %s*%s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 1.0 - dtmp[1] * dtmp[0]);
	EGfree (strnum3);

	/* divide */
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumDivTo (ntmp[2], ntmp[1]);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s / %s = %s (%lg)\n", strnum1, strnum2, strnum3,
					 dtmp[0] / dtmp[1]);
	EGfree (strnum3);
	EGlpNumCopy (ntmp[2], ntmp[0]);
	EGlpNumDivUiTo (ntmp[2], 0xffU);
	strnum3 = EGlpNumGetStr (ntmp[2]);
	fprintf (stderr, "%s / %u = %s (%lg)\n", strnum1, 0xffU, strnum3,
					 dtmp[0] / 0xffU);
	EGfree (strnum3);
	EGfree (strnum1);
	EGfree (strnum2);

#ifdef HAVE_LIBGMP
	/* test transformation to rationals */
	{
		mpq_t n1, n2;
		mpf_t f1, f2;
		mpq_init (n1);
		mpq_init (n2);
		mpf_init (f1);
		mpf_init (f2);
		mpf_EGlpNumSet(f1,EGlpNumToLf(ntmp[0]));
		mpf_EGlpNumSet(f2,EGlpNumToLf(ntmp[1]));
		mpq_EGlpNumSet_mpf (n1, f1);
		mpq_EGlpNumSet_mpf (n2, f2);
		strnum1 = mpq_EGlpNumGetStr (n1);
		strnum2 = mpq_EGlpNumGetStr (n2);
		fprintf (stderr, "Your input in rational was:\n\t(%10.7lf) %s\n\t(%10.7lf)"
				" %s\n", EGlpNumToLf (ntmp[0]), strnum1, EGlpNumToLf (ntmp[1]),
				strnum2);
		EGfree (strnum1);
		EGfree (strnum2);

		/* test natural exponentiation */
		mpf_EGlpNumEpow (f1, -38.81624211135693732736499880);
		mpf_set_ui (f2, (unsigned long)1);
		mpf_div_2exp (f2, f2, (unsigned long)56);
		strnum1 = mpf_EGlpNumGetStr (f1);
		strnum2 = mpf_EGlpNumGetStr (f2);
		fprintf (stderr, "2^-56 = %s ~ %s\n", strnum1, strnum2);
		EGfree (strnum1);
		EGfree (strnum2);
		mpq_clear (n1);
		mpq_clear (n2);
		mpf_clear (f1);
		mpf_clear (f2);
	}
#endif

	/* ending */
	CLEANUP:
	EGlpNumClearVar (ntmp[0]);
	EGlpNumClearVar (ntmp[1]);
	EGlpNumClearVar (ntmp[2]);
	EGlpNumClearVar (ntmp[3]);
	#ifdef HAVE_LIBGMP
	mpq_clear (qnum);
	#endif
	EGlpNumClear();
	return 0;
}