Changeset 3714


Ignore:
Timestamp:
Aug 29, 2015 8:52:06 PM (5 years ago)
Author:
bradbell
Message:

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 630f51c9e1a0037b2302ab026d1f2867b9490e91
end hash code: 1d82806185c40ae85242338c2c1cdba2fd4f5985

commit 1d82806185c40ae85242338c2c1cdba2fd4f5985
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 12:57:14 2015 -0700

checkpoint.hpp: implement vectorBool rev_sparse_hes.

commit b42838e676305047dbcee4e031f8fb83d1e70770
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 12:15:49 2015 -0700

checkpoint.hpp: implement vectorBool rev_sparse_jac.

commit b89fc4a703f41d39f3516703dad2f7718dd7ef79
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 11:51:19 2015 -0700

checkpoint.hpp: implement for_sparse_jac with vectorBool.

commit 53654104f0dc924ef1d26142b4ca2ade58c8ff4a
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 11:39:10 2015 -0700

checkpoint.hpp: change assert -> CPPAD_ASSERT_UNKNOWN.

commit 78dd8572e4c7108e1876b690e93c92bd3cf651f7
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 11:27:44 2015 -0700

Remove invisible white space.

commit 628ec0c68477bb13677a5e728a51bbf78e136f1c
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 11:26:52 2015 -0700

Start checking use of boolean sparstiy patterns.
atomic_base.hpp: default to boolean so it gets checked.
checkpoint.hpp: implement boolean sparsity for forward mode case.

commit 1fe7822a0bf1a668c4f28ce602cc51a7a8b16d66
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 10:08:37 2015 -0700

checkpoint.hpp: fix type of jac_sparse_bool_, hes_sparse_bool_.

commit 60875bf6073356b0504a2f64b41956de5dd18103
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 08:35:22 2015 -0700

Use internal sparsity for forward Jaobian part of checkpoint hessian.

commit ee41da9ab646f7bf0f357a4fe1d6e0f403166d24
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 07:53:20 2015 -0700

checkpoint.hpp: add computation of boolean versions of sparsity.

commit 4a8f2410f16843370ff36dda765ad734fb5ac68b
Author: Brad Bell <bradbell@…>
Date: Sat Aug 29 07:41:17 2015 -0700

