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

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

First version that actually calls forward_cskip_0, not yet actually skipping
operations.

  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1/* $Id: forward.hpp 2968 2013-10-18 19:41:48Z 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                );
131# endif
132        }
133        else if( q == 0 )
134        {       compare_change_ = forward_sweep(s, true, q,
135                        p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
136                );
137        }
138        else
139        {       forward_sweep(s, true, q,
140                        p, n, total_num_var_, &play_, taylor_col_dim_, taylor_.data()
141                );
142        }
143
144        // return Taylor coefficients for dependent variables
145        Vector y_p;
146        if( n_order == 1 )
147        {       y_p.resize(m);
148                for(i = 0; i < m; i++)
149                {       CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < total_num_var_ );
150                        y_p[i] = taylor_[dep_taddr_[i] * taylor_col_dim_ + p];
151                }
152        }
153        else
154        {       y_p.resize(m * n_order );
155                for(i = 0; i < m; i++) 
156                {       for(k = 0; k < n_order; k++)
157                                y_p[ i * n_order + k] = 
158                                        taylor_[ dep_taddr_[i] * taylor_col_dim_ + k ]; 
159                }
160        }
161# ifndef NDEBUG
162        if( check_for_nan_ )
163        {       bool ok = true;
164                if( p == 0 && n_order == 1 )
165                        ok = ! hasnan(y_p);
166                else if( n_order != 1 )
167                {       for(i = 0; i < m; i++)
168                        ok &= ! isnan( y_p[ i * n_order + 0 ] );
169                } 
170                CPPAD_ASSERT_KNOWN(ok,
171                        "y_p = f.Forward(p, x): has a zero order Taylor coefficient "
172                        "with the value nan."
173                ); 
174                if( p != 0 && n_order == 1 )
175                        ok = ! hasnan(y_p);
176                else if( n_order != 1 )
177                {       for(i = 0; i < m; i++)
178                        {       for(k = 1; k < n_order; k++)
179                                        ok &= ! isnan( y_p[ i * n_order + k ] );
180                        }
181                }
182                CPPAD_ASSERT_KNOWN(ok,
183                "y_p = f.Forward(p, x): has a non-zero order Taylor coefficient\n"
184                "with the value nan (but zero order coefficients are not nan)."
185                );
186        }
187# endif
188
189
190        // now we have p + 1  taylor_ coefficients per variable
191        taylor_per_var_ = p + 1;
192
193        return y_p;
194}
195
196/*! \} */
197} // END_CPPAD_NAMESPACE
198# endif
Note: See TracBrowser for help on using the repository browser.