source: branches/opt_cond_exp/cppad/local/forward.hpp @ 2970

Last change on this file since 2970 was 2970, checked in by bradbell, 7 years ago

Convert forward_sweep to handel CSkip operators.

forward0sweep.hpp: minor clean up of doxygen, alphabetic order ops.

  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1/* $Id: forward.hpp 2970 2013-10-19 02:16:02Z bradbell $ */
2# ifndef CPPAD_FORWARD_INCLUDED
3# define CPPAD_FORWARD_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16/*
17$begin Forward$$
18
19$section Forward Mode$$
20
21$childtable%
22        omh/forward.omh%
23        cppad/local/cap_taylor.hpp%
24        example/forward.cpp%
25        example/forward_mul.cpp
26%$$
27
28$end
29-----------------------------------------------------------------------------
30*/
31
32// documened after Forward but included here so easy to see
33# include <cppad/local/cap_taylor.hpp>
34
35namespace CppAD { // BEGIN_CPPAD_NAMESPACE
36/*!
37\defgroup forward_hpp forward.hpp
38\{
39\file forward.hpp
40User interface to forward mode computations
41*/
42
43/*!
44Compute arbitrary order forward mode Taylor coefficieints.
45
46\tparam Base
47The type used during the forward mode computations; i.e., the corresponding
48recording of operations used the type \c AD<Base>.
49
50\tparam Vector
51is a Simple Vector class with eleements of type \c Base.
52
53\param p
54is the hightest order for this forward mode computation; i.e.,
55after this calculation there will be <code>p+1</code>
56Taylor coefficients per variables.
57
58\param x_p
59contains Taylor coefficients for the independent variables.
60The size of \a x_p must either be \c n or <code>n*(p+1)</code>,
61We define <code>q = p + 1 - x_p.size() / n</code>.
62The Taylor coefficients of order k, for
63k = q, ... , p are calculated.
64
65\param s
66Is the stream where output corresponding to \c PriOp operations will written.
67*/
68
69template <typename Base>
70template <typename Vector>
71Vector ADFun<Base>::Forward(
72        size_t p                    , 
73        const Vector& x_p           , 
74        std::ostream& s             )
75{       // temporary indices
76        size_t i, j, k;
77
78        // number of independent variables
79        size_t n = ind_taddr_.size();
80
81        // number of dependent variables
82        size_t m = dep_taddr_.size();
83
84        // check Vector is Simple Vector class with Base type elements
85        CheckSimpleVector<Base, Vector>();
86
87        CPPAD_ASSERT_KNOWN(
88                size_t(x_p.size()) == n || size_t(x_p.size()) == n*(p+1),
89                "Forward: x_p.size() is not equal n or n*(p+1)"
90        );
91        size_t n_order = size_t(x_p.size()) / n;
92        CPPAD_ASSERT_KNOWN(
93                p <= taylor_per_var_ || n_order == p + 1,
94                "The number of Taylor coefficient currently stored in this ADFun\n"
95                "is less than p and x_p.size() != n*(p+1)."
96        ); 
97
98        // check if the taylor_ matrix needs more columns
99        if( taylor_col_dim_ <= p )
100                capacity_taylor(p + 1);
101        CPPAD_ASSERT_UNKNOWN( taylor_col_dim_ > p );
102
103        // set the p-th order taylor_ coefficients for independent variables
104        for(j = 0; j < n; j++)
105        {       CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < total_num_var_ );
106
107                // ind_taddr_[j] is operator taddr for j-th independent variable
108                CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == InvOp );
109
110                // It is also variable taddr for j-th independent variable
111                if( n_order ==  1 )
112                        taylor_[ind_taddr_[j] * taylor_col_dim_ + p] = x_p[j];
113                else for(k = 0; k < n_order; k++)
114                        taylor_[ind_taddr_[j] * taylor_col_dim_ + k] = 
115                                x_p[j * n_order + k];
116        }
117
118        // evaluate the derivatives
119        size_t q = (p + 1) - n_order;
120        if( p == 0 )
121        {
122# if CPPAD_USE_FORWARD0SWEEP
123                compare_change_ = forward0sweep(s, true,
124                        n, total_num_var_, &play_, taylor_col_dim_, taylor_.data(),
125                        cskip_var_
126                );
127# else
128                compare_change_ = forward_sweep(s, true, q,
129                        p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data(),
130                        cskip_var_
131                );
132# endif
133        }
134        else if( q == 0 )
135        {       compare_change_ = forward_sweep(s, true, q,
136                        p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data(),
137                        cskip_var_
138                );
139        }
140        else
141        {       forward_sweep(s, true, q,
142                        p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data(),
143                        cskip_var_
144                );
145        }
146
147        // return Taylor coefficients for dependent variables
148        Vector y_p;
149        if( n_order == 1 )
150        {       y_p.resize(m);
151                for(i = 0; i < m; i++)
152                {       CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < total_num_var_ );
153                        y_p[i] = taylor_[dep_taddr_[i] * taylor_col_dim_ + p];
154                }
155        }
156        else
157        {       y_p.resize(m * n_order );
158                for(i = 0; i < m; i++) 
159                {       for(k = 0; k < n_order; k++)
160                                y_p[ i * n_order + k] = 
161                                        taylor_[ dep_taddr_[i] * taylor_col_dim_ + k ]; 
162                }
163        }
164# ifndef NDEBUG
165        if( check_for_nan_ )
166        {       bool ok = true;
167                if( p == 0 && n_order == 1 )
168                        ok = ! hasnan(y_p);
169                else if( n_order != 1 )
170                {       for(i = 0; i < m; i++)
171                        ok &= ! isnan( y_p[ i * n_order + 0 ] );
172                } 
173                CPPAD_ASSERT_KNOWN(ok,
174                        "y_p = f.Forward(p, x): has a zero order Taylor coefficient "
175                        "with the value nan."
176                ); 
177                if( p != 0 && n_order == 1 )
178                        ok = ! hasnan(y_p);
179                else if( n_order != 1 )
180                {       for(i = 0; i < m; i++)
181                        {       for(k = 1; k < n_order; k++)
182                                        ok &= ! isnan( y_p[ i * n_order + k ] );
183                        }
184                }
185                CPPAD_ASSERT_KNOWN(ok,
186                "y_p = f.Forward(p, x): has a non-zero order Taylor coefficient\n"
187                "with the value nan (but zero order coefficients are not nan)."
188                );
189        }
190# endif
191
192
193        // now we have p + 1  taylor_ coefficients per variable
194        taylor_per_var_ = p + 1;
195
196        return y_p;
197}
198
199/*! \} */
200} // END_CPPAD_NAMESPACE
201# endif
Note: See TracBrowser for help on using the repository browser.