<?xml version='1.0'?>
<html xmlns='http://www.w3.org/1999/xhtml'
      xmlns:math='http://www.w3.org/1998/Math/MathML'
>
<head>
<title>Hessian of Lagrangian and  ADFun Default Constructor: Example and Test</title>
<meta name="description" id="description" content="Hessian of Lagrangian and  ADFun Default Constructor: Example and Test"/>
<meta name="keywords" id="keywords" content=" Heslagrangian example Hessian of Lagrangian test Adfun default constructor "/>
<style type='text/css'>
body { color : black }
body { background-color : white }
A:link { color : blue }
A:visited { color : purple }
A:active { color : purple }
</style>
<script type='text/javascript' language='JavaScript' src='_hes_lagrangian.cpp_xml.js'>
</script>
</head>
<body>
<table><tr>
<td>
<a href="http://www.coin-or.org/CppAD/" target="_top"><img border="0" src="_image.gif"/></a>
</td>
<td><a href="hessian.cpp.xml" target="_top">Prev</a>
</td><td><a href="fortwo.xml" target="_top">Next</a>
</td><td>
<select onchange='choose_across0(this)'>
<option>Index-&gt;</option>
<option>contents</option>
<option>reference</option>
<option>index</option>
<option>search</option>
<option>external</option>
</select>
</td>
<td>
<select onchange='choose_up0(this)'>
<option>Up-&gt;</option>
<option>CppAD</option>
<option>ADFun</option>
<option>Drivers</option>
<option>Hessian</option>
<option>hes_lagrangian.cpp</option>
</select>
</td>
<td>
<select onchange='choose_down3(this)'>
<option>ADFun-&gt;</option>
<option>Independent</option>
<option>FunConstruct</option>
<option>Dependent</option>
<option>abort_recording</option>
<option>seq_property</option>
<option>FunEval</option>
<option>Drivers</option>
<option>FunCheck</option>
<option>optimize</option>
<option>check_for_nan</option>
</select>
</td>
<td>
<select onchange='choose_down2(this)'>
<option>Drivers-&gt;</option>
<option>Jacobian</option>
<option>ForOne</option>
<option>RevOne</option>
<option>Hessian</option>
<option>ForTwo</option>
<option>RevTwo</option>
<option>sparse_jacobian</option>
<option>sparse_hessian</option>
</select>
</td>
<td>
<select onchange='choose_down1(this)'>
<option>Hessian-&gt;</option>
<option>hessian.cpp</option>
<option>hes_lagrangian.cpp</option>
</select>
</td>
<td>hes_lagrangian.cpp</td>
<td>Headings</td>
</tr></table><br/>




<center><b><big><big>Hessian of Lagrangian and  ADFun Default Constructor: Example and Test</big></big></b></center>
<code><font color="blue"><pre style='display:inline'> 

# include &lt;cppad/cppad.hpp&gt;
# include &lt;cassert&gt;

