Codebase list cppad / upstream/2015.00.00.7 doc / interface2c.cpp.xml
upstream/2015.00.00.7

Tree @upstream/2015.00.00.7 (Download .tar.gz)

interface2c.cpp.xml @upstream/2015.00.00.7raw · history · blame

<?xml version='1.0'?>
<html xmlns='http://www.w3.org/1999/xhtml'
      xmlns:math='http://www.w3.org/1998/Math/MathML'
>
<head>
<title>Interfacing to C: Example and Test</title>
<meta http-equiv='Content-Type' content='text/html' charset='utf-8'/>
<meta name="description" id="description" content="Interfacing to C: Example and Test"/>
<meta name="keywords" id="keywords" content=" interfacing to c: example and test C interface difference central "/>
<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='_interface2c.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="hes_lu_det.cpp.xml" target="_top">Prev</a>
</td><td><a href="jac_minor_det.cpp.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>Example</option>
<option>General</option>
<option>interface2c.cpp</option>
</select>
</td>
<td>
<select onchange='choose_down3(this)'>
<option>CppAD-&gt;</option>
<option>Install</option>
<option>Introduction</option>
<option>AD</option>
<option>ADFun</option>
<option>preprocessor</option>
<option>multi_thread</option>
<option>library</option>
<option>ipopt_solve</option>
<option>Example</option>
<option>speed</option>
<option>Appendix</option>
</select>
</td>
<td>
<select onchange='choose_down2(this)'>
<option>Example-&gt;</option>
<option>General</option>
<option>ExampleUtility</option>
<option>ListAllExamples</option>
<option>testvector</option>
</select>
</td>
<td>
<select onchange='choose_down1(this)'>
<option>General-&gt;</option>
<option>ad_fun.cpp</option>
<option>ad_in_c.cpp</option>
<option>conj_grad.cpp</option>
<option>cppad_eigen.hpp</option>
<option>hes_minor_det.cpp</option>
<option>hes_lu_det.cpp</option>
<option>interface2c.cpp</option>
<option>jac_minor_det.cpp</option>
<option>jac_lu_det.cpp</option>
<option>mul_level</option>
<option>ode_stiff.cpp</option>
<option>mul_level_ode.cpp</option>
<option>mul_level_adolc_ode.cpp</option>
<option>ode_taylor.cpp</option>
<option>stack_machine.cpp</option>
</select>
</td>
<td>interface2c.cpp</td>
<td>Headings</td>
</tr></table><br/>



<center><b><big><big>Interfacing to C: Example and Test</big></big></b></center>
<code><font color="blue"><pre style='display:inline'> 
# include &lt;cppad/cppad.hpp&gt;  // CppAD utilities
# include &lt;cassert&gt;        // assert macro

