lines 8-306 of file: include/cppad/core/bender_quad.hpp

{xrst_begin BenderQuad app}
{xrst_spell
   avector
   gx
   gxx
}

Computing Jacobian and Hessian of Bender's Reduced Objective
############################################################

Syntax
******

| # ``include <cppad/cppad.hpp>``
| *BenderQuad* ( ``x`` , ``y`` , ``fun`` , ``g`` , ``gx`` , ``gxx`` )

See Also
********
:ref:`opt_val_hes-name`

Problem
*******
The type :ref:`BenderQuad@ADvector` cannot be determined
form the arguments above
(currently the type *ADvector* must be
``CPPAD_TESTVECTOR`` ( *Base* ) .)
This will be corrected in the future by requiring *Fun*
to define *Fun* :: ``vector_type`` which will specify the
type *ADvector* .

Purpose
*******
We are given the optimization problem

.. math::
   :nowrap:

   \begin{eqnarray}
   {\rm minimize} & F(x, y) & {\rm w.r.t.} \; (x, y) \in \B{R}^n \times \B{R}^m
   \end{eqnarray}

that is convex with respect to :math:`y`.
In addition, we are given a set of equations :math:`H(x, y)`
such that

.. math::

   H[ x , Y(x) ] = 0 \;\; \Rightarrow \;\; F_y [ x , Y(x) ] = 0

(In fact, it is often the case that :math:`H(x, y) = F_y (x, y)`.)
Furthermore, it is easy to calculate a Newton step for these equations; i.e.,

.. math::

   dy = - [ \partial_y H(x, y)]^{-1} H(x, y)

The purpose of this routine is to compute the
value, Jacobian, and Hessian of the reduced objective function

.. math::

   G(x) = F[ x , Y(x) ]

Note that if only the value and Jacobian are needed, they can be
computed more quickly using the relations

.. math::

   G^{(1)} (x) = \partial_x F [x, Y(x) ]

x
*
The ``BenderQuad`` argument *x* has prototype

   ``const`` *BAvector* & *x*

(see :ref:`BenderQuad@BAvector` below)
and its size must be equal to *n* .
It specifies the point at which we evaluating
the reduced objective function and its derivatives.

y
*
The ``BenderQuad`` argument *y* has prototype

   ``const`` *BAvector* & *y*

and its size must be equal to *m* .
It must be equal to :math:`Y(x)`; i.e.,
it must solve the problem in :math:`y` for this given value of :math:`x`

.. math::
   :nowrap:

   \begin{eqnarray}
      {\rm minimize} & F(x, y) & {\rm w.r.t.} \; y \in \B{R}^m
   \end{eqnarray}

fun
***
The ``BenderQuad`` object *fun*
must support the member functions listed below.
The ``AD`` < *Base* > arguments will be variables for
a tape created by a call to :ref:`Independent-name` from ``BenderQuad``
(hence they can not be combined with variables corresponding to a
different tape).

fun.f
=====
The ``BenderQuad`` argument *fun* supports the syntax

   *f* = *fun* . ``f`` ( *x* , *y* )

The *fun* . ``f`` argument *x* has prototype

   ``const`` *ADvector* & *x*

(see :ref:`BenderQuad@ADvector` below)
and its size must be equal to *n* .
The *fun* . ``f`` argument *y* has prototype

   ``const`` *ADvector* & *y*

and its size must be equal to *m* .
The *fun* . ``f`` result *f* has prototype

   *ADvector* *f*

and its size must be equal to one.
The value of *f* is

.. math::

   f = F(x, y)

fun.h
=====
The ``BenderQuad`` argument *fun* supports the syntax

   *h* = *fun* . ``h`` ( *x* , *y* )

The *fun* . ``h`` argument *x* has prototype

   ``const`` *ADvector* & *x*

and its size must be equal to *n* .
The *fun* . ``h`` argument *y* has prototype

   ``const`` *BAvector* & *y*

and its size must be equal to *m* .
The *fun* . ``h`` result *h* has prototype

   *ADvector* *h*

and its size must be equal to *m* .
The value of *h* is

.. math::

   h = H(x, y)

fun.dy
======
The ``BenderQuad`` argument *fun* supports the syntax

| |tab| *dy* = *fun* . ``dy`` ( *x* , *y* , *h* )
|
| *x*

The *fun* . ``dy`` argument *x* has prototype

   ``const`` *BAvector* & *x*

and its size must be equal to *n* .
Its value will be exactly equal to the ``BenderQuad`` argument
*x* and values depending on it can be stored as private objects
in *f* and need not be recalculated.

   *y*

The *fun* . ``dy`` argument *y* has prototype

   ``const`` *BAvector* & *y*

and its size must be equal to *m* .
Its value will be exactly equal to the ``BenderQuad`` argument
*y* and values depending on it can be stored as private objects
in *f* and need not be recalculated.

   *h*

The *fun* . ``dy`` argument *h* has prototype

   ``const`` *ADvector* & *h*

and its size must be equal to *m* .

   *dy*

The *fun* . ``dy`` result *dy* has prototype

   *ADvector* *dy*

and its size must be equal to *m* .
The return value *dy* is given by

.. math::

   dy = - [ \partial_y H (x , y) ]^{-1} h

Note that if *h* is equal to :math:`H(x, y)`,
:math:`dy` is the Newton step for finding a zero
of :math:`H(x, y)` with respect to :math:`y`;
i.e.,
:math:`y + dy` is an approximate solution for the equation
:math:`H (x, y + dy) = 0`.

g
*
The argument *g* has prototype

   *BAvector* & *g*

and has size one.
The input value of its element does not matter.
On output,
it contains the value of :math:`G (x)`; i.e.,

.. math::

   g[0] = G (x)

gx
**
The argument *gx* has prototype

   *BAvector* & *gx*

and has size :math:`n`.
The input values of its elements do not matter.
On output,
it contains the Jacobian of :math:`G (x)`; i.e.,
for :math:`j = 0 , \ldots , n-1`,

.. math::

   gx[ j ] = G^{(1)} (x)_j

gxx
***
The argument *gx* has prototype

   *BAvector* & *gxx*

and has size :math:`n \times n`.
The input values of its elements do not matter.
On output,
it contains the Hessian of :math:`G (x)`; i.e.,
for :math:`i = 0 , \ldots , n-1`, and
:math:`j = 0 , \ldots , n-1`,

.. math::

   gxx[ i * n + j ] = G^{(2)} (x)_{i,j}

BAvector
********
The type *BAvector* must be a
:ref:`SimpleVector-name` class.
We use *Base* to refer to the type of the elements of
*BAvector* ; i.e.,

   *BAvector* :: ``value_type``

ADvector
********
The type *ADvector* must be a
:ref:`SimpleVector-name` class with elements of type
``AD`` < *Base* > ; i.e.,

   *ADvector* :: ``value_type``

must be the same type as

   ``AD`` < *BAvector* :: ``value_type >``

.

Example
*******
{xrst_toc_hidden
   example/general/bender_quad.cpp
}
The file
:ref:`bender_quad.cpp-name`
contains an example and test of this operation.

{xrst_end BenderQuad}