checkpoint.hpp: change entire_*_sparse_ -> *_sparse_set_.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/cppad/local/atomic_base.hpp

    r3607 r3714  
    77
    88CppAD is distributed under multiple licenses. This distribution is under
    9 the terms of the 
     9the terms of the
    1010                    Eclipse Public License Version 1.0.
    1111
     
    4444        option_enum sparsity_;
    4545
    46         /// temporary work space used afun, declared here to avoid memory 
     46        /// temporary work space used afun, declared here to avoid memory
    4747        /// allocation/deallocation for each call to afun
    4848        vector<bool>  afun_vx_[CPPAD_MAX_NUM_THREADS];
     
    111111The object $icode afun$$ must stay in scope for as long
    112112as the corresponding atomic function is used.
    113 This includes use by any $cref/ADFun<Base>/ADFun/$$ that 
    114 has this $icode atomic_user$$ operation in its 
     113This includes use by any $cref/ADFun<Base>/ADFun/$$ that
     114has this $icode atomic_user$$ operation in its
    115115$cref/operation sequence/glossary/Operation/Sequence/$$.
    116116
    117117$subhead Implementation$$
    118 The user defined $icode atomic_user$$ class is a publicly derived class of 
     118The user defined $icode atomic_user$$ class is a publicly derived class of
    119119$codei%atomic_base<%Base%>%$$.
    120120It should be declared as follows:
     
    126126        };
    127127%$$
    128 where $icode ...$$ 
     128where $icode ...$$
    129129denotes the rest of the implementation of the derived class.
    130130This includes completing the constructor and
    131 all the virtual functions that have their 
    132 $code atomic_base$$ implementations replaced by 
     131all the virtual functions that have their
     132$code atomic_base$$ implementations replaced by
    133133$icode atomic_user$$ implementations.
    134134
     
    195195atomic_base( const std::string&  name) :
    196196index_( class_object().size() )     ,
    197 sparsity_( set_sparsity_enum )
     197sparsity_( bool_sparsity_enum )
    198198{       CPPAD_ASSERT_KNOWN(
    199199                ! thread_alloc::in_parallel() ,
     
    243243$index atomic_sparsity$$
    244244$index sparsity, atomic$$
    245 You can used this option to set the type used for 
     245You can used this option to set the type used for
    246246$icode afun$$ sparsity patterns.
    247247This does not apply individual calls to $icode afun$$,
    248248but rather all its uses between when the sparsity pattern is set and when
    249249it is changed.
    250 If neither the $code set_sparsity_enum$$ or 
     250If neither the $code set_sparsity_enum$$ or
    251251$code bool_sparsity_enum$$ option is set,
    252252the type for $icode atomic_sparsity$$ is one of the two choices below
     
    255255$subhead bool_sparsity_enum$$
    256256$index bool_sparsity_enum$$
    257 If $icode option_value$$ is $codei%atomic_base<%Base%>::bool_sparsity_enum%$$, 
     257If $icode option_value$$ is $codei%atomic_base<%Base%>::bool_sparsity_enum%$$,
    258258then the type used by $icode afun$$ for
    259259$cref/sparsity patterns/glossary/Sparsity Pattern/$$,
     
    262262        typedef CppAD::vector<bool> %atomic_sparsity%
    263263%$$
    264 If $icode r$$ is a sparsity pattern 
     264If $icode r$$ is a sparsity pattern
    265265for a matrix $latex R \in B^{p \times q}$$:
    266266$icode%r%.size() == %p% * %q%$$.
     
    268268$subhead set_sparsity_enum$$
    269269$index set_sparsity_enum$$
    270 If $icode option_value$$ is $icode%atomic_base<%Base%>::set_sparsity_enum%$$, 
     270If $icode option_value$$ is $icode%atomic_base<%Base%>::set_sparsity_enum%$$,
    271271then the type used by $icode afun$$ for
    272272$cref/sparsity patterns/glossary/Sparsity Pattern/$$,
     
    275275        typedef CppAD::vector< std::set<size_t> > %atomic_sparsity%
    276276%$$
    277 If $icode r$$ is a sparsity pattern 
     277If $icode r$$ is a sparsity pattern
    278278for a matrix $latex R \in B^{p \times q}$$:
    279279$icode%r%.size() == %p%$$, and for $latex i = 0 , \ldots , p-1$$,
    280 the elements of $icode%r%[%i%]%$$ are between zero and $latex q-1$$ inclusive. 
     280the elements of $icode%r%[%i%]%$$ are between zero and $latex q-1$$ inclusive.
    281281
    282282$end
     
    317317$head Purpose$$
    318318Given $icode ax$$,
    319 this call computes the corresponding value of $icode ay$$. 
     319this call computes the corresponding value of $icode ay$$.
    320320If $codei%AD<%Base%>%$$ operations are being recorded,
    321321it enters the computation as an atomic operation in the recording;
     
    328328
    329329$head afun$$
    330 is a $cref/atomic_user/atomic_ctor/atomic_user/$$ object 
     330is a $cref/atomic_user/atomic_ctor/atomic_user/$$ object
    331331and this $icode afun$$ function call is implemented by the
    332 $cref/atomic_base/atomic_ctor/atomic_base/$$ class. 
     332$cref/atomic_base/atomic_ctor/atomic_base/$$ class.
    333333
    334334$head ax$$
     
    338338%$$
    339339and size must be equal to $icode n$$.
    340 It specifies vector $latex x \in B^n$$ 
    341 at which an $codei%AD<%Base%>%$$ version of 
    342 $latex y = f(x)$$ is to be evaluated; see 
     340It specifies vector $latex x \in B^n$$
     341at which an $codei%AD<%Base%>%$$ version of
     342$latex y = f(x)$$ is to be evaluated; see
    343343$cref/Base/atomic_ctor/atomic_base/Base/$$.
    344344
     
    349349%$$
    350350and size must be equal to $icode m$$.
    351 The input values of its elements 
     351The input values of its elements
    352352are not specified (must not matter).
    353 Upon return, it is an $codei%AD<%Base%>%$$ version of 
     353Upon return, it is an $codei%AD<%Base%>%$$ version of
    354354$latex y = f(x)$$.
    355355
    356356$head Examples$$
    357 The following files contain example uses of 
     357The following files contain example uses of
    358358the AD version of atomic functions during recording:
    359359$cref%get_started.cpp%atomic_get_started.cpp%Use Atomic Function%Recording%$$,
     
    417417                ty.resize(m);
    418418        }
    419         // 
     419        //
    420420        // Determine tape corresponding to variables in ax
    421421        tape_id_t     tape_id  = 0;
     
    433433# ifndef NDEBUG
    434434                        if( tape_id != ax[j].tape_id_ )
    435                         {       msg += afun_name() + 
     435                        {       msg += afun_name() +
    436436                                ": ax contains variables from different threads.";
    437437                                CPPAD_ASSERT_KNOWN(false, msg.c_str());
     
    444444        set_id(id);
    445445# ifdef NDEBUG
    446         forward(p, q, vx, vy, tx, ty); 
     446        forward(p, q, vx, vy, tx, ty);
    447447# else
    448         ok = forward(p, q, vx, vy, tx, ty); 
     448        ok = forward(p, q, vx, vy, tx, ty);
    449449        if( ! ok )
    450450        {       msg += afun_name() + ": ok is false for "
     
    469469# ifndef NDEBUG
    470470        if( record_operation & (tape == CPPAD_NULL) )
    471         {       msg += 
     471        {       msg +=
    472472                "all elements of vx are false but vy contains a true element";
    473473                CPPAD_ASSERT_KNOWN(false, msg.c_str() );
     
    522522                tape->Rec_.PutArg(index_, id, n, m);
    523523                tape->Rec_.PutOp(UserOp);
    524         } 
     524        }
    525525        return;
    526526}
     
    560560This virtual function must be defined by the
    561561$cref/atomic_user/atomic_ctor/atomic_user/$$ class.
    562 It can just return $icode%ok% == false%$$ 
     562It can just return $icode%ok% == false%$$
    563563(and not compute anything) for values
    564564of $icode%q% > 0%$$ that are greater than those used by your
     
    570570        size_t %p%
    571571%$$
    572 It specifies the lowest order Taylor coefficient that we are evaluating. 
     572It specifies the lowest order Taylor coefficient that we are evaluating.
    573573During calls to $cref atomic_afun$$, $icode%p% == 0%$$.
    574574
     
    578578        size_t %q%
    579579%$$
    580 It specifies the highest order Taylor coefficient that we are evaluating. 
     580It specifies the highest order Taylor coefficient that we are evaluating.
    581581During calls to $cref atomic_afun$$, $icode%q% == 0%$$.
    582582
     
    586586        const CppAD::vector<bool>& %vx%
    587587%$$
    588 The case $icode%vx%.size() > 0%$$ only occurs while evaluating a call to 
     588The case $icode%vx%.size() > 0%$$ only occurs while evaluating a call to
    589589$cref atomic_afun$$.
    590590In this case,
    591 $icode%p% == %q% == 0%$$, 
     591$icode%p% == %q% == 0%$$,
    592592$icode%vx%.size() == %n%$$, and
    593593for $latex j = 0 , \ldots , n-1$$,
    594594$icode%vx%[%j%]%$$ is true if and only if
    595 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$ 
    596 in the corresponding call to 
     595$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$
     596in the corresponding call to
    597597$codei%
    598598        %afun%(%ax%, %ay%, %id%)
    599599%$$
    600 If $icode%vx%.size() == 0%$$, 
     600If $icode%vx%.size() == 0%$$,
    601601then $icode%vy%.size() == 0%$$ and neither of these vectors
    602602should be used.
     
    608608%$$
    609609If $icode%vy%.size() == 0%$$, it should not be used.
    610 Otherwise, 
     610Otherwise,
    611611$icode%q% == 0%$$ and $icode%vy%.size() == %m%$$.
    612 The input values of the elements of $icode vy$$ 
     612The input values of the elements of $icode vy$$
    613613are not specified (must not matter).
    614614Upon return, for $latex j = 0 , \ldots , m-1$$,
     
    665665        y_j^k = \frac{1}{ k ! } Y_j^{(k)} (0)
    666666\] $$
    667 If $latex p > 0$$, 
     667If $latex p > 0$$,
    668668for $latex i = 0 , \ldots , m-1$$ and $latex k = 0 , \ldots , p-1$$,
    669669the input of $icode ty$$ satisfies
     
    685685$latex \[
    686686\begin{array}{rcl}
    687 y_i^0 & = & Y(0) 
     687y_i^0 & = & Y(0)
    688688        = f_i ( x^0 )
    689689\\
    690 y_i^1 & = & Y^{(1)} ( 0 ) 
    691         = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 ) 
    692         = f_i^{(1)} ( x^0 ) x^1 
     690y_i^1 & = & Y^{(1)} ( 0 )
     691        = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 )
     692        = f_i^{(1)} ( x^0 ) x^1
    693693\\
    694 y_i^2 
     694y_i^2
    695695& = & \frac{1}{2 !} Y^{(2)} (0)
    696696\\
     
    698698  +   \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 )
    699699\\
    700 & = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1 
     700& = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1
    701701  +    f_i^{(1)} ( x^0 ) x^2
    702702\end{array}
    703703\] $$
    704 For $latex i = 0 , \ldots , m-1$$, and $latex k = 0 , 1 , 2$$, 
     704For $latex i = 0 , \ldots , m-1$$, and $latex k = 0 , 1 , 2$$,
    705705$latex \[
    706706        ty [ i * (q + 1) + k ] = y_i^k
     
    725725$cref%mat_mul.cpp%atomic_mat_mul.cpp%Use Atomic Function%forward%$$.
    726726
    727  
     727
    728728$end
    729729-----------------------------------------------------------------------------
    730730*/
    731731/*!
    732 Link from atomic_base to forward mode 
     732Link from atomic_base to forward mode
    733733
    734734\param p [in]
     
    750750Taylor coefficient corresponding to \c y for this calculation
    751751
    752 See the forward mode in user's documentation for base_atomic 
     752See the forward mode in user's documentation for base_atomic
    753753*/
    754754virtual bool forward(
     
    787787
    788788$head Purpose$$
    789 This function is used by $cref/reverse/Reverse/$$ 
     789This function is used by $cref/reverse/Reverse/$$
    790790to compute derivatives.
    791791
     
    795795this virtual function must be defined by the
    796796$cref/atomic_user/atomic_ctor/atomic_user/$$ class.
    797 It can just return $icode%ok% == false%$$ 
     797It can just return $icode%ok% == false%$$
    798798(and not compute anything) for values
    799799of $icode q$$ that are greater than those used by your
     
    859859
    860860$head F, G, H$$
    861 We use the notation $latex \{ x_j^k \} \in B^{n \times (q+1)}$$ for 
     861We use the notation $latex \{ x_j^k \} \in B^{n \times (q+1)}$$ for
    862862$latex \[
    863863        \{ x_j^k \W{:} j = 0 , \ldots , n-1, k = 0 , \ldots , q \}
    864 \]$$ 
    865 We use the notation $latex \{ y_i^k \} \in B^{m \times (q+1)}$$ for 
     864\]$$
     865We use the notation $latex \{ y_i^k \} \in B^{m \times (q+1)}$$ for
    866866$latex \[
    867867        \{ y_i^k \W{:} i = 0 , \ldots , m-1, k = 0 , \ldots , q \}
    868 \]$$ 
     868\]$$
    869869We define the function
    870870$latex F : B^{n \times (q+1)} \rightarrow B^{m \times (q+1)}$$ by
     
    897897%$$
    898898and $icode%px%.size() == n * (%q%+1)%$$.
    899 The input values of the elements of $icode px$$ 
     899The input values of the elements of $icode px$$
    900900are not specified (must not matter).
    901901Upon return,
     
    905905px [ j * (q + 1) + \ell ] & = & \partial H / \partial x_j^\ell
    906906\\
    907 & = & 
    908 ( \partial G / \partial \{ y_i^k \} ) 
     907& = &
     908( \partial G / \partial \{ y_i^k \} )
    909909        ( \partial \{ y_i^k \} / \partial x_j^\ell )
    910910\\
    911 & = & 
     911& = &
    912912\sum_{i=0}^{m-1} \sum_{k=0}^q
    913913( \partial G / \partial y_i^k ) ( \partial y_i^k / \partial x_j^\ell )
    914914\\
    915 & = & 
     915& = &
    916916\sum_{i=0}^{m-1} \sum_{k=\ell}^q
    917917py[ i * (q + 1 ) + k ] ( \partial F_i^k / \partial x_j^\ell )
     
    966966Partials w.r.t. the \c y Taylor coefficients.
    967967
    968 See atomic_reverse mode use documentation 
     968See atomic_reverse mode use documentation
    969969*/
    970970virtual bool reverse(
     
    10201020     size_t %q%
    10211021%$$
    1022 It specifies the number of columns in 
    1023 $latex R \in B^{n \times q}$$ and the Jacobian 
    1024 $latex S(x) \in B^{m \times q}$$. 
     1022It specifies the number of columns in
     1023$latex R \in B^{n \times q}$$ and the Jacobian
     1024$latex S(x) \in B^{m \times q}$$.
    10251025
    10261026$subhead r$$
     
    10291029     const %atomic_sparsity%& %r%
    10301030%$$
    1031 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for 
     1031and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    10321032$latex R \in B^{n \times q}$$.
    10331033
     
    10371037        %atomic_sparsity%& %s%
    10381038%$$
    1039 The input values of its elements 
     1039The input values of its elements
    10401040are not specified (must not matter).
    1041 Upon return, $icode s$$ is a 
    1042 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for 
     1041Upon return, $icode s$$ is a
     1042$cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    10431043$latex S(x) \in B^{m \times q}$$.
    10441044
     
    11401140     size_t %q%
    11411141%$$
    1142 It specifies the number of rows in 
    1143 $latex R \in B^{q \times m}$$ and the Jacobian 
    1144 $latex S(x) \in B^{q \times n}$$. 
     1142It specifies the number of rows in
     1143$latex R \in B^{q \times m}$$ and the Jacobian
     1144$latex S(x) \in B^{q \times n}$$.
    11451145
    11461146$subhead rt$$
     
    11491149     const %atomic_sparsity%& %rt%
    11501150%$$
    1151 and is a 
     1151and is a
    11521152$cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    11531153$latex R^\R{T} \in B^{m \times q}$$.
     
    11581158        %atomic_sparsity%& %st%
    11591159%$$
    1160 The input value of its elements 
     1160The input value of its elements
    11611161are not specified (must not matter).
    1162 Upon return, $icode s$$ is a 
     1162Upon return, $icode s$$ is a
    11631163$cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    1164 $latex S(x)^\R{T} \in B^{n \times q}$$. 
     1164$latex S(x)^\R{T} \in B^{n \times q}$$.
    11651165
    11661166$head ok$$
     
    12431243This function is used by $cref RevSparseHes$$ to compute
    12441244Hessian sparsity patterns.
    1245 There is an unspecified scalar valued function 
     1245There is an unspecified scalar valued function
    12461246$latex g : B^m \rightarrow B$$.
    1247 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for 
     1247Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for
    12481248$latex R \in B^{n \times q}$$,
    12491249and information about the function $latex z = g(y)$$,
     
    12661266for $latex j = 0 , \ldots , n-1$$,
    12671267$icode%vx%[%j%]%$$ is true if and only if
    1268 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$ 
    1269 in the corresponding call to 
     1268$icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$
     1269in the corresponding call to
    12701270$codei%
    12711271        %afun%(%ax%, %ay%, %id%)
     
    12771277     const CppAD:vector<bool>& %s%
    12781278%$$
    1279 and its size is $icode m$$. 
    1280 It is a sparsity pattern for 
     1279and its size is $icode m$$.
     1280It is a sparsity pattern for
    12811281$latex S(x) = g^{(1)} (y) \in B^{1 \times m}$$.
    12821282
     
    12871287%$$
    12881288and its size is $icode m$$.
    1289 The input values of its elements 
     1289The input values of its elements
    12901290are not specified (must not matter).
    1291 Upon return, $icode t$$ is a 
    1292 sparsity pattern for 
     1291Upon return, $icode t$$ is a
     1292sparsity pattern for
    12931293$latex T(x) \in B^{1 \times n}$$ where
    12941294$latex \[
     
    13011301     size_t %q%
    13021302%$$
    1303 It specifies the number of columns in 
     1303It specifies the number of columns in
    13041304$latex R \in B^{n \times q}$$,
    13051305$latex U(x) \in B^{m \times q}$$, and
    1306 $latex V(x) \in B^{n \times q}$$. 
     1306$latex V(x) \in B^{n \times q}$$.
    13071307
    13081308$subhead r$$
     
    13111311     const %atomic_sparsity%& %r%
    13121312%$$
    1313 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for 
     1313and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    13141314$latex R \in B^{n \times q}$$.
    13151315
     
    13191319     const %atomic_sparsity%& %u%
    13201320%$$
    1321 and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for 
     1321and is a $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    13221322$latex U(x) \in B^{m \times q}$$ which is defined by
    13231323$latex \[
    13241324\begin{array}{rcl}
    13251325U(x)
    1326 & = & 
     1326& = &
    13271327\partial_u \{ \partial_y g[ y + f^{(1)} (x) R u ] \}_{u=0}
    13281328\\
    1329 & = & 
     1329& = &
    13301330\partial_u \{ g^{(1)} [ y + f^{(1)} (x) R u ] \}_{u=0}
    13311331\\
     
    13401340     %atomic_sparsity%& %v%
    13411341%$$
    1342 The input value of its elements 
     1342The input value of its elements
    13431343are not specified (must not matter).
    1344 Upon return, $icode v$$ is a 
    1345 $cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for 
     1344Upon return, $icode v$$ is a
     1345$cref/atomic_sparsity/atomic_option/atomic_sparsity/$$ pattern for
    13461346$latex V(x) \in B^{n \times q}$$ which is defined by
    13471347$latex \[
    13481348\begin{array}{rcl}
    1349 V(x) 
    1350 & = & 
     1349V(x)
     1350& = &
    13511351\partial_u [ \partial_x (g \circ f) ( x + R u )  ]_{u=0}
    13521352\\
     
    14551455If an the $code atomic_base$$ object is global or static because,
    14561456the it does not get deleted.
    1457 This is a problem when using 
    1458 $code thread_alloc$$ $cref/free_all/ta_free_all/$$ 
    1459 to check that all allocated memory has been freed. 
     1457This is a problem when using
     1458$code thread_alloc$$ $cref/free_all/ta_free_all/$$
     1459to check that all allocated memory has been freed.
    14601460Calling this $code clear$$ function will free all the
    1461 memory currently being held onto by the 
     1461memory currently being held onto by the
    14621462$codei%atomic_base<%Base%>%$$ class.
    14631463
     
    15071507and has the corresponding id of the corresponding virtual call.
    15081508*/
    1509 virtual void set_id(size_t id) 
     1509virtual void set_id(size_t id)
    15101510{ }
    15111511// ---------------------------------------------------------------------------
  • trunk/cppad/local/checkpoint.hpp

    r3713 r3714  
    1515# include <cppad/local/sparse_set.hpp>
    1616# include <cppad/local/sparse_list.hpp>
     17# include <cppad/local/sparse_pack.hpp>
    1718
    1819namespace CppAD { // BEGIN_CPPAD_NAMESPACE
     
    184185        ADFun<Base> f_;
    185186        //
    186         /// sparsity for f(x)^{(1)}
    187         CPPAD_INTERNAL_SPARSE_SET  entire_jac_sparse_;
     187        /// sparsity for entire Jacobian f(x)^{(1)} does not change so can cache it
     188        CPPAD_INTERNAL_SPARSE_SET  jac_sparse_set_;
     189        vectorBool                 jac_sparse_bool_;
    188190        //
    189         /// sparsity for sum_i f_i(x)^{(2)}
    190         CPPAD_INTERNAL_SPARSE_SET  entire_hes_sparse_;
    191         //
    192         /// set entire_jac_sparse_
    193         void set_entire_jac_sparse(void)
    194         {       assert( entire_jac_sparse_.n_set() == 0 );
     191        /// sparsity for sum_i f_i(x)^{(2)} does not change so can cache it
     192        CPPAD_INTERNAL_SPARSE_SET  hes_sparse_set_;
     193        vectorBool                 hes_sparse_bool_;
     194        // ------------------------------------------------------------------------
     195        typename atomic_base<Base>::option_enum sparsity(void)
     196        {       return static_cast< atomic_base<Base>* >(this)->sparsity(); }
     197        // ------------------------------------------------------------------------
     198        /// set jac_sparse_set_
     199        void set_jac_sparse_set(void)
     200        {       CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
    195201                bool transpose  = false;
    196202                bool dependency = true;
     
    205211                                identity.add_element(j, j);
    206212                        f_.ForSparseJacCheckpoint(
    207                                 n, identity, transpose, dependency, entire_jac_sparse_
     213                                n, identity, transpose, dependency, jac_sparse_set_
    208214                        );
    209215                        f_.size_forward_set(0);
     
    215221                                identity.add_element(i, i);
    216222                        f_.RevSparseJacCheckpoint(
    217                                 m, identity, transpose, dependency, entire_jac_sparse_
     223                                m, identity, transpose, dependency, jac_sparse_set_
    218224                        );
    219225                }
     
    221227                CPPAD_ASSERT_UNKNOWN( f_.size_forward_bool() == 0 );
    222228        }
    223         //
    224         /// set entire_hes_sparse_
    225         void set_entire_hes_sparse(void)
    226         {       assert( entire_hes_sparse_.n_set() == 0 );
     229        /// set jac_sparse_bool_
     230        void set_jac_sparse_bool(void)
     231        {       CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == 0 );
     232                bool transpose  = false;
     233                bool dependency = true;
     234                size_t n = f_.Domain();
     235                size_t m = f_.Range();
     236                // Use the choice for forward / reverse that results in smaller
     237                // size for the sparsity pattern of all variables in the tape.
     238                if( n <= m )
     239                {       vectorBool identity(n * n);
     240                        for(size_t j = 0; j < n; j++)
     241                        {       for(size_t i = 0; i < n; i++)
     242                                        identity[ i * n + j ] = (i == j);
     243                        }
     244                        jac_sparse_bool_ = f_.ForSparseJac(
     245                                n, identity, transpose, dependency
     246                        );
     247                        f_.size_forward_bool(0);
     248                }
     249                else
     250                {       vectorBool identity(m * m);
     251                        for(size_t j = 0; j < m; j++)
     252                        {       for(size_t i = 0; i < m; i++)
     253                                        identity[ i * m + j ] = (i == j);
     254                        }
     255                        jac_sparse_bool_ = f_.RevSparseJac(
     256                                m, identity, transpose, dependency
     257                        );
     258                }
     259                CPPAD_ASSERT_UNKNOWN( f_.size_forward_bool() == 0 );
     260                CPPAD_ASSERT_UNKNOWN( f_.size_forward_set() == 0 );
     261        }
     262        // ------------------------------------------------------------------------
     263        /// set hes_sparse_set_
     264        void set_hes_sparse_set(void)
     265        {       CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == 0 );
    227266                size_t n = f_.Domain();
    228267                size_t m = f_.Range();
     
    234273
    235274                // set version of sparsity for n by n idendity matrix
    236                 vector< std::set<size_t> > identity(n);
     275                CPPAD_INTERNAL_SPARSE_SET identity;
     276                identity.resize(n, n);
    237277                for(size_t j = 0; j < n; j++)
    238                         identity[j].insert(j);
     278                        identity.add_element(j, j);
     279
     280                // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)}
     281                bool transpose  = false;
     282                bool dependency = false;
     283                f_.ForSparseJacCheckpoint(
     284                        n, identity, transpose, dependency, jac_sparse_set_
     285                );
     286                f_.RevSparseHesCheckpoint(
     287                        n, all_one, transpose, hes_sparse_set_
     288                );
     289                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == n );
     290                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.end()   == n );
     291                //
     292                // drop the forward sparsity results from f_
     293                f_.size_forward_set(0);
     294        }
     295        /// set hes_sparse_bool_
     296        void set_hes_sparse_bool(void)
     297        {       CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == 0 );
     298                size_t n = f_.Domain();
     299                size_t m = f_.Range();
     300                //
     301                // set version of sparsity for vector of all ones
     302                vectorBool all_one(m);
     303                for(size_t i = 0; i < m; i++)
     304                        all_one[i] = true;
     305
     306                // set version of sparsity for n by n idendity matrix
     307                vectorBool identity(n * n);
     308                for(size_t j = 0; j < n; j++)
     309                {       for(size_t i = 0; i < n; i++)
     310                                identity[ i * n + j ] = (i == j);
     311                }
    239312
    240313                // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)}
     
    242315                bool dependency = false;
    243316                f_.ForSparseJac(n, identity, transpose, dependency);
    244                 f_.RevSparseHesCheckpoint(
    245                         n, all_one, transpose, entire_hes_sparse_
    246                 );
    247                 CPPAD_ASSERT_UNKNOWN( entire_hes_sparse_.n_set() == n );
    248                 CPPAD_ASSERT_UNKNOWN( entire_hes_sparse_.end()   == n );
     317                hes_sparse_bool_ = f_.RevSparseHes(n, all_one, transpose);
     318                CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == n * n );
    249319                //
    250320                // drop the forward sparsity results from f_
    251                 f_.size_forward_set(0);
     321                f_.size_forward_bool(0);
     322                CPPAD_ASSERT_UNKNOWN( f_.size_forward_bool() == 0 );
     323                CPPAD_ASSERT_UNKNOWN( f_.size_forward_set() == 0 );
    252324        }
    253325public:
     326        // ------------------------------------------------------------------------
    254327        /*!
    255328        Constructor of a checkpoint object
     
    290363                // 2DO: add a debugging mode that checks for changes and aborts
    291364                f_.compare_change_count(0);
    292                 //
    293                 // set sparsity for entire Jacobian once and for all
    294                 set_entire_jac_sparse();
    295         }
     365        }
     366        // ------------------------------------------------------------------------
    296367        /*!
    297368        Implement the user call to <tt>atom_fun.size_var()</tt>.
     
    299370        size_t size_var(void)
    300371        {       return f_.size_var(); }
     372        // ------------------------------------------------------------------------
    301373        /*!
    302374        Implement the user call to <tt>atom_fun(ax, ay)</tt>.
     
    324396                this->atomic_base<Base>::operator()(ax, ay, id);
    325397        }
     398        // ------------------------------------------------------------------------
    326399        /*!
    327400        Link from user_atomic to forward mode
     
    348421                if( vx.size() == 0 )
    349422                {       // during user forward mode
    350                         if( entire_jac_sparse_.n_set() == 0 )
    351                                 entire_jac_sparse_.resize(0,0);
    352                         if( entire_hes_sparse_.n_set() == 0 )
    353                                 entire_hes_sparse_.resize(0,0);
     423                        if( jac_sparse_set_.n_set() != 0 )
     424                                jac_sparse_set_.resize(0,0);
     425                        if( jac_sparse_bool_.size() != 0 )
     426                                jac_sparse_bool_.clear();
     427                        //
     428                        if( hes_sparse_set_.n_set() != 0 )
     429                                hes_sparse_set_.resize(0,0);
     430                        if( hes_sparse_bool_.size() != 0 )
     431                                hes_sparse_bool_.clear();
    354432                }
    355433                if( vx.size() > 0 )
    356                 {       // during user recording using this checkpoint function
    357                         if( entire_jac_sparse_.n_set() == 0 )
    358                                 set_entire_jac_sparse();
    359                         assert( entire_jac_sparse_.n_set() == m );
    360                         assert( entire_jac_sparse_.end()   == n );
    361                         //
    362                         for(size_t i = 0; i < m; i++)
    363                         {       vy[i] = false;
    364                                 entire_jac_sparse_.begin(i);
    365                                 size_t j = entire_jac_sparse_.next_element();
    366                                 while(j < n )
    367                                 {       // y[i] depends on the value of x[j]
    368                                         vy[i] |= vx[j];
    369                                         j = entire_jac_sparse_.next_element();
     434                {       // need Jacobian sparsity pattern to determine variable relation
     435                        // during user recording using checkpoint functions
     436                        if( sparsity() == atomic_base<Base>::set_sparsity_enum )
     437                        {       if( jac_sparse_set_.n_set() == 0 )
     438                                        set_jac_sparse_set();
     439                                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == m );
     440                                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.end()   == n );
     441                                //
     442                                for(size_t i = 0; i < m; i++)
     443                                {       vy[i] = false;
     444                                        jac_sparse_set_.begin(i);
     445                                        size_t j = jac_sparse_set_.next_element();
     446                                        while(j < n )
     447                                        {       // y[i] depends on the value of x[j]
     448                                                vy[i] |= vx[j];
     449                                                j = jac_sparse_set_.next_element();
     450                                        }
     451                                }
     452                        }
     453                        else
     454                        {       if( jac_sparse_set_.n_set() != 0 )
     455                                        jac_sparse_set_.resize(0, 0);
     456                                if( jac_sparse_bool_.size() == 0 )
     457                                        set_jac_sparse_bool();
     458                                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
     459                                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
     460                                //
     461                                for(size_t i = 0; i < m; i++)
     462                                {       vy[i] = false;
     463                                        for(size_t j = 0; j < n; j++)
     464                                        {       if( jac_sparse_bool_[ i * n + j ] )
     465                                                {       // y[i] depends on the value of x[j]
     466                                                        vy[i] |= vx[j];
     467                                                }
     468                                        }
    370469                                }
    371470                        }
     
    381480                return ok;
    382481        }
     482        // ------------------------------------------------------------------------
    383483        /*!
    384484        Link from user_atomic to reverse mode
     
    427527                return ok;
    428528        }
     529        // ------------------------------------------------------------------------
    429530        /*!
    430531        Link from user_atomic to forward sparse Jacobian sets
     
    439540                size_t m = f_.Range();
    440541                size_t n = f_.Domain();
    441                 if( entire_jac_sparse_.n_set() == 0 )
    442                         set_entire_jac_sparse();
    443                 assert( entire_jac_sparse_.n_set() == m );
    444                 assert( entire_jac_sparse_.end()   == n );
    445                 assert( r.size() == n );
    446                 assert( s.size() == m );
     542                if( jac_sparse_bool_.size() != 0 )
     543                        jac_sparse_bool_.clear();
     544                if( jac_sparse_set_.n_set() == 0 )
     545                        set_jac_sparse_set();
     546                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == 0 );
     547                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == m );
     548                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.end()   == n );
     549                CPPAD_ASSERT_UNKNOWN( r.size() == n );
     550                CPPAD_ASSERT_UNKNOWN( s.size() == m );
    447551
    448552                bool ok = true;
     
    450554                        s[i].clear();
    451555
    452                 // sparsity for  s = entire_jac_sparse_ * r
     556                // sparsity for  s = jac_sparse_set_ * r
    453557                for(size_t i = 0; i < m; i++)
    454558                {       // compute row i of the return pattern
    455                         entire_jac_sparse_.begin(i);
    456                         size_t j = entire_jac_sparse_.next_element();
     559                        jac_sparse_set_.begin(i);
     560                        size_t j = jac_sparse_set_.next_element();
    457561                        while(j < n )
    458562                        {       std::set<size_t>::const_iterator itr_j;
     
    460564                                for(itr_j = r_j.begin(); itr_j != r_j.end(); itr_j++)
    461565                                {       size_t k = *itr_j;
    462                                         assert( k < q );
     566                                        CPPAD_ASSERT_UNKNOWN( k < q );
    463567                                        s[i].insert(k);
    464568                                }
    465                                 j = entire_jac_sparse_.next_element();
     569                                j = jac_sparse_set_.next_element();
    466570                        }
    467571                }
     
    481585                size_t m = f_.Range();
    482586                size_t n = f_.Domain();
    483                 if( entire_jac_sparse_.n_set() == 0 )
    484                         set_entire_jac_sparse();
    485                 assert( entire_jac_sparse_.n_set() == m );
    486                 assert( entire_jac_sparse_.end()   == n );
    487                 assert( r.size() == n * q );
    488                 assert( s.size() == m * q );
     587                if( jac_sparse_bool_.size() == 0 )
     588                        set_jac_sparse_bool();
     589                if( jac_sparse_set_.n_set() != 0 )
     590                        jac_sparse_set_.resize(0, 0);
     591                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
     592                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
     593                CPPAD_ASSERT_UNKNOWN( r.size() == n * q );
     594                CPPAD_ASSERT_UNKNOWN( s.size() == m * q );
    489595                //
    490596                bool ok = true;
     
    493599                                s[i * q + k] = false;
    494600                }
    495                 // sparsity for  s = entire_jac_sparse_ * r
     601                // sparsity for  s = jac_sparse_bool_ * r
    496602                for(size_t i = 0; i < m; i++)
    497603                {       // compute row i of the return pattern
    498                         entire_jac_sparse_.begin(i);
    499                         size_t j = entire_jac_sparse_.next_element();
    500                         while(j < n )
    501                         {       for(size_t k = 0; k < q; k++)
    502                                         s[i * q + k] |= r[j * q + k ];
    503                                 j = entire_jac_sparse_.next_element();
    504                         }
    505                 }
    506 
     604                        for(size_t j = 0; j < n; j++)
     605                        {       if( jac_sparse_bool_[ i * n + j] )
     606                                {       for(size_t k = 0; k < q; k++)
     607                                                s[i * q + k] |= r[j * q + k ];
     608                                }
     609                        }
     610                }
    507611                return ok;
    508612        }
     613        // ------------------------------------------------------------------------
    509614        /*!
    510615        Link from user_atomic to reverse Jacobian sets
     
    519624                size_t m = f_.Range();
    520625                size_t n = f_.Domain();
    521                 if( entire_jac_sparse_.n_set() == 0 )
    522                         set_entire_jac_sparse();
    523                 assert( entire_jac_sparse_.n_set() == m );
    524                 assert( entire_jac_sparse_.end()   == n );
    525                 assert( rt.size() == m );
    526                 assert( st.size() == n );
     626                if( jac_sparse_bool_.size() != 0 )
     627                        jac_sparse_bool_.clear();
     628                if( jac_sparse_set_.n_set() == 0 )
     629                        set_jac_sparse_set();
     630                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == 0 );
     631                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == m );
     632                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.end()   == n );
     633                CPPAD_ASSERT_UNKNOWN( rt.size() == m );
     634                CPPAD_ASSERT_UNKNOWN( st.size() == n );
    527635                //
    528636                bool ok  = true;
     
    531639                        st[j].clear();
    532640                //
    533                 // sparsity for  s = r * entire_jac_sparse_
    534                 // s^T = entire_jac_sparse_^T * r^T
     641                // sparsity for  s = r * jac_sparse_set_
     642                // s^T = jac_sparse_set_^T * r^T
    535643                for(size_t i = 0; i < m; i++)
    536644                {       // i is the row index in r^T
     
    540648                        {       // k is the column index in r^T
    541649                                size_t k = *itr_i;
    542                                 assert( k < q );
     650                                CPPAD_ASSERT_UNKNOWN( k < q );
    543651                                //
    544                                 // i is column index in entire_sparse_jac^T
    545                                 entire_jac_sparse_.begin(i);
    546                                 size_t j = entire_jac_sparse_.next_element();
     652                                // i is column index in jac_sparse_set^T
     653                                jac_sparse_set_.begin(i);
     654                                size_t j = jac_sparse_set_.next_element();
    547655                                while( j < n )
    548                                 {       // j is row index in entire_sparse_jac^T
     656                                {       // j is row index in jac_sparse_set^T
    549657                                        st[j].insert(k);
    550                                         j = entire_jac_sparse_.next_element();
     658                                        j = jac_sparse_set_.next_element();
    551659                                }
    552660                        }
     
    567675                size_t m = f_.Range();
    568676                size_t n = f_.Domain();
    569                 if( entire_jac_sparse_.n_set() == 0 )
    570                         set_entire_jac_sparse();
    571                 assert( entire_jac_sparse_.n_set() == m );
    572                 assert( entire_jac_sparse_.end()   == n );
    573                 assert( rt.size() == m * q );
    574                 assert( st.size() == n * q );
     677                if( jac_sparse_bool_.size() == 0 )
     678                        set_jac_sparse_bool();
     679                if( jac_sparse_set_.n_set() != 0 )
     680                        jac_sparse_set_.resize(0, 0);
     681                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
     682                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
     683                CPPAD_ASSERT_UNKNOWN( rt.size() == m * q );
     684                CPPAD_ASSERT_UNKNOWN( st.size() == n * q );
    575685                bool ok  = true;
    576686                //
     
    580690                }
    581691                //
    582                 // sparsity for  s = r * entire_jac_sparse_
    583                 // s^T = entire_jac_sparse_^T * r^T
     692                // sparsity for  s = r * jac_sparse_bool_
     693                // s^T = jac_sparse_bool_^T * r^T
    584694                for(size_t i = 0; i < m; i++)
    585695                {       // i is the row index in r^T
     
    587697                        {       // k is column index in r^T
    588698                                if( rt[i * q + k] )
    589                                 {       // i is column index in entire_sparse_jac^T
    590                                         entire_jac_sparse_.begin(i);
    591                                         size_t j = entire_jac_sparse_.next_element();
    592                                         while( j < n )
    593                                         {       st[j * q + k ] = true;
    594                                                 j = entire_jac_sparse_.next_element();
     699                                {       // i is column index in jac_sparse_bool_^T
     700                                        for(size_t j = 0; j < n; j++)
     701                                        {       if( jac_sparse_bool_[i * n + j] )
     702                                                        st[j * q + k ] = true;
    595703                                        }
    596704                                }
    597705                        }
    598706                }
    599 
    600707                return ok;
    601708        }
     709        // ------------------------------------------------------------------------
    602710        /*!
    603711        Link from user_atomic to reverse sparse Hessian sets
     
    624732                bool ok        = true;
    625733
    626                 // make sure entire_hes_sparse_ has been set
    627                 if( entire_hes_sparse_.n_set() == 0 )
    628                         set_entire_hes_sparse();
     734                // make sure hes_sparse_set_ has been set
     735                if( hes_sparse_bool_.size() != 0 )
     736                        hes_sparse_bool_.clear();
     737                if( hes_sparse_set_.n_set() == 0 )
     738                        set_hes_sparse_set();
     739                CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == 0 );
     740                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == n );
     741                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.end()   == n );
    629742
    630743                // compute sparsity pattern for T(x) = S(x) * f'(x)
     
    640753
    641754                // compute sparsity pattern for A(x) = f'(x)^T * U(x)
     755                // 2DO: change a to use INTERNAL_SPARSE_SET
    642756                bool transpose = true;
    643757                vector< std::set<size_t> > a(n);
     
    646760                // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,
    647761                // but use less efficient sparsity for  f(x)''(x) * R so that
    648                 // entire_hes_sparse_ can be used every time this is needed.
     762                // hes_sparse_set_ can be used every time this is needed.
    649763                for(size_t i = 0; i < n; i++)
    650764                {       v[i].clear();
    651                         entire_hes_sparse_.begin(i);
    652                         size_t j = entire_hes_sparse_.next_element();
     765                        hes_sparse_set_.begin(i);
     766                        size_t j = hes_sparse_set_.next_element();
    653767                        while( j < n )
    654768                        {       std::set<size_t>::const_iterator itr_j;
     
    658772                                        v[i].insert(k);
    659773                                }
    660                                 j = entire_hes_sparse_.next_element();
     774                                j = hes_sparse_set_.next_element();
    661775                        }
    662776                }
     
    697811                bool ok        = true;
    698812
    699                 // make sure entire_hes_sparse_ has been set
    700                 if( entire_hes_sparse_.n_set() == 0 )
    701                         set_entire_hes_sparse();
     813                // make sure hes_sparse_bool_ has been set
     814                if( hes_sparse_bool_.size() == 0 )
     815                        set_hes_sparse_bool();
     816                if( hes_sparse_set_.n_set() != 0 )
     817                        hes_sparse_set_.resize(0, 0);
     818                CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == n * n );
     819                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == 0 );
     820
    702821
    703822                // compute sparsity pattern for T(x) = S(x) * f'(x)
     
    713832
    714833                // compute sparsity pattern for A(x) = f'(x)^T * U(x)
     834                // 2DO: change a to use vectorBool
    715835                bool transpose = true;
    716836                vector<bool> a(n * q);
     
    719839                // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,
    720840                // but use less efficient sparsity for  f(x)''(x) * R so that
    721                 // entire_hes_sparse_ can be used every time this is needed.
     841                // hes_sparse_set_ can be used every time this is needed.
    722842                for(size_t i = 0; i < n; i++)
    723843                {       for(size_t k = 0; k < q; k++)
    724844                                v[i * q + k] = false;
    725                         entire_hes_sparse_.begin(i);
    726                         size_t j = entire_hes_sparse_.next_element();
    727                         while( j < n )
    728                         {       for(size_t k = 0; k < q; k++)
    729                                         v[i * q + k] |= r[ j * q + k ];
    730                                 j = entire_hes_sparse_.next_element();
     845                        for(size_t j = 0; j < n; j++)
     846                        {       if( hes_sparse_bool_[i * n + j] )
     847                                {       for(size_t k = 0; k < q; k++)
     848                                                v[i * q + k] |= r[ j * q + k ];
     849                                }
    731850                        }
    732851                }
     
    737856                                v[ i * q + k ] |= a[ i * q + k];
    738857                }
    739 
    740858                return ok;
    741859        }
  • trunk/cppad/local/for_sparse_jac.hpp

    r3712 r3714  
    793793On output, s is the sparsity pattern for the matrix \f$ S(x) \f$
    794794or \f$ S(x)^T \f$ depending on transpose.
     795
     796\par Side Effects
     797If \c VectorSet::value_type is \c bool,
     798the forward sparsity pattern for all of the variables on the
     799tape is stored in \c for_jac_sparse_pack__.
     800In this case
     801\verbatim
     802        for_jac_sparse_pack_.n_set() == num_var_tape_
     803        for_jac_sparse_pack_.end() == q
     804        for_jac_sparse_set_.n_set()  == 0
     805        for_jac_sparse_set_.end()  == 0
     806\endverbatim
     807\n
     808\n
     809If \c VectorSet::value_type is \c std::set<size_t>,
     810the forward sparsity pattern for all of the variables on the
     811tape is stored in \c for_jac_sparse_set__.
     812In this case
     813\verbatim
     814        for_jac_sparse_set_.n_set()   == num_var_tape_
     815        for_jac_sparse_set_.end()   == q
     816        for_jac_sparse_pack_.n_set()  == 0
     817        for_jac_sparse_pack_.end()  == 0
     818\endverbatim
    795819*/
    796820template <class Base>
     
    819843# endif
    820844
    821         // holds reverse Jacobian sparsity pattern for all variables
    822         CPPAD_INTERNAL_SPARSE_SET var_sparsity;
    823         var_sparsity.resize(num_var_tape_, q);
     845        // free all memory currently in sparsity patterns
     846        for_jac_sparse_pack_.resize(0, 0);
     847        for_jac_sparse_set_.resize(0, 0);
     848
     849        // allocate new sparsity pattern
     850        for_jac_sparse_set_.resize(num_var_tape_, q);
    824851
    825852        // set sparsity pattern for dependent variables
     
    829856                        size_t j = r.next_element();
    830857                        while( j < n )
    831                         {       var_sparsity.add_element( ind_taddr_[j], i );
     858                        {       for_jac_sparse_set_.add_element( ind_taddr_[j], i );
    832859                                j = r.next_element();
    833860                        }
     
    839866                        size_t i = r.next_element();
    840867                        while( i < q )
    841                         {       var_sparsity.add_element( ind_taddr_[j], i );
     868                        {       for_jac_sparse_set_.add_element( ind_taddr_[j], i );
    842869                                i = r.next_element();
    843870                        }
     
    851878                num_var_tape_,
    852879                &play_,
    853                 var_sparsity
     880                for_jac_sparse_set_
    854881        );
    855882
     
    864891        {       CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );
    865892
    866                 // extract the result from var_sparsity
    867                 CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );
    868                 var_sparsity.begin( dep_taddr_[i] );
    869                 size_t j = var_sparsity.next_element();
     893                // extract the result from for_jac_sparse_set_
     894                CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );
     895                for_jac_sparse_set_.begin( dep_taddr_[i] );
     896                size_t j = for_jac_sparse_set_.next_element();
    870897                while( j < q )
    871898                {       if( transpose )
     
    873900                        else
    874901                                s.add_element(i, j);
    875                         j  = var_sparsity.next_element();
     902                        j  = for_jac_sparse_set_.next_element();
    876903                }
    877904        }
  • trunk/omh/whats_new/whats_new_15.omh

    r3713 r3714  
    6161assist you in learning about changes between various versions of CppAD.
    6262
     63$head 08-29$$
     64Some asserts in the $cref checkpoint$$ implementation were not using
     65the CppAD $cref ErrorHandler$$. This has been fixed.
     66
    6367$head 08-28$$
    6468Free $cref checkpoint$$ function sparsity patters during
Note: See TracChangeset for help on using the changeset viewer.