namespace {
	CppAD::<a href="ad.xml" target="_top">AD</a>&lt;double&gt; Lagragian(
		const CppAD::vector&lt; CppAD::<a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt; &amp;xyz )
	{	using CppAD::AD;
		assert( xyz.size() == 6 );

		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; x0 = xyz[0];
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; x1 = xyz[1];
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; x2 = xyz[2];
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; y0 = xyz[3];
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; y1 = xyz[4];
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; z  = xyz[5];
	
		// compute objective function
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; f = x0 * x0;
		// compute constraint functions
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; g0 = 1. + 2.*x1 + 3.*x2;
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; g1 = log( x0 * x2 );
		// compute the Lagragian
		<a href="ad.xml" target="_top">AD</a>&lt;double&gt; L = y0 * g0 + y1 * g1 + z * f;
	
		return L;
	
	}
	CppAD::vector&lt; CppAD::<a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt; fg(
		const CppAD::vector&lt; CppAD::<a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt; &amp;x )
	{	using CppAD::AD;
		using CppAD::vector;
		assert( x.size() == 3 );

		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt; fg(3);
		fg[0] = x[0] * x[0];
		fg[1] = 1. + 2. * x[1] + 3. * x[2];
		fg[2] = log( x[0] * x[2] );

		return fg;
	}
	bool CheckHessian(
	CppAD::vector&lt;double&gt; H , 
	double x0, double x1, double x2, double y0, double y1, double z )
	{	using CppAD::NearEqual;
		bool ok  = true;
		size_t n = 3;
		assert( H.size() == n * n );
		/*
		L   =    z*x0*x0 + y0*(1 + 2*x1 + 3*x2) + y1*log(x0*x2)

		L_0 = 2 * z * x0 + y1 / x0
		L_1 = y0 * 2 
		L_2 = y0 * 3 + y1 / x2 
		*/
		// L_00 = 2 * z - y1 / ( x0 * x0 )
		double check = 2. * z - y1 / (x0 * x0);
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[0 * n + 0], check, 1e-10, 1e-10); 
		// L_01 = L_10 = 0
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[0 * n + 1], 0., 1e-10, 1e-10);
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[1 * n + 0], 0., 1e-10, 1e-10);
		// L_02 = L_20 = 0
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[0 * n + 2], 0., 1e-10, 1e-10);
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[2 * n + 0], 0., 1e-10, 1e-10);
		// L_11 = 0
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[1 * n + 1], 0., 1e-10, 1e-10);
		// L_12 = L_21 = 0
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[1 * n + 2], 0., 1e-10, 1e-10);
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[2 * n + 1], 0., 1e-10, 1e-10);
		// L_22 = - y1 / (x2 * x2)
		check = - y1 / (x2 * x2);
		ok &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(H[2 * n + 2], check, 1e-10, 1e-10);

		return ok;
	}
	bool UseL()
	{	using CppAD::AD;
		using CppAD::vector;

		// double values corresponding to XYZ vector
		double x0(.5), x1(1e3), x2(1), y0(2.), y1(3.), z(4.);

		// domain space vector
		size_t n = 3;
		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt;  XYZ(n);
		XYZ[0] = x0;
		XYZ[1] = x1;
		XYZ[2] = x2;

		// declare X as independent variable vector and start recording
		CppAD::<a href="independent.xml" target="_top">Independent</a>(XYZ);

		// add the Lagragian multipliers to XYZ
		// (note that this modifies the vector XYZ)
		XYZ.push_back(y0);
		XYZ.push_back(y1);
		XYZ.push_back(z);

		// range space vector
		size_t m = 1;
		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt;  L(m);
		L[0] = Lagragian(XYZ);

		// create K: X -&gt; L and stop tape recording
		// We cannot use the ADFun sequence constructor because XYZ has
		// changed between the call to Independent and here.
		CppAD::<a href="funconstruct.xml" target="_top">ADFun</a>&lt;double&gt; K;
		K.Dependent(L);

		// Operation sequence corresponding to K does depends on 
		// value of y0, y1, and z. Must redo calculations above when 
		// y0, y1, or z changes.

		// declare independent variable vector and Hessian
		vector&lt;double&gt; x(n);
		vector&lt;double&gt; H( n * n );

		// point at which we are computing the Hessian
		// (must redo calculations below each time x changes)
		x[0] = x0;
		x[1] = x1;
		x[2] = x2;
		H = K.Hessian(x, 0);

		// check this Hessian calculation
		return CheckHessian(H, x0, x1, x2, y0, y1, z); 
	}
	bool Usefg()
	{	using CppAD::AD;
		using CppAD::vector;

		// parameters defining problem
		double x0(.5), x1(1e3), x2(1), y0(2.), y1(3.), z(4.);

		// domain space vector
		size_t n = 3;
		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt;  X(n);
		X[0] = x0;
		X[1] = x1;
		X[2] = x2;

		// declare X as independent variable vector and start recording
		CppAD::<a href="independent.xml" target="_top">Independent</a>(X);

		// range space vector
		size_t m = 3;
		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt;  FG(m);
		FG = fg(X);

		// create K: X -&gt; FG and stop tape recording
		CppAD::<a href="funconstruct.xml" target="_top">ADFun</a>&lt;double&gt; K;
		K.Dependent(FG);

		// Operation sequence corresponding to K does not depend on 
		// value of x0, x1, x2, y0, y1, or z. 

		// forward and reverse mode arguments and results 
		vector&lt;double&gt; x(n);
		vector&lt;double&gt; H( n * n );
		vector&lt;double&gt;  dx(n);
		vector&lt;double&gt;   w(m);
		vector&lt;double&gt;  dw(2*n);

		// compute Hessian at this value of x
		// (must redo calculations below each time x changes)
		x[0] = x0;
		x[1] = x1;
		x[2] = x2;
		K.<a href="forward.xml" target="_top">Forward</a>(0, x);

		// set weights to Lagrange multiplier values
		// (must redo calculations below each time y0, y1, or z changes)
		w[0] = z;
		w[1] = y0;
		w[2] = y1;

		// initialize dx as zero
		size_t i, j;
		for(i = 0; i &lt; n; i++)
			dx[i] = 0.;
		// loop over components of x
		for(i = 0; i &lt; n; i++)
		{	dx[i] = 1.;             // dx is i-th elementary vector
			K.<a href="forward.xml" target="_top">Forward</a>(1, dx);       // partial w.r.t dx
			dw = K.<a href="reverse.xml" target="_top">Reverse</a>(2, w);   // deritavtive of partial
			for(j = 0; j &lt; n; j++)
				H[ i * n + j ] = dw[ j * 2 + 1 ];
			dx[i] = 0.;             // dx is zero vector
		}

		// check this Hessian calculation
		return CheckHessian(H, x0, x1, x2, y0, y1, z); 
	}
}

bool HesLagrangian(void)
{	bool ok = true;

	// UseL is simpler, but must retape every time that y of z changes
	ok     &amp;= UseL();

	// Usefg does not need to retape unless operation sequence changes
	ok     &amp;= Usefg();
	return ok;
}

</pre>

</font></code>


<hr/>Input File: example/hes_lagrangian.cpp

</body>
</html>
