File: hes_times_dir.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (83 lines) | stat: -rw-r--r-- 2,174 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------

/*
{xrst_begin hes_times_dir.cpp}

Hessian Times Direction: Example and Test
#########################################

{xrst_literal
   // BEGIN C++
   // END C++
}

{xrst_end hes_times_dir.cpp}
*/
// BEGIN C++
// Example and test of computing the Hessian times a direction; i.e.,
// given F : R^n -> R and a direction dx in R^n, we compute F''(x) * dx

# include <cppad/cppad.hpp>

namespace { // put this function in the empty namespace
   // F(x) = |x|^2 = x[0]^2 + ... + x[n-1]^2
   template <class Type>
   Type F(CPPAD_TESTVECTOR(Type) &x)
   {  Type sum = 0;
      size_t i = x.size();
      while(i--)
         sum += x[i] * x[i];
      return sum;
   }
}

bool HesTimesDir(void)
{  bool ok = true;                   // initialize test result
   size_t j;                         // a domain variable variable

   using CppAD::AD;
   using CppAD::NearEqual;
   double eps99 = 99.0 * std::numeric_limits<double>::epsilon();

   // domain space vector
   size_t n = 5;
   CPPAD_TESTVECTOR(AD<double>)  X(n);
   for(j = 0; j < n; j++)
      X[j] = AD<double>(j);

   // declare independent variables and start recording
   CppAD::Independent(X);

   // range space vector
   size_t m = 1;
   CPPAD_TESTVECTOR(AD<double>) Y(m);
   Y[0] = F(X);

   // create f : X -> Y and stop recording
   CppAD::ADFun<double> f(X, Y);

   // choose a direction dx and compute dy(x) = F'(x) * dx
   CPPAD_TESTVECTOR(double) dx(n);
   CPPAD_TESTVECTOR(double) dy(m);
   for(j = 0; j < n; j++)
      dx[j] = double(n - j);
   dy = f.Forward(1, dx);

   // compute ddw = F''(x) * dx
   CPPAD_TESTVECTOR(double) w(m);
   CPPAD_TESTVECTOR(double) ddw(2 * n);
   w[0] = 1.;
   ddw  = f.Reverse(2, w);

   // F(x)        = x[0]^2 + x[1]^2 + ... + x[n-1]^2
   // F''(x)      = 2 * Identity_Matrix
   // F''(x) * dx = 2 * dx
   for(j = 0; j < n; j++)
      ok &= NearEqual(ddw[j * 2 + 1], 2.*dx[j], eps99, eps99);

   return ok;
}
// END C++