/*Translated by FOR_C, v3.4.2 (-), on 07/09/115 at 08:33:11 */
/*FOR_C Options SET: ftn=u io=c no=p op=aimnv pf=,p_dmlc01 s=dbov str=l x=f - prototypes */
#include <math.h>
#include "fcrt.h"
#include <stdio.h>
#include <stdlib.h>
#include "p_dmlc01.h"
#include "drdmlc01.h"
/*     program DRDMLC01
 *>> 2001-05-22 DRDMLC01 Krogh Minor change for making .f90 version.
 *>> 1996-07-08 DRDMLC01 Krogh  Minor format change for C conversion.
 *>> 1994-11-02 DRDMLC01 Krogh  Changes to use M77CON
 *>> 1994-09-13 DRDMLC01 CLL
 *>> 1992-05-13 CLL
 *>> 1992-04-15 CLL
 *>> 1992-01-21 CLL
 *>> 1991-06-10 CLL
 *>> 1992-01-16 CLL
 *>> 1990-07-12 CLL
 *     Demo driver for DMLC01.  Also uses DCKDER to check gradient.
 *     Minimization with linear constraints.
 *     The constraints are Ax .le. b with equality required in the first
 *     two rows.
 *     ------------------------------------------------------------------
 *--D replaces "?": DR?MLC01, ?MLC01, ?XLOGX, ?CKDER
 *     ------------------------------------------------------------------ */
		/* PARAMETER translations */
#define	LIW	(4 + MMAX + 2*NMAX)
#define	LW	(3 + MMAX + NMAX*(16 + NMAX))
#define	MMAX	3
#define	NMAX	4
		/* end of PARAMETER translations */
 
 
int main( )
{
	LOGICAL32 haveg;
	long int i, imax, iw[LIW], j, jmax, mode, _i, _r;
	double fval[1], gdummy[NMAX], grad[NMAX], test[NMAX], tstmax,
	 w[LW];
	static double a[NMAX][MMAX], b[MMAX], x[NMAX], xl[NMAX], xu[NMAX];
	static long m = 3;
	static long meq = 2;
	static long n = 4;
	static double acc = 0.0e0;
	static long iprint = 3;
	static long mxeval = 0;
	static int _aini = 1;
		/* OFFSET Vectors w/subscript range: 1 to dimension */
	double *const B = &b[0] - 1;
	double *const Fval = &fval[0] - 1;
	double *const Gdummy = &gdummy[0] - 1;
	double *const Grad = &grad[0] - 1;
	long *const Iw = &iw[0] - 1;
	double *const Test = &test[0] - 1;
	double *const W = &w[0] - 1;
	double *const X = &x[0] - 1;
	double *const Xl = &xl[0] - 1;
	double *const Xu = &xu[0] - 1;
		/* end of OFFSET VECTORS */
	if( _aini ){ /* Do 1 TIME INITIALIZATIONS! */
		{ static double _itmp0[] = {1.0e0,1.0e0,1.0e0,1.0e0,1.0e0,
		 -1.0e0,0.0e0,0.0e0,0.0e0,-1.0e0,1.0e0,0.0e0};
		for (i = 1, _r = 0; i <= 3; i++)
		{
			for (j = 1; j <= 4; j++)
			{
				a[j - 1][i - 1] = _itmp0[_r++];
				}
			}
		}
		{ static double _itmp1[] = {1.0e0,0.25e0,-0.1e0};
		for (i = 1, _r = 0; i <= 3; i++)
		{
			B[i] = _itmp1[_r++];
			}
		}
		for (j = 1; j <= 4; j++)
		{
			Xl[j] = 1.0e-6;
			}
		for (j = 1; j <= 4; j++)
		{
			Xu[j] = 1.0e0;
			}
		{ static double _itmp2[] = {0.7e0,0.6e0,0.5e0,0.4e0};
		for (j = 1, _r = 0; j <= 4; j++)
		{
			X[j] = _itmp2[_r++];
			}
		}
		_aini = 0;
	}
 
	/*     ------------------------------------------------------------------ */
	printf("Program DRDMLC01..  Demo driver for DMLC01.  Also uses DCKDER.\n");
 
	/*                    Using DCKDER to check the gradient calculation.
	 * */
	mode = 1;
	dxlogx( n, x, &Fval[1], grad, &haveg );
L_10:
	;
	dckder( &mode, 1, n, x, fval, grad, 1, test, &imax, &jmax, &tstmax );
	dxlogx( n, x, &Fval[1], gdummy, &haveg );
	if (mode == 2)
		goto L_10;
	printf("\n Using DCKDER to check the gradient calculation.\n");
	printf("\n           X(J) =");
	for (j = 1; j <= n; j++)
	{
		printf("%11.3g", X[j]);
	}
	printf("\n");
	printf("           FVAL =%11.3g\n", Fval[1]);
	printf("       Gradient =");
	for (j = 1; j <= n; j++)
	{
		printf("%11.3g", Grad[j]);
	}
	printf("\n");
	printf("         TEST() =");
	for (j = 1; j <= n; j++)
	{
		printf("%11.3g", Test[j]);
	}
	printf("\n");
	printf("           JMAX =%3ld,          TSTMAX =%11.3g\n", jmax, tstmax);
 
	/*                Using DMLC01 to solve the minimization problem.
	 * */
	printf("\n Using DMLC01 to solve the minimization problem.\n");
	dmlc01( dxlogx, n, m, meq, (double*)a, MMAX, b, xl, xu, x, acc,
	 iprint, mxeval, iw, LIW, w, LW );
	exit(0);
} /* end of function */
/*     ================================================================== */
void /*FUNCTION*/ dxlogx(
long n,
double x[],
double *f,
double g[],
LOGICAL32 *haveg)
{
	long int i;
		/* OFFSET Vectors w/subscript range: 1 to dimension */
	double *const G = &g[0] - 1;
	double *const X = &x[0] - 1;
		/* end of OFFSET VECTORS */
 
	/*     ------------------------------------------------------------------ */
	/*     ------------------------------------------------------------------ */
	*haveg = TRUE;
	*f = 0.0e0;
	for (i = 1; i <= n; i++)
	{
		*f += X[i]*log( X[i] );
		G[i] = 1.0e0 + log( X[i] );
	}
	return;
} /* end of function */