namespace { // Begin empty namespace
/*
Compute the value of a sum of Gaussians defined by a and evaluated at x
	y = sum_{i=1}^n a[3*i] exp( (x - a[3*i+1])^2 / a[3*i+2])^2 )
where the floating point type is a template parameter
*/
template &lt;class Float&gt;
Float sumGauss(const Float &amp;x, const CppAD::vector&lt;Float&gt; &amp;a)   
{ 
	// number of components in a
	size_t na = a.size();

	// number of Gaussians
	size_t n = na / 3;

	// check the restricitons on na 
	assert( na == n * 3 );

	// declare temporaries used inside of loop
	Float ex, arg;

	// initialize sum
  	Float y = 0.; 

	// loop with respect to Gaussians
	size_t i;
	for(i = 0; i &lt; n; i++)
	{
		arg =   (x - a[3*i+1]) / a[3*i+2]; 
		ex  =   exp(-arg * arg); 
		y  +=   a[3*i] * ex; 
	} 
	return y;
}
/*
Create a C function interface that computes both
	y = sum_{i=1}^n a[3*i] exp( (x - a[3*i+1])^2 / a[3*i+2])^2 )
and its derivative with respect to the parameter vector a.
*/
extern &quot;C&quot;
void sumGauss(float x, float a[], float *y, float dyda[], size_t na)   
{	// Note that any simple vector could replace CppAD::vector; 
	// for example, std::vector, std::valarray

	// check the restrictions on na
	assert( na % 3 == 0 );  // mod(na, 3) = 0

	// use the shorthand ADfloat for the type CppAD::<a href="ad.xml" target="_top">AD</a>&lt;float&gt;
	typedef CppAD::<a href="ad.xml" target="_top">AD</a>&lt;float&gt; ADfloat;

	// vector for indpendent variables
	CppAD::vector&lt;ADfloat&gt; A(na);      // used with template function above
	CppAD::vector&lt;float&gt;   acopy(na);  // used for derivative calculations

	// vector for the dependent variables (there is only one)
	CppAD::vector&lt;ADfloat&gt; Y(1); 

	// copy the independent variables from C vector to CppAD vectors
	size_t i;
	for(i = 0; i &lt; na; i++)
 		A[i] = acopy[i] = a[i];

	// declare that A is the independent variable vector
	CppAD::<a href="independent.xml" target="_top">Independent</a>(A);

	// value of x as an ADfloat object
	ADfloat X = x;

	// Evaluate template version of sumGauss with ADfloat as the template 
	// parameter. Set the independent variable to the resulting value
	Y[0] = sumGauss(X, A); 

	// create the AD function object F : A -&gt; Y
	CppAD::<a href="funconstruct.xml" target="_top">ADFun</a>&lt;float&gt; F(A, Y);

	// use Value to convert Y[0] to float and return y = F(a)  
	*y = CppAD::Value(Y[0]);

	// evaluate the derivative F'(a)
	CppAD::vector&lt;float&gt; J(na);
	J = F.<a href="jacobian.xml" target="_top">Jacobian</a>(acopy);

	// return the value of dyda = F'(a) as a C vector
	for(i = 0; i &lt; na; i++)
		dyda[i] = J[i];

	return;
}
/*
Link CppAD::NearEqual so do not have to use namespace notation in Interface2C
*/
bool <a href="nearequal.xml" target="_top">NearEqual</a>(float x, float y, float r, float a)
{	return CppAD::<a href="nearequal.xml" target="_top">NearEqual</a>(x, y, r, a);
}

} // End empty namespace

bool Interface2C(void)
{	// This routine is intentionally coded as if it were a C routine
	// except for the fact that it uses the predefined type bool.
	bool ok = true; 

	// declare variables
	float x, a[6], y, dyda[6], tmp[6];
	size_t na, i;

	// number of parameters (3 for each Gaussian)
	na = 6;

	// number of Gaussians: n  = na / 3;

	// value of x
	x = 1.;

	// value of the parameter vector a
	for(i = 0; i &lt; na; i++)
		a[i] = (float) (i+1);

	// evaulate function and derivative
	sumGauss(x, a, &amp;y, dyda, na);

	// compare dyda to central difference approximation for deriative
	for(i = 0; i &lt; na; i++)
	{	// local variables
		float small, ai, yp, ym, dy_da;

		// We assume that the type float has at least 7 digits of 
		// precision, so we choose small to be about pow(10., -7./2.).
		small  = (float) 3e-4;

		// value of this component of a
		ai    = a[i];

		// evaluate F( a + small * ei )
		a[i]  = ai + small;
		sumGauss(x, a, &amp;yp, tmp, na);

		// evaluate F( a - small * ei )
		a[i]  = ai - small;
		sumGauss(x, a, &amp;ym, tmp, na);

		// evaluate central difference approximates for partial
		dy_da = (yp - ym) / (2 * small);

		// restore this component of a
		a[i]  = ai;

		ok   &amp;= <a href="nearequal.xml" target="_top">NearEqual</a>(dyda[i], dy_da, small, small); 
	}
	return ok;
}
</pre>

</font></code>


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

</body>
</html>