<?xml version='1.0'?>
<html xmlns='http://www.w3.org/1999/xhtml'
xmlns:math='http://www.w3.org/1998/Math/MathML'
>
<head>
<title>ODE Inverse Problem Definitions: Source Code</title>
<meta http-equiv='Content-Type' content='text/html' charset='utf-8'/>
<meta name="description" id="description" content="ODE Inverse Problem Definitions: Source Code"/>
<meta name="keywords" id="keywords" content=" ode inverse problem definitions: source code example purpose forward measurements simulation analytic solution parameter values simulated measurement trapezoidal approximation method "/>
<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='_ipopt_solve_ode_inverse.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="ipopt_solve_retape.cpp.xml" target="_top">Prev</a>
</td><td><a href="example.xml" target="_top">Next</a>
</td><td>
<select onchange='choose_across0(this)'>
<option>Index-></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-></option>
<option>CppAD</option>
<option>ipopt_solve</option>
<option>ipopt_solve_ode_inverse.cpp</option>
</select>
</td>
<td>
<select onchange='choose_down2(this)'>
<option>CppAD-></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_down1(this)'>
<option>ipopt_solve-></option>
<option>ipopt_solve_get_started.cpp</option>
<option>ipopt_solve_retape.cpp</option>
<option>ipopt_solve_ode_inverse.cpp</option>
</select>
</td>
<td>ipopt_solve_ode_inverse.cpp</td>
<td>
<select onchange='choose_current0(this)'>
<option>Headings-></option>
<option>Purpose</option>
<option>Forward Problem</option>
<option>Measurements</option>
<option>---..Simulation Analytic Solution</option>
<option>---..Simulation Parameter Values</option>
<option>---..Simulated Measurement Values</option>
<option>Inverse Problem</option>
<option>Trapezoidal Approximation</option>
<option>Solution Method</option>
<option>Source</option>
</select>
</td>
</tr></table><br/>
<center><b><big><big>ODE Inverse Problem Definitions: Source Code</big></big></b></center>
<br/>
<b><big><a name="Purpose" id="Purpose">Purpose</a></big></b>
<br/>
This example demonstrates how to invert for parameters
in a ODE where the solution of the ODE is numerically approximated.
<br/>
<br/>
<b><big><a name="Forward Problem" id="Forward Problem">Forward Problem</a></big></b>
<br/>
We consider the following ordinary differential equation:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<msub><mo stretchy="false">∂</mo>
<mi mathvariant='italic'>t</mi>
</msub>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd></mtr><mtr><mtd columnalign="right" >
<msub><mo stretchy="false">∂</mo>
<mi mathvariant='italic'>t</mi>
</msub>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<mo stretchy="false">+</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>2</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd></mtr></mtable>
</mrow></math>
with the initial conditions
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">=</mo>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">,</mo>
<mn>0</mn>
<msup><mo stretchy="false">)</mo>
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>T</mi>
</mstyle></mrow>
</msup>
</mrow></math>
Our forward problem is stated as follows:
Given
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>3</mn>
</msup>
</mrow></math>
determine the value of
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>y</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow></math>
,
for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">∈</mo>
<mi mathvariant='italic'>R</mi>
</mrow></math>
, that solves the initial value problem above.
<br/>
<br/>
<b><big><a name="Measurements" id="Measurements">Measurements</a></big></b>
<br/>
Suppose we are also given measurement times
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>s</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>5</mn>
</msup>
</mrow></math>
and a measurement vector
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>z</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>4</mn>
</msup>
</mrow></math>
and for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mn>3</mn>
</mrow></math>
, we model
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>z</mi>
<mi mathvariant='italic'>i</mi>
</msub>
</mrow></math>
by
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<msub><mi mathvariant='italic'>z</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">=</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>s</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">+</mo>
<msub><mi mathvariant='italic'>e</mi>
<mi mathvariant='italic'>i</mi>
</msub>
</mrow></math>
where
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>e</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mn>-1</mn>
</mrow>
</msub>
<mo stretchy="false">∼</mo>
<mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>N</mi>
</mstyle></mrow>
<mo stretchy="false">(</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<msup><mi mathvariant='normal'>σ</mi>
<mn>2</mn>
</msup>
<mo stretchy="false">)</mo>
</mrow></math>
is the measurement noise,
and
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='normal'>σ</mi>
<mo stretchy="false">></mo>
<mn>0</mn>
</mrow></math>
is the standard deviation of the noise.
<br/>
<br/>
<b><a name="Measurements.Simulation Analytic Solution" id="Measurements.Simulation Analytic Solution">Simulation Analytic Solution</a></b>
<br/>
The following analytic solution to the forward problem is used
to simulate a data set:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<msub><mi mathvariant='italic'>a</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">*</mo>
<mi>exp</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">)</mo>
</mtd></mtr><mtr><mtd columnalign="right" >
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<msub><mi mathvariant='italic'>a</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<mfrac><mrow><mi>exp</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>2</mn>
</msub>
<mo stretchy="false">*</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">-</mo>
<mi>exp</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">)</mo>
</mrow>
<mrow><msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>2</mn>
</msub>
</mrow>
</mfrac>
</mtd></mtr></mtable>
</mrow></math>
<br/>
<b><a name="Measurements.Simulation Parameter Values" id="Measurements.Simulation Parameter Values">Simulation Parameter Values</a></b>
<table><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>0</mn>
</msub>
<mo stretchy="false">=</mo>
<mn>1</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
initial value of
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow></math>
</td></tr><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>1</mn>
</msub>
<mo stretchy="false">=</mo>
<mn>2</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
transfer rate from compartment zero to compartment one
</td></tr><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>2</mn>
</msub>
<mo stretchy="false">=</mo>
<mn>1</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
transfer rate from compartment one to outside world
</td></tr><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='normal'>σ</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
standard deviation of measurement noise
</td></tr><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>e</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">=</mo>
<mn>0</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
simulated measurement noise,
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>1</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>Nz</mi>
</mrow></math>
</td></tr><tr><td align='left' valign='top'>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>s</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">=</mo>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">*</mo>
<mn>.5</mn>
</mrow></math>
<code><span style='white-space: nowrap'> </span></code> </td><td align='left' valign='top'>
time corresponding to the <code><i>i</i></code>-th measurement,
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mn>3</mn>
</mrow></math>
</td></tr>
</table>
<br/>
<b><a name="Measurements.Simulated Measurement Values" id="Measurements.Simulated Measurement Values">Simulated Measurement Values</a></b>
<br/>
The simulated measurement values are given by the equation
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<msub><mi mathvariant='italic'>z</mi>
<mi mathvariant='italic'>i</mi>
</msub>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<msub><mi mathvariant='italic'>e</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">+</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>s</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">,</mo>
<mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mo stretchy="false">)</mo>
</mtd></mtr><mtr><mtd columnalign="right" >
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>0</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<mfrac><mrow><mi>exp</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">-</mo>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>2</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>s</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">)</mo>
<mo stretchy="false">-</mo>
<mi>exp</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">-</mo>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>s</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">)</mo>
</mrow>
<mrow><msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>1</mn>
</msub>
<mo stretchy="false">-</mo>
<msub><mover accent='false'><mrow><mi mathvariant='italic'>a</mi>
</mrow>
<mo stretchy='false'>¯</mo></mover>
<mn>2</mn>
</msub>
</mrow>
</mfrac>
</mtd></mtr></mtable>
</mrow></math>
for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mn>3</mn>
</mrow></math>
.
<br/>
<br/>
<b><big><a name="Inverse Problem" id="Inverse Problem">Inverse Problem</a></big></b>
<br/>
The maximum likelihood estimate for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>a</mi>
</mrow></math>
given
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>z</mi>
</mrow></math>
solves the following optimization problem
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>minimize</mi>
</mstyle></mrow>
<mspace width='.3em'/>
</mtd><mtd columnalign="center" >
<munderover><mo displaystyle='true' largeop='true'>∑</mo>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
</mrow>
<mn>3</mn>
</munderover>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>z</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>s</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<msup><mo stretchy="false">)</mo>
<mn>2</mn>
</msup>
</mtd><mtd columnalign="left" >
<mspace width='.3em'/>
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>w</mi>
<mo stretchy="false">.</mo>
<mi mathvariant='normal'>r</mi>
<mo stretchy="false">.</mo>
<mi mathvariant='normal'>t</mi>
</mstyle></mrow>
<mspace width='.3em'/>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>3</mn>
</msup>
</mtd></mtr></mtable>
</mrow></math>
<br/>
<b><big><a name="Trapezoidal Approximation" id="Trapezoidal Approximation">Trapezoidal Approximation</a></big></b>
<br/>
We are given a number of approximation points per measurement interval
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>np</mi>
</mrow></math>
and define the time grid
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>t</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mrow><mn>4</mn>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
</mrow>
</msup>
</mrow></math>
as follows:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>t</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">=</mo>
<msub><mi mathvariant='italic'>s</mi>
<mn>0</mn>
</msub>
</mrow></math>
and
for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
<mo stretchy="false">,</mo>
<mn>1</mn>
<mo stretchy="false">,</mo>
<mn>2</mn>
<mo stretchy="false">,</mo>
<mn>3</mn>
</mrow></math>
,
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>j</mi>
<mo stretchy="false">=</mo>
<mn>1</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>np</mi>
</mrow></math>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<msub><mi mathvariant='italic'>t</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
<mo stretchy="false">+</mo>
<mi mathvariant='italic'>j</mi>
</mrow>
</msub>
<mo stretchy="false">=</mo>
<msub><mi mathvariant='italic'>s</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">+</mo>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>s</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">-</mo>
<mi mathvariant='italic'>s</mi>
<mrow><mi mathvariant='italic'>i</mi>
</mrow>
<mo stretchy="false">)</mo>
<mfrac><mrow><mi mathvariant='italic'>i</mi>
</mrow>
<mrow><mi mathvariant='italic'>np</mi>
</mrow>
</mfrac>
</mrow></math>
We note that for
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>1</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mn>4</mn>
</mrow></math>
,
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msub><mi mathvariant='italic'>t</mi>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
</mrow>
</msub>
<mo stretchy="false">=</mo>
<msub><mi mathvariant='italic'>s</mi>
<mi mathvariant='italic'>i</mi>
</msub>
</mrow></math>
.
This example uses a trapezoidal approximation to solve the ODE.
Given
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>3</mn>
</msup>
</mrow></math>
and
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">≈</mo>
<mi mathvariant='italic'>y</mi>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>t</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msub>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow></math>
,
the a trapezoidal method approximates
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>y</mi>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>t</mi>
<mi mathvariant='italic'>j</mi>
</msub>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow></math>
by the value
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<msup><mi mathvariant='italic'>y</mi>
<mi mathvariant='italic'>k</mi>
</msup>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>2</mn>
</msup>
</mrow></math>
) that solves the equation
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<msup><mi mathvariant='italic'>y</mi>
<mi mathvariant='italic'>k</mi>
</msup>
<mo stretchy="false">=</mo>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">+</mo>
<mfrac><mrow><mi mathvariant='italic'>G</mi>
<mo stretchy="false">(</mo>
<msup><mi mathvariant='italic'>y</mi>
<mi mathvariant='italic'>k</mi>
</msup>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">+</mo>
<mi mathvariant='italic'>G</mi>
<mo stretchy="false">(</mo>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow>
<mrow><mn>2</mn>
</mrow>
</mfrac>
<mo stretchy="false">*</mo>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>t</mi>
<mi mathvariant='italic'>k</mi>
</msub>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>t</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msub>
<mo stretchy="false">)</mo>
</mrow></math>
where
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>G</mi>
<mo stretchy="false">:</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>2</mn>
</msup>
<mo stretchy="false">×</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>3</mn>
</msup>
<mo stretchy="false">→</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>2</mn>
</msup>
</mrow></math>
is defined by
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<msub><mi mathvariant='italic'>G</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>y</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
</mtd></mtr><mtr><mtd columnalign="right" >
<msub><mi mathvariant='italic'>G</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>y</mi>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="center" >
<mo stretchy="false">=</mo>
</mtd><mtd columnalign="left" >
<mo stretchy="false">+</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>2</mn>
</msub>
<mo stretchy="false">*</mo>
<msub><mi mathvariant='italic'>y</mi>
<mn>1</mn>
</msub>
</mtd></mtr></mtable>
</mrow></math>
<br/>
<b><big><a name="Solution Method" id="Solution Method">Solution Method</a></big></b>
<br/>
We use constraints to embed the
forward problem in the inverse problem.
To be specific, we solve the optimization problem
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mtable rowalign="center" ><mtr><mtd columnalign="right" >
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>minimize</mi>
</mstyle></mrow>
</mtd><mtd columnalign="center" >
<munderover><mo displaystyle='true' largeop='true'>∑</mo>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>0</mn>
</mrow>
<mn>3</mn>
</munderover>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>z</mi>
<mi mathvariant='italic'>i</mi>
</msub>
<mo stretchy="false">-</mo>
<msubsup><mi mathvariant='italic'>y</mi>
<mn>1</mn>
<mrow><mo stretchy="false">(</mo>
<mi mathvariant='italic'>i</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
<mo stretchy="false">)</mo>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
</mrow>
</msubsup>
<msup><mo stretchy="false">)</mo>
<mn>2</mn>
</msup>
</mtd><mtd columnalign="left" >
<mspace width='.3em'/>
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>w</mi>
<mo stretchy="false">.</mo>
<mi mathvariant='normal'>r</mi>
<mo stretchy="false">.</mo>
<mi mathvariant='normal'>t</mi>
</mstyle></mrow>
<mspace width='.3em'/>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>3</mn>
</msup>
<mspace width='.3em'/>
<msup><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msup>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>2</mn>
</msup>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mn>3</mn>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">∈</mo>
<msup><mrow><mstyle mathvariant='bold'><mi mathvariant='bold'>R</mi>
</mstyle></mrow>
<mn>2</mn>
</msup>
</mtd></mtr><mtr><mtd columnalign="right" >
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>subject</mi>
<mspace width='.3em'/>
<mi mathvariant='normal'>to</mi>
</mstyle></mrow>
<mn>0</mn>
<mo stretchy="false">=</mo>
<msup><mi mathvariant='italic'>y</mi>
<mn>0</mn>
</msup>
<mo stretchy="false">-</mo>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">,</mo>
<mn>0</mn>
<msup><mo stretchy="false">)</mo>
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>T</mi>
</mstyle></mrow>
</msup>
</mtd></mtr><mtr><mtd columnalign="right" >
</mtd><mtd columnalign="center" >
<mn>0</mn>
<mo stretchy="false">=</mo>
<msup><mi mathvariant='italic'>y</mi>
<mi mathvariant='italic'>k</mi>
</msup>
<mo stretchy="false">-</mo>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">-</mo>
<mfrac><mrow><mi mathvariant='italic'>G</mi>
<mo stretchy="false">(</mo>
<msup><mi mathvariant='italic'>y</mi>
<mi mathvariant='italic'>k</mi>
</msup>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">+</mo>
<mi mathvariant='italic'>G</mi>
<mo stretchy="false">(</mo>
<msup><mi mathvariant='italic'>y</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msup>
<mo stretchy="false">,</mo>
<mi mathvariant='italic'>a</mi>
<mo stretchy="false">)</mo>
</mrow>
<mrow><mn>2</mn>
</mrow>
</mfrac>
<mo stretchy="false">(</mo>
<msub><mi mathvariant='italic'>t</mi>
<mi mathvariant='italic'>k</mi>
</msub>
<mo stretchy="false">-</mo>
<msub><mi mathvariant='italic'>t</mi>
<mrow><mi mathvariant='italic'>k</mi>
<mn>-1</mn>
</mrow>
</msub>
<mo stretchy="false">)</mo>
</mtd><mtd columnalign="left" >
<mspace width='.3em'/>
<mrow><mstyle mathvariant='normal'><mi mathvariant='normal'>for</mi>
</mstyle></mrow>
<mspace width='.3em'/>
<mi mathvariant='italic'>k</mi>
<mo stretchy="false">=</mo>
<mn>1</mn>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<mn>4</mn>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
</mtd></mtr></mtable>
</mrow></math>
The code below we using the notation
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">∈</mo>
<mrow><mstyle mathvariant='bold'><mn>3</mn>
<mo stretchy="false">+</mo>
<mo stretchy="false">(</mo>
<mn>4</mn>
<mo stretchy="false">·</mo>
<mi mathvariant='bold'>np</mi>
<mo stretchy="false">+</mo>
<mn>1</mn>
<mo stretchy="false">)</mo>
<mo stretchy="false">·</mo>
<mn>2</mn>
</mstyle></mrow>
</mrow></math>
defined by
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">=</mo>
<mrow><mo stretchy="true">(</mo><mrow><msub><mi mathvariant='italic'>a</mi>
<mn>0</mn>
</msub>
<mo stretchy="false">,</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>1</mn>
</msub>
<mo stretchy="false">,</mo>
<msub><mi mathvariant='italic'>a</mi>
<mn>2</mn>
</msub>
<mo stretchy="false">,</mo>
<msubsup><mi mathvariant='italic'>y</mi>
<mn>0</mn>
<mn>0</mn>
</msubsup>
<mo stretchy="false">,</mo>
<msubsup><mi mathvariant='italic'>y</mi>
<mn>1</mn>
<mn>0</mn>
</msubsup>
<mo stretchy="false">,</mo>
<mo stretchy="false">…</mo>
<mo stretchy="false">,</mo>
<msubsup><mi mathvariant='italic'>y</mi>
<mn>0</mn>
<mrow><mn>4</mn>
<mo stretchy="false">·</mo>
<mi mathvariant='italic'>np</mi>
</mrow>
</msubsup>
<mo stretchy="false">,</mo>
<msubsup><mi mathvariant='italic'>y</mi>
<mn>1</mn>
<mrow><mn>4</mn>
<mo stretchy="false">⋯</mo>
<mi mathvariant='italic'>np</mi>
</mrow>
</msubsup>
</mrow><mo stretchy="true">)</mo></mrow>
</mrow></math>
<br/>
<b><big><a name="Source" id="Source">Source</a></big></b>
<br/>
The following source code
implements the ODE inversion method proposed above:
<code><font color="blue">
<pre style='display:inline'>
# include <cppad/ipopt/solve.hpp>
namespace {
using CppAD::AD;
// value of a during simulation a[0], a[1], a[2]
double a_[] = {2.0, 1.0, 0.5};
// number of components in a
size_t na_ = sizeof(a_) / sizeof(a_[0]);
// function used to simulate data
double yone(double t)
{ return
a_[0]*a_[1] * (exp(-a_[2]*t) - exp(-a_[1]*t)) / (a_[1] - a_[2]);
}
// time points were we have data (no data at first point)
double s_[] = {0.0, 0.5, 1.0, 1.5, 2.0 };
// Simulated data for case with no noise (first point is not used)
double z_[] = {yone(s_[1]), yone(s_[2]), yone(s_[3]), yone(s_[4])};
size_t nz_ = sizeof(z_) / sizeof(z_[0]);
// number of trapozoidal approximation points per measurement interval
size_t np_ = 40;
class FG_eval
{
private:
public:
// derived class part of constructor
typedef <a href="testvector.xml" target="_top">CPPAD_TESTVECTOR</a>( <a href="ad.xml" target="_top">AD</a><double> ) ADvector;
// Evaluation of the objective f(x), and constraints g(x)
void operator()(ADvector& fg, const ADvector& x)
{ <a href="testvector.xml" target="_top">CPPAD_TESTVECTOR</a>( <a href="ad.xml" target="_top">AD</a><double> ) a(na_);
size_t i, j, k;
// extract the vector a
for(i = 0; i < na_; i++)
a[i] = x[i];
// compute the object f(x)
fg[0] = 0.0;
for(i = 0; i < nz_; i++)
{ k = (i + 1) * np_;
<a href="ad.xml" target="_top">AD</a><double> y_1 = x[na_ + 2 * k + 1];
<a href="ad.xml" target="_top">AD</a><double> dif = z_[i] - y_1;
fg[0] += dif * dif;
}
// constraint corresponding to initial value y(0, a)
// Note that this constraint is invariant with size of dt
fg[1] = x[na_+0] - a[0];
fg[2] = x[na_+1] - 0.0;
// constraints corresponding to trapozoidal approximation
for(i = 0; i < nz_; i++)
{ // spacing between grid point
double dt = (s_[i+1] - s_[i]) / static_cast<double>(np_);
for(j = 1; j <= np_; j++)
{ k = i * np_ + j;
// compute derivative at y^k
<a href="ad.xml" target="_top">AD</a><double> y_0 = x[na_ + 2 * k + 0];
<a href="ad.xml" target="_top">AD</a><double> y_1 = x[na_ + 2 * k + 1];
<a href="ad.xml" target="_top">AD</a><double> G_0 = - a[1] * y_0;
<a href="ad.xml" target="_top">AD</a><double> G_1 = + a[1] * y_0 - a[2] * y_1;
// compute derivative at y^{k-1}
<a href="ad.xml" target="_top">AD</a><double> ym_0 = x[na_ + 2 * (k-1) + 0];
<a href="ad.xml" target="_top">AD</a><double> ym_1 = x[na_ + 2 * (k-1) + 1];
<a href="ad.xml" target="_top">AD</a><double> Gm_0 = - a[1] * ym_0;
<a href="ad.xml" target="_top">AD</a><double> Gm_1 = + a[1] * ym_0 - a[2] * ym_1;
// constraint should be zero
fg[1 + 2*k ] = y_0 - ym_0 - dt*(G_0 + Gm_0)/2.;
fg[2 + 2*k ] = y_1 - ym_1 - dt*(G_1 + Gm_1)/2.;
// scale g(x) so it has similar size as f(x)
fg[1 + 2*k ] /= dt;
fg[2 + 2*k ] /= dt;
}
}
}
};
}
bool ode_inverse(void)
{ bool ok = true;
size_t i;
typedef <a href="testvector.xml" target="_top">CPPAD_TESTVECTOR</a>( double ) Dvector;
// number of components in the function g
size_t ng = (np_ * nz_ + 1) * 2;
// number of independent variables
size_t nx = na_ + ng;
// initial vlaue for the variables we are optimizing w.r.t
Dvector xi(nx), xl(nx), xu(nx);
for(i = 0; i < nx; i++)
{ xi[i] = 0.0; // initial value
xl[i] = -1e19; // no lower limit
xu[i] = +1e19; // no upper limit
}
for(i = 0; i < na_; i++)
xi[0] = 1.5; // initial value for a
// all the difference equations are constrainted to be zero
Dvector gl(ng), gu(ng);
for(i = 0; i < ng; i++)
{ gl[i] = 0.0;
gu[i] = 0.0;
}
// object defining both f(x) and g(x)
FG_eval fg_eval;
// options
std::string options;
// Use sparse matrices for calculation of Jacobians and Hessians
// with forward mode for Jacobian (seems to be faster for this case).
options += "Sparse true forward\n";
// turn off any printing
options += "Integer print_level 0\n";
options += "String sb yes\n";
// maximum number of iterations
options += "Integer max_iter 30\n";
// approximate accuracy in first order necessary conditions;
// see Mathematical Programming, Volume 106, Number 1,
// Pages 25-57, Equation (6)
options += "Numeric tol 1e-6\n";
// place to return solution
CppAD::ipopt::solve_result<Dvector> solution;
// solve the problem
CppAD::ipopt::solve<Dvector, FG_eval>(
options, xi, xl, xu, gl, gu, fg_eval, solution
);
//
// Check some of the solution values
//
ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
//
double rel_tol = 1e-4; // relative tolerance
double abs_tol = 1e-4; // absolute tolerance
for(i = 0; i < na_; i++)
ok &= CppAD::<a href="nearequal.xml" target="_top">NearEqual</a>( a_[i], solution.x[i], rel_tol, abs_tol);
return ok;
}
</pre>
</font></code>
<hr/>Input File: example/ipopt_solve/ode_inverse.cpp
</body>
</html>