File: det_lu.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 (120 lines) | stat: -rw-r--r-- 3,658 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-24 Bradley M. Bell
// ----------------------------------------------------------------------------
/*
{xrst_begin adolc_det_lu.cpp}

Adolc Speed: Gradient of Determinant Using Lu Factorization
###########################################################

Specifications
**************
See :ref:`link_det_lu-name` .

Implementation
**************
{xrst_spell_off}
{xrst_code cpp} */
// suppress conversion warnings before other includes
# include <cppad/wno_conversion.hpp>
//
# include <adolc/adolc.h>

# include <cppad/speed/det_by_lu.hpp>
# include <cppad/speed/uniform_01.hpp>
# include <cppad/utility/track_new_del.hpp>

// list of possible options
# include <map>
extern std::map<std::string, bool> global_option;

bool link_det_lu(
   size_t                     size     ,
   size_t                     repeat   ,
   CppAD::vector<double>     &matrix   ,
   CppAD::vector<double>     &gradient )
{
   // speed test global option values
   if( global_option["onetape"] || global_option["atomic"] )
      return false;
   if( global_option["memory"] || global_option["optimize"] )
      return false;
   // -----------------------------------------------------
   // setup
   short tag  = 0;                // tape identifier
   int   keep = 1;                // keep forward mode results in buffer
   int   m    = 1;                // number of dependent variables
   int   n    = int(size * size); // number of independent variables
   double f;                      // function value
   int j;                         // temporary index

   // set up for thread_alloc memory allocator (fast and checks for leaks)
   using CppAD::thread_alloc; // the allocator
   size_t size_min;           // requested number of elements
   size_t size_out;           // capacity of an allocation

   // object for computing determinant
   typedef adouble            ADScalar;
   typedef ADScalar*          ADVector;
   CppAD::det_by_lu<ADScalar> Det(size);

   // AD value of determinant
   ADScalar   detA;

   // AD version of matrix
   size_min    = size_t(n);
   ADVector A  = thread_alloc::create_array<ADScalar>(size_min, size_out);

   // vectors of reverse mode weights
   size_min    = size_t(m);
   double* u   = thread_alloc::create_array<double>(size_min, size_out);
   u[0] = 1.;

   // vector with matrix value
   size_min     = size_t(n);
   double* mat  = thread_alloc::create_array<double>(size_min, size_out);

   // vector to receive gradient result
   size_min     = size_t(n);
   double* grad = thread_alloc::create_array<double>(size_min, size_out);
   // ------------------------------------------------------
   while(repeat--)
   {  // get the next matrix
      CppAD::uniform_01( size_t(n), mat);

      // declare independent variables
      trace_on(tag, keep);
      for(j = 0; j < n; j++)
         A[j] <<= mat[j];

      // AD computation of the determinant
      detA = Det(A);

      // create function object f : A -> detA
      detA >>= f;
      trace_off();

      // evaluate and return gradient using reverse mode
      fos_reverse(tag, m, n, u, grad);
   }
   // ------------------------------------------------------

   // return matrix and gradient
   for(j = 0; j < n; j++)
   {  matrix[j] = mat[j];
      gradient[j] = grad[j];
   }
   // tear down
   thread_alloc::delete_array(grad);
   thread_alloc::delete_array(mat);
   thread_alloc::delete_array(u);
   thread_alloc::delete_array(A);

   return true;
}
/* {xrst_code}
{xrst_spell_on}

{xrst_end adolc_det_lu.cpp}
*/