Changeset 3717


Ignore:
Timestamp:
Aug 31, 2015 6:16:15 PM (4 years ago)
Author:
bradbell
Message:

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 54847d046ca10b16893f91cf125b2debdd697748
end hash code: 48d2f6a2d4b58dc317f3f05d20b5225ce2b832b9

commit 48d2f6a2d4b58dc317f3f05d20b5225ce2b832b9
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 12:50:52 2015 -0700

Implement and test pack sparsity virtual functions in checkpoint class.

commit ce33ebf8a9e7b963b12d1da0e97f3bd123bb73e7
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 10:41:32 2015 -0700

Remove invisible white space.

commit dc5e43c83f8932d84b56c0aa3bc8314a1d24aa15
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 10:41:09 2015 -0700

thread_alloc.hpp: remove incorrect mention of OpenMP.
sparsity.cpp: fix alignment array in documentation.

commit 4c293d006058258df8fdf38607f3884a790301a7
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 07:37:17 2015 -0700

Remove invisible white space.

commit 14eabcd0ad919e2ba229d95a11f14a13968d0fc2
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 07:37:03 2015 -0700

Move test_more/atomic_base -> example/atomic/sparsity.

commit e18aac40f8a0868e15e83df6c7faa0cb194af3d7
Author: Brad Bell <bradbell@…>
Date: Mon Aug 31 06:34:59 2015 -0700

Implement and test atomic_base pack sparsity.

commit 1d211f15f472ec38e676385634b8b5fc07d7fba4
Author: Brad Bell <bradbell@…>
Date: Sun Aug 30 08:42:30 2015 -0700

Add the pack type for atomic sparsity calculations and atomic_base.cpp test.
atomic_base.cpp: file that will be used to test atomic pack sparsity option.

commit 3607f0e483b00646e7dc0188fc2bbc639e537784
Author: Brad Bell <bradbell@…>
Date: Sun Aug 30 08:18:19 2015 -0700

Add pack to type of sparsity patterns supported by atomic functions (not yet used).

Location:
trunk
Files:
1 added
18 edited

Legend:

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

    r3715 r3717  
    2929// ===================================================================
    3030public:
    31         enum option_enum { bool_sparsity_enum, set_sparsity_enum};
     31        enum option_enum {
     32                pack_sparsity_enum   ,
     33                bool_sparsity_enum   ,
     34                set_sparsity_enum    ,
     35        };
    3236private:
    3337        // ------------------------------------------------------
     
    155159        atomic_base<%Base%>::option_enum %sparsity%
    156160%$$
    157 and its value is either
    158 $code atomic_base<%Base%>::bool_sparsity_enum$$ or
    159 $code atomic_base<%Base%>::set_sparsity_enum$$.
    160 There is a unspecified default value for $icode sparsity$$ if it is not
    161 included in the constructor.
    162 If the sparsity for this object is always bool (set),
    163 only the bool (set) versions of
    164 $cref atomic_for_sparse_jac$$,
    165 $cref atomic_rev_sparse_jac$$, and
    166 $cref atomic_rev_sparse_hes$$ need to be implemented.
     161The current $icode sparsity$$ for an $code atomic_base$$ object
     162determines which type of sparsity patterns it uses
     163and its value is one of the following:
     164$table
     165$icode sparsity$$   $cnext sparsity patterns $rnext
     166$codei%atomic_base<%Base%>::pack_sparsity_enum%$$ $pre  $$ $cnext
     167        $cref/vectorBool/CppAD_vector/vectorBool/$$
     168$rnext
     169$codei%atomic_base<%Base%>::bool_sparsity_enum%$$ $pre  $$ $cnext
     170        $cref/vector/CppAD_vector/$$$code <bool>$$
     171$rnext
     172$codei%atomic_base<%Base%>::set_sparsity_enum%$$ $pre  $$ $cnext
     173        $cref/vector/CppAD_vector/$$$code <std::set<std::size_t> >$$
     174$tend
     175There is a default value for $icode sparsity$$ if it is not
     176included in the constructor (which may be either the bool or set option).
    167177
    168178$head Examples$$
     
    207217\param sparsity [in]
    208218what type of sparsity patterns are computed by this function,
    209 bool_sparsity_enum or set_sparsity_enum. Default value is unspecified.
     219bool_sparsity_enum or set_sparsity_enum. Default value is
     220bool sparsity patterns.
    210221*/
    211222atomic_base(
     
    262273$head atomic_sparsity$$
    263274
     275$subhead pack_sparsity_enum$$
     276If $icode option_value$$ is $codei%atomic_base<%Base%>::pack_sparsity_enum%$$,
     277then the type used by $icode afun$$ for
     278$cref/sparsity patterns/glossary/Sparsity Pattern/$$,
     279(after the option is set) will be
     280$codei%
     281        typedef CppAD::vectorBool %atomic_sparsity%
     282%$$
     283If $icode r$$ is a sparsity pattern
     284for a matrix $latex R \in B^{p \times q}$$:
     285$icode%r%.size() == %p% * %q%$$.
     286
    264287$subhead bool_sparsity_enum$$
    265288If $icode option_value$$ is $codei%atomic_base<%Base%>::bool_sparsity_enum%$$,
     
    291314void option(enum option_enum option_value)
    292315{       switch( option_value )
    293         {       case bool_sparsity_enum:
     316        {       case pack_sparsity_enum:
     317                case bool_sparsity_enum:
    294318                case set_sparsity_enum:
    295319                sparsity_ = option_value;
     
    11011125              vector<bool>&                     s  )
    11021126{       return false; }
     1127virtual bool for_sparse_jac(
     1128        size_t                                  q  ,
     1129        const vectorBool&                       r  ,
     1130              vectorBool&                       s  )
     1131{       return false; }
    11031132/*
    11041133-------------------------------------- ---------------------------------------
     
    12211250        const vector<bool>&                     rt ,
    12221251              vector<bool>&                     st )
     1252{       return false; }
     1253virtual bool rev_sparse_jac(
     1254        size_t                                  q  ,
     1255        const vectorBool&                       rt ,
     1256              vectorBool&                       st )
    12231257{       return false; }
    12241258/*
     
    14381472        const vector<bool>&                     u  ,
    14391473              vector<bool>&                     v  )
     1474{       return false; }
     1475virtual bool rev_sparse_hes(
     1476        const vector<bool>&                     vx ,
     1477        const vector<bool>&                     s  ,
     1478              vector<bool>&                     t  ,
     1479        size_t                                  q  ,
     1480        const vectorBool&                       r  ,
     1481        const vectorBool&                       u  ,
     1482              vectorBool&                       v  )
    14401483{       return false; }
    14411484/*
  • trunk/cppad/local/checkpoint.hpp

    r3715 r3717  
    5555checkpointing functions of the form $latex y = f(x)$$ where
    5656$latex f : B^n \rightarrow B^m$$.
     57It may also reduce the time to make a recording at different
     58independent variable values.
     59(The checkpoint recording can not depend on independent variables but the
     60recording that uses it may.)
    5761
    5862$head Method$$
     
    129133It specifies $cref/sparsity/atomic_ctor/atomic_base/sparsity/$$
    130134in the $code atomic_base$$ constructor and must be either
     135$codei%atomic_base<%Base%>::pack_sparsity_enum%$$,
    131136$codei%atomic_base<%Base%>::bool_sparsity_enum%$$, or
    132137$codei%atomic_base<%Base%>::set_sparsity_enum%$$.
     
    341346                CPPAD_ASSERT_UNKNOWN( f_.size_forward_set() == 0 );
    342347        }
     348        // ------------------------------------------------------------------------
     349        /*!
     350        Link from user_atomic to forward sparse Jacobian pack and bool
     351
     352        \copydetails atomic_base::for_sparse_jac
     353        */
     354        template <class sparsity_type>
     355        bool for_sparse_jac(
     356                size_t                                  q  ,
     357                const sparsity_type&                    r  ,
     358                      sparsity_type&                    s  )
     359        {       // during user sparsity calculations
     360                size_t m = f_.Range();
     361                size_t n = f_.Domain();
     362                if( jac_sparse_bool_.size() == 0 )
     363                        set_jac_sparse_bool();
     364                if( jac_sparse_set_.n_set() != 0 )
     365                        jac_sparse_set_.resize(0, 0);
     366                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
     367                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
     368                CPPAD_ASSERT_UNKNOWN( r.size() == n * q );
     369                CPPAD_ASSERT_UNKNOWN( s.size() == m * q );
     370                //
     371                bool ok = true;
     372                for(size_t i = 0; i < m; i++)
     373                {       for(size_t k = 0; k < q; k++)
     374                                s[i * q + k] = false;
     375                }
     376                // sparsity for  s = jac_sparse_bool_ * r
     377                for(size_t i = 0; i < m; i++)
     378                {       // compute row i of the return pattern
     379                        for(size_t j = 0; j < n; j++)
     380                        {       if( jac_sparse_bool_[ i * n + j] )
     381                                {       for(size_t k = 0; k < q; k++)
     382                                                // s[i * q + k] |= r[j * q + k ];
     383                                                s[i * q + k] = bool(s[i * q + k]) | bool(r[j * q + k]);
     384                                }
     385                        }
     386                }
     387                return ok;
     388        }
     389        // ------------------------------------------------------------------------
     390        /*!
     391        Link from user_atomic to reverse sparse Jacobian pack and bool
     392
     393        \copydetails atomic_base::rev_sparse_jac
     394        */
     395        template <class sparsity_type>
     396        bool rev_sparse_jac(
     397                size_t                                  q  ,
     398                const sparsity_type&                    rt ,
     399                      sparsity_type&                    st )
     400        {       // during user sparsity calculations
     401                size_t m = f_.Range();
     402                size_t n = f_.Domain();
     403                if( jac_sparse_bool_.size() == 0 )
     404                        set_jac_sparse_bool();
     405                if( jac_sparse_set_.n_set() != 0 )
     406                        jac_sparse_set_.resize(0, 0);
     407                CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
     408                CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
     409                CPPAD_ASSERT_UNKNOWN( rt.size() == m * q );
     410                CPPAD_ASSERT_UNKNOWN( st.size() == n * q );
     411                bool ok  = true;
     412                //
     413                for(size_t j = 0; j < n; j++)
     414                {       for(size_t k = 0; k < q; k++)
     415                                st[j * q + k] = false;
     416                }
     417                //
     418                // sparsity for  s = r * jac_sparse_bool_
     419                // s^T = jac_sparse_bool_^T * r^T
     420                for(size_t i = 0; i < m; i++)
     421                {       // i is the row index in r^T
     422                        for(size_t k = 0; k < q; k++)
     423                        {       // k is column index in r^T
     424                                if( rt[i * q + k] )
     425                                {       // i is column index in jac_sparse_bool_^T
     426                                        for(size_t j = 0; j < n; j++)
     427                                        {       if( jac_sparse_bool_[i * n + j] )
     428                                                        st[j * q + k ] = true;
     429                                        }
     430                                }
     431                        }
     432                }
     433                return ok;
     434        }
     435        /*!
     436        Link from user_atomic to reverse sparse Hessian  bools
     437
     438        \copydetails atomic_base::rev_sparse_hes
     439        */
     440        template <class sparsity_type>
     441        bool rev_sparse_hes(
     442                const vector<bool>&                     vx ,
     443                const vector<bool>&                     s  ,
     444                      vector<bool>&                     t  ,
     445                size_t                                  q  ,
     446                const sparsity_type&                    r  ,
     447                const sparsity_type&                    u  ,
     448                      sparsity_type&                    v  )
     449        {       size_t n = f_.Domain();
     450                size_t m = f_.Range();
     451                CPPAD_ASSERT_UNKNOWN( vx.size() == n );
     452                CPPAD_ASSERT_UNKNOWN(  s.size() == m );
     453                CPPAD_ASSERT_UNKNOWN(  t.size() == n );
     454                CPPAD_ASSERT_UNKNOWN(  r.size() == n * q );
     455                CPPAD_ASSERT_UNKNOWN(  u.size() == m * q );
     456                CPPAD_ASSERT_UNKNOWN(  v.size() == n * q );
     457                //
     458                bool ok        = true;
     459
     460                // make sure hes_sparse_bool_ has been set
     461                if( hes_sparse_bool_.size() == 0 )
     462                        set_hes_sparse_bool();
     463                if( hes_sparse_set_.n_set() != 0 )
     464                        hes_sparse_set_.resize(0, 0);
     465                CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == n * n );
     466                CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == 0 );
     467
     468
     469                // compute sparsity pattern for T(x) = S(x) * f'(x)
     470                t = f_.RevSparseJac(1, s);
     471# ifndef NDEBUG
     472                for(size_t j = 0; j < n; j++)
     473                        CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] )
     474# endif
     475
     476                // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R
     477                // U(x) = g''(y) * f'(x) * R
     478                // S(x) = g'(y)
     479
     480                // compute sparsity pattern for A(x) = f'(x)^T * U(x)
     481                bool transpose = true;
     482                sparsity_type a(n * q);
     483                a = f_.RevSparseJac(q, u, transpose);
     484
     485                // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,
     486                // but use less efficient sparsity for  f(x)''(x) * R so that
     487                // hes_sparse_set_ can be used every time this is needed.
     488                for(size_t i = 0; i < n; i++)
     489                {       for(size_t k = 0; k < q; k++)
     490                                v[i * q + k] = false;
     491                        for(size_t j = 0; j < n; j++)
     492                        {       if( hes_sparse_bool_[i * n + j] )
     493                                {       for(size_t k = 0; k < q; k++)
     494                                                // v[i * q + k] |= r[ j * q + k ];
     495                                                v[i * q + k] = bool(v[i*q + k]) | bool(r[j*q + k]);
     496                                }
     497                        }
     498                }
     499
     500                // compute sparsity pattern for V(x) = A(x) + H(x)
     501                for(size_t i = 0; i < n; i++)
     502                {       for(size_t k = 0; k < q; k++)
     503                                // v[ i * q + k ] |= a[ i * q + k];
     504                                v[ i * q + k ] = bool(v[ i * q + k]) | bool(a[ i * q + k]);
     505                }
     506                return ok;
     507        }
    343508public:
    344509        // ------------------------------------------------------------------------
     
    556721        // ------------------------------------------------------------------------
    557722        /*!
     723        Link from user_atomic to forward sparse Jacobian pack
     724
     725        \copydetails atomic_base::for_sparse_jac
     726        */
     727        virtual bool for_sparse_jac(
     728                size_t                                  q  ,
     729                const vectorBool&                       r  ,
     730                      vectorBool&                       s  )
     731        {       return for_sparse_jac< vectorBool >(q, r, s);
     732        }
     733        /*!
     734        Link from user_atomic to forward sparse Jacobian bool
     735
     736        \copydetails atomic_base::for_sparse_jac
     737        */
     738        virtual bool for_sparse_jac(
     739                size_t                                  q  ,
     740                const vector<bool>&                     r  ,
     741                      vector<bool>&                     s  )
     742        {       return for_sparse_jac< vector<bool> >(q, r, s);
     743        }
     744        /*!
    558745        Link from user_atomic to forward sparse Jacobian sets
    559746
     
    600787                return ok;
    601788        }
    602         /*!
    603         Link from user_atomic to forward sparse Jacobian bools
    604 
    605         \copydetails atomic_base::for_sparse_jac
    606         */
    607         virtual bool for_sparse_jac(
    608                 size_t                                  q  ,
    609                 const vector<bool>&                     r  ,
    610                       vector<bool>&                     s  )
    611         {       // during user sparsity calculations
    612                 size_t m = f_.Range();
    613                 size_t n = f_.Domain();
    614                 if( jac_sparse_bool_.size() == 0 )
    615                         set_jac_sparse_bool();
    616                 if( jac_sparse_set_.n_set() != 0 )
    617                         jac_sparse_set_.resize(0, 0);
    618                 CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
    619                 CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
    620                 CPPAD_ASSERT_UNKNOWN( r.size() == n * q );
    621                 CPPAD_ASSERT_UNKNOWN( s.size() == m * q );
    622                 //
    623                 bool ok = true;
    624                 for(size_t i = 0; i < m; i++)
    625                 {       for(size_t k = 0; k < q; k++)
    626                                 s[i * q + k] = false;
    627                 }
    628                 // sparsity for  s = jac_sparse_bool_ * r
    629                 for(size_t i = 0; i < m; i++)
    630                 {       // compute row i of the return pattern
    631                         for(size_t j = 0; j < n; j++)
    632                         {       if( jac_sparse_bool_[ i * n + j] )
    633                                 {       for(size_t k = 0; k < q; k++)
    634                                                 s[i * q + k] |= r[j * q + k ];
    635                                 }
    636                         }
    637                 }
    638                 return ok;
    639         }
    640         // ------------------------------------------------------------------------
     789        // ------------------------------------------------------------------------
     790        /*!
     791        Link from user_atomic to reverse sparse Jacobian pack
     792
     793        \copydetails atomic_base::rev_sparse_jac
     794        */
     795        virtual bool rev_sparse_jac(
     796                size_t                                  q  ,
     797                const vectorBool&                       rt ,
     798                      vectorBool&                       st )
     799        {       return rev_sparse_jac< vectorBool >(q, rt, st);
     800        }
     801        /*!
     802        Link from user_atomic to reverse sparse Jacobian bool
     803
     804        \copydetails atomic_base::rev_sparse_jac
     805        */
     806        virtual bool rev_sparse_jac(
     807                size_t                                  q  ,
     808                const vector<bool>&                     rt ,
     809                      vector<bool>&                     st )
     810        {       return rev_sparse_jac< vector<bool> >(q, rt, st);
     811        }
    641812        /*!
    642813        Link from user_atomic to reverse Jacobian sets
     
    690861                return ok;
    691862        }
    692         /*!
    693         Link from user_atomic to reverse sparse Jacobian sets
    694 
    695         \copydetails atomic_base::rev_sparse_jac
    696         */
    697         virtual bool rev_sparse_jac(
    698                 size_t                                  q  ,
    699                 const vector<bool>&                     rt ,
    700                       vector<bool>&                     st )
    701         {       // during user sparsity calculations
    702                 size_t m = f_.Range();
    703                 size_t n = f_.Domain();
    704                 if( jac_sparse_bool_.size() == 0 )
    705                         set_jac_sparse_bool();
    706                 if( jac_sparse_set_.n_set() != 0 )
    707                         jac_sparse_set_.resize(0, 0);
    708                 CPPAD_ASSERT_UNKNOWN( jac_sparse_bool_.size() == m * n );
    709                 CPPAD_ASSERT_UNKNOWN( jac_sparse_set_.n_set() == 0 );
    710                 CPPAD_ASSERT_UNKNOWN( rt.size() == m * q );
    711                 CPPAD_ASSERT_UNKNOWN( st.size() == n * q );
    712                 bool ok  = true;
    713                 //
    714                 for(size_t j = 0; j < n; j++)
    715                 {       for(size_t k = 0; k < q; k++)
    716                                 st[j * q + k] = false;
    717                 }
    718                 //
    719                 // sparsity for  s = r * jac_sparse_bool_
    720                 // s^T = jac_sparse_bool_^T * r^T
    721                 for(size_t i = 0; i < m; i++)
    722                 {       // i is the row index in r^T
    723                         for(size_t k = 0; k < q; k++)
    724                         {       // k is column index in r^T
    725                                 if( rt[i * q + k] )
    726                                 {       // i is column index in jac_sparse_bool_^T
    727                                         for(size_t j = 0; j < n; j++)
    728                                         {       if( jac_sparse_bool_[i * n + j] )
    729                                                         st[j * q + k ] = true;
    730                                         }
    731                                 }
    732                         }
    733                 }
    734                 return ok;
    735         }
    736         // ------------------------------------------------------------------------
     863        // ------------------------------------------------------------------------
     864        /*!
     865        Link from user_atomic to reverse sparse Hessian pack
     866
     867        \copydetails atomic_base::rev_sparse_hes
     868        */
     869        virtual bool rev_sparse_hes(
     870                const vector<bool>&                     vx ,
     871                const vector<bool>&                     s  ,
     872                      vector<bool>&                     t  ,
     873                size_t                                  q  ,
     874                const vectorBool&                       r  ,
     875                const vectorBool&                       u  ,
     876                      vectorBool&                       v  )
     877        {       return rev_sparse_hes< vectorBool >(vx, s, t, q, r, u, v);
     878        }
     879        /*!
     880        Link from user_atomic to reverse sparse Hessian bool
     881
     882        \copydetails atomic_base::rev_sparse_hes
     883        */
     884        virtual bool rev_sparse_hes(
     885                const vector<bool>&                     vx ,
     886                const vector<bool>&                     s  ,
     887                      vector<bool>&                     t  ,
     888                size_t                                  q  ,
     889                const vector<bool>&                     r  ,
     890                const vector<bool>&                     u  ,
     891                      vector<bool>&                     v  )
     892        {       return rev_sparse_hes< vector<bool> >(vx, s, t, q, r, u, v);
     893        }
    737894        /*!
    738895        Link from user_atomic to reverse sparse Hessian sets
     
    814971                return ok;
    815972        }
    816         /*!
    817         Link from user_atomic to reverse sparse Hessian  bools
    818 
    819         \copydetails atomic_base::rev_sparse_hes
    820         */
    821         virtual bool rev_sparse_hes(
    822                 const vector<bool>&                     vx ,
    823                 const vector<bool>&                     s  ,
    824                       vector<bool>&                     t  ,
    825                 size_t                                  q  ,
    826                 const vector<bool>&                     r  ,
    827                 const vector<bool>&                     u  ,
    828                       vector<bool>&                     v  )
    829         {       size_t n = f_.Domain();
    830                 size_t m = f_.Range();
    831                 CPPAD_ASSERT_UNKNOWN( vx.size() == n );
    832                 CPPAD_ASSERT_UNKNOWN(  s.size() == m );
    833                 CPPAD_ASSERT_UNKNOWN(  t.size() == n );
    834                 CPPAD_ASSERT_UNKNOWN(  r.size() == n * q );
    835                 CPPAD_ASSERT_UNKNOWN(  u.size() == m * q );
    836                 CPPAD_ASSERT_UNKNOWN(  v.size() == n * q );
    837                 //
    838                 bool ok        = true;
    839 
    840                 // make sure hes_sparse_bool_ has been set
    841                 if( hes_sparse_bool_.size() == 0 )
    842                         set_hes_sparse_bool();
    843                 if( hes_sparse_set_.n_set() != 0 )
    844                         hes_sparse_set_.resize(0, 0);
    845                 CPPAD_ASSERT_UNKNOWN( hes_sparse_bool_.size() == n * n );
    846                 CPPAD_ASSERT_UNKNOWN( hes_sparse_set_.n_set() == 0 );
    847 
    848 
    849                 // compute sparsity pattern for T(x) = S(x) * f'(x)
    850                 t = f_.RevSparseJac(1, s);
    851 # ifndef NDEBUG
    852                 for(size_t j = 0; j < n; j++)
    853                         CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] )
    854 # endif
    855 
    856                 // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R
    857                 // U(x) = g''(y) * f'(x) * R
    858                 // S(x) = g'(y)
    859 
    860                 // compute sparsity pattern for A(x) = f'(x)^T * U(x)
    861                 // 2DO: change a to use vectorBool
    862                 bool transpose = true;
    863                 vector<bool> a(n * q);
    864                 a = f_.RevSparseJac(q, u, transpose);
    865 
    866                 // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,
    867                 // but use less efficient sparsity for  f(x)''(x) * R so that
    868                 // hes_sparse_set_ can be used every time this is needed.
    869                 for(size_t i = 0; i < n; i++)
    870                 {       for(size_t k = 0; k < q; k++)
    871                                 v[i * q + k] = false;
    872                         for(size_t j = 0; j < n; j++)
    873                         {       if( hes_sparse_bool_[i * n + j] )
    874                                 {       for(size_t k = 0; k < q; k++)
    875                                                 v[i * q + k] |= r[ j * q + k ];
    876                                 }
    877                         }
    878                 }
    879 
    880                 // compute sparsity pattern for V(x) = A(x) + H(x)
    881                 for(size_t i = 0; i < n; i++)
    882                 {       for(size_t k = 0; k < q; k++)
    883                                 v[ i * q + k ] |= a[ i * q + k];
    884                 }
    885                 return ok;
    886         }
    887973};
    888974
  • trunk/cppad/local/for_jac_sweep.hpp

    r3709 r3717  
    170170        vector<bool>       bool_s;   // bool sparisty pattern for the result y
    171171        //
     172        vectorBool         pack_r;   // pack sparsity pattern for the argument x
     173        vectorBool         pack_s;   // pack sparisty pattern for the result y
     174        //
    172175        const size_t user_q = limit; // maximum element plus one
    173176        size_t user_index = 0;       // indentifier for this atomic operation
     
    179182        //
    180183        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
    181         bool               user_bool = false;      // use bool or set sparsity ?
     184        bool               user_pack = false;      // sparsity pattern type is pack
     185        bool               user_bool = false;      // sparsity pattern type is bool
     186        bool               user_set  = false;      // sparsity pattern type is set
    182187# ifndef NDEBUG
    183188        bool               user_ok   = false;      // atomic op return value
     
    645650                                }
    646651# endif
     652                                user_pack  = user_atom->sparsity() ==
     653                                                        atomic_base<Base>::pack_sparsity_enum;
    647654                                user_bool  = user_atom->sparsity() ==
    648655                                                        atomic_base<Base>::bool_sparsity_enum;
     656                                user_set   = user_atom->sparsity() ==
     657                                                        atomic_base<Base>::set_sparsity_enum;
     658                                CPPAD_ASSERT_UNKNOWN( user_pack || user_bool || user_set );
     659                                if( user_pack )
     660                                {       if( pack_r.size() != user_n * user_q )
     661                                                pack_r.resize( user_n * user_q );
     662                                        if( pack_s.size() != user_m * user_q )
     663                                                pack_s.resize( user_m * user_q );
     664                                        for(i = 0; i < user_n; i++)
     665                                                for(j = 0; j < user_q; j++)
     666                                                        pack_r[ i * user_q + j] = false;
     667                                }
    649668                                if( user_bool )
    650669                                {       if( bool_r.size() != user_n * user_q )
     
    656675                                                        bool_r[ i * user_q + j] = false;
    657676                                }
    658                                 else
     677                                if( user_set)
    659678                                {       if(set_r.size() != user_n )
    660679                                                set_r.resize(user_n);
     
    678697                                {       std::string msg =
    679698                                                atomic_base<Base>::class_name(user_index)
    680                                                 + ": atomic_base.for_sparse_jac: returned false";
     699                                                + ": atomic_base.for_sparse_jac: returned false\n";
     700                                        if( user_pack )
     701                                                msg += "sparsity = pack_sparsity_enum";
     702                                        if( user_bool )
     703                                                msg += "sparsity = bool_sparsity_enum";
     704                                        if( user_set )
     705                                                msg += "sparsity = set_sparsity_enum";
    681706                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
    682707                                }
     
    696721                        {       // call users function for this operation
    697722                                user_atom->set_id(user_id);
     723                                if( user_pack )
     724                                        CPPAD_ATOMIC_CALL( user_q, pack_r, pack_s);
    698725                                if( user_bool )
    699                                         CPPAD_ATOMIC_CALL(
    700                                                 user_q, bool_r, bool_s
    701                                 );
    702                                 else
    703                                         CPPAD_ATOMIC_CALL(
    704                                                 user_q, set_r, set_s
    705                                 );
     726                                        CPPAD_ATOMIC_CALL( user_q, bool_r, bool_s);
     727                                if( user_set )
     728                                        CPPAD_ATOMIC_CALL( user_q, set_r, set_s);
    706729                                user_state = user_ret;
    707730                        }
     
    717740                        i = var_sparsity.next_element();
    718741                        while( i < user_q )
    719                         {       if( user_bool )
     742                        {       if( user_pack )
     743                                        pack_r[user_j * user_q + i] = true;
     744                                if( user_bool )
    720745                                        bool_r[user_j * user_q + i] = true;
    721                                 else
     746                                if( user_set )
    722747                                        set_r[user_j].insert(i);
    723748                                i = var_sparsity.next_element();
     
    727752                        {       // call users function for this operation
    728753                                user_atom->set_id(user_id);
     754                                if( user_pack )
     755                                        CPPAD_ATOMIC_CALL( user_q, pack_r, pack_s);
    729756                                if( user_bool )
    730                                         CPPAD_ATOMIC_CALL(
    731                                                 user_q, bool_r, bool_s
    732                                 );
    733                                 else
    734                                         CPPAD_ATOMIC_CALL(
    735                                                 user_q, set_r, set_s
    736                                 );
     757                                        CPPAD_ATOMIC_CALL( user_q, bool_r, bool_s);
     758                                if( user_set )
     759                                        CPPAD_ATOMIC_CALL( user_q, set_r, set_s);
    737760                                user_state = user_ret;
    738761                        }
     
    754777                        // It might be faster if we add set union to var_sparsity
    755778                        // where one of the sets is not in var_sparsity
     779                        if( user_pack )
     780                        {       for(j = 0; j < user_q; j++)
     781                                        if( pack_s[ user_i * user_q + j ] )
     782                                                var_sparsity.add_element(i_var, j);
     783                        }
    756784                        if( user_bool )
    757785                        {       for(j = 0; j < user_q; j++)
     
    759787                                                var_sparsity.add_element(i_var, j);
    760788                        }
    761                         else
     789                        if( user_set )
    762790                        {       set_itr = set_s[user_i].begin();
    763791                                set_end = set_s[user_i].end();
  • trunk/cppad/local/rev_hes_sweep.hpp

    r3685 r3717  
    178178        vector<bool>       bool_v;   // bool reverse Hessian sparsity for x
    179179        //
     180        vectorBool         pack_r;   // pack forward Jacobian sparsity for x
     181        vectorBool         pack_u;   // pack reverse Hessian sparsity for y
     182        vectorBool         pack_v;   // pack reverse Hessian sparsity for x
     183        //
    180184        vector<bool>       user_vx;  // which components of x are variables
    181185        vector<bool>       user_s;   // reverse Jacobian sparsity for y
     
    190194        //
    191195        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
    192         bool               user_bool = false;      // use bool or set sparsity ?
     196        bool               user_pack = false;      // sparsity pattern type is pack
     197        bool               user_bool = false;      // sparsity pattern type is bool
     198        bool               user_set  = false;      // sparsity pattern type is set
    193199# ifndef NDEBUG
    194200        bool               user_ok   = false;      // atomic op return value
     
    664670                                }
    665671# endif
     672                                user_pack  = user_atom->sparsity() ==
     673                                                        atomic_base<Base>::pack_sparsity_enum;
    666674                                user_bool  = user_atom->sparsity() ==
    667675                                                        atomic_base<Base>::bool_sparsity_enum;
     676                                user_set   = user_atom->sparsity() ==
     677                                                        atomic_base<Base>::set_sparsity_enum;
     678                                CPPAD_ASSERT_UNKNOWN( user_pack || user_bool || user_set );
    668679                                user_ix.resize(user_n);
    669680                                user_vx.resize(user_n);
     
    676687                                for(i = 0; i < user_n; i++)
    677688                                        user_t[i] = false;
     689                                if( user_pack )
     690                                {       pack_r.resize(user_n * user_q);
     691                                        pack_u.resize(user_m * user_q);
     692                                        pack_v.resize(user_n * user_q);
     693                                        // simpler to initialize all patterns as empty
     694                                        for(i = 0; i < user_m; i++)
     695                                        {
     696                                                for(j = 0; j < user_q; j++)
     697                                                        pack_u[ i * user_q + j] = false;
     698                                        }
     699                                        for(i = 0; i < user_n; i++)
     700                                        {
     701                                                for(j = 0; j < user_q; j++)
     702                                                {       pack_r[ i * user_q + j] = false;
     703                                                        pack_v[ i * user_q + j] = false;
     704                                                }
     705                                        }
     706                                }
    678707                                if( user_bool )
    679708                                {       bool_r.resize(user_n * user_q);
     
    694723                                        }
    695724                                }
    696                                 else
     725                                if( user_set )
    697726                                {       set_r.resize(user_n);
    698727                                        set_u.resize(user_m);
     
    720749                                user_atom->set_id(user_id);
    721750# ifdef NDEBUG
    722                                 if( user_bool )
     751                                if( user_pack )
     752                                        user_atom->rev_sparse_hes(user_vx,
     753                                                user_s, user_t, user_q, pack_r, pack_u, pack_v
     754                                );
     755                                if( user_bool )
    723756                                        user_atom->rev_sparse_hes(user_vx,
    724757                                                user_s, user_t, user_q, bool_r, bool_u, bool_v
    725758                                );
    726                                 else
     759                                if( user_set )
    727760                                        user_atom->rev_sparse_hes(user_vx,
    728761                                                user_s, user_t, user_q, set_r, set_u, set_v
    729762                                );
    730763# else
    731                                 if( user_bool )
     764                                if( user_pack )
     765                                        user_ok = user_atom->rev_sparse_hes(user_vx,
     766                                                user_s, user_t, user_q, pack_r, pack_u, pack_v
     767                                );
     768                                if( user_bool )
    732769                                        user_ok = user_atom->rev_sparse_hes(user_vx,
    733770                                                user_s, user_t, user_q, bool_r, bool_u, bool_v
    734771                                );
    735                                 else
     772                                if( user_set )
    736773                                        user_ok = user_atom->rev_sparse_hes(user_vx,
    737774                                                user_s, user_t, user_q, set_r, set_u, set_v
     
    740777                                {       std::string msg =
    741778                                                atomic_base<Base>::class_name(user_index)
    742                                                 + ": atomic_base.rev_sparse_hes: returned false";
     779                                                + ": atomic_base.rev_sparse_hes: returned false\n";
     780                                        if( user_pack )
     781                                                msg += "sparsity = pack_sparsity_enum";
     782                                        if( user_bool )
     783                                                msg += "sparsity = bool_sparsity_enum";
     784                                        if( user_set )
     785                                                msg += "sparsity = set_sparsity_enum";
    743786                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
    744787                                }
     
    749792                                        if( user_t[i] )
    750793                                                RevJac[i_x] = true;
     794                                        if( user_pack )
     795                                        {
     796                                                for(j = 0; j < user_q; j++)
     797                                                        if( pack_v[ i * user_q + j ] )
     798                                                                rev_hes_sparse.add_element(i_x, j);
     799                                        }
    751800                                        if( user_bool )
    752801                                        {
     
    755804                                                                rev_hes_sparse.add_element(i_x, j);
    756805                                        }
    757                                         else
     806                                        if( user_set )
    758807                                        {
    759808                                                set_itr = set_v[i].begin();
     
    792841                        i = for_jac_sparse.next_element();
    793842                        while( i < user_q )
    794                         {       if( user_bool )
     843                        {       if( user_pack )
     844                                        pack_r[ user_j * user_q + i ] = true;
     845                                if( user_bool )
    795846                                        bool_r[ user_j * user_q + i ] = true;
    796                                 else
     847                                if( user_set )
    797848                                        set_r[user_j].insert(i);
    798849                                i = for_jac_sparse.next_element();
     
    825876                        j = rev_hes_sparse.next_element();
    826877                        while( j < user_q )
    827                         {       if( user_bool )
     878                        {       if( user_pack )
     879                                        pack_u[user_i * user_q + j] = true;
     880                                if( user_bool )
    828881                                        bool_u[user_i * user_q + j] = true;
    829882                                else
  • trunk/cppad/local/rev_jac_sweep.hpp

    r3708 r3717  
    172172        vector<bool>       bool_s;   // bool sparisty pattern for the result y
    173173        //
     174        vectorBool         pack_r;   // pack sparsity pattern for the argument x
     175        vectorBool         pack_s;   // pack sparisty pattern for the result y
     176        //
    174177        const size_t user_q = limit; // maximum element plus one
    175178        size_t user_index = 0;       // indentifier for this atomic operation
     
    181184        //
    182185        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
    183         bool               user_bool = false;      // use bool or set sparsity ?
     186        bool               user_pack = false;      // sparsity pattern type is pack
     187        bool               user_bool = false;      // sparsity pattern type is bool
     188        bool               user_set  = false;      // sparsity pattern type is set
    184189# ifndef NDEBUG
    185190        bool               user_ok   = false;      // atomic op return value
     
    642647                                }
    643648# endif
     649                                user_pack  = user_atom->sparsity() ==
     650                                                        atomic_base<Base>::pack_sparsity_enum;
    644651                                user_bool  = user_atom->sparsity() ==
    645652                                                        atomic_base<Base>::bool_sparsity_enum;
     653                                user_set   = user_atom->sparsity() ==
     654                                                        atomic_base<Base>::set_sparsity_enum;
     655                                CPPAD_ASSERT_UNKNOWN( user_pack || user_bool || user_set );
     656                                if( user_pack )
     657                                {       if( pack_r.size() != user_m * user_q )
     658                                                pack_r.resize( user_m * user_q );
     659                                        if( pack_s.size() != user_n * user_q )
     660                                                pack_s.resize( user_n * user_q );
     661                                        for(i = 0; i < user_m; i++)
     662                                                for(j = 0; j < user_q; j++)
     663                                                        pack_r[ i * user_q + j] = false;
     664                                }
    646665                                if( user_bool )
    647666                                {       if( bool_r.size() != user_m * user_q )
     
    653672                                                        bool_r[ i * user_q + j] = false;
    654673                                }
    655                                 else
     674                                if( user_set )
    656675                                {       if(set_r.size() != user_m )
    657676                                                set_r.resize(user_m);
     
    675694                                {       std::string msg =
    676695                                                atomic_base<Base>::class_name(user_index)
    677                                                 + ": atomic_base.rev_sparse_jac: returned false";
     696                                                + ": atomic_base.rev_sparse_jac: returned false\n";
     697                                        if( user_pack )
     698                                                msg += "sparsity = pack_sparsity_enum";
     699                                        if( user_bool )
     700                                                msg += "sparsity = bool_sparsity_enum";
     701                                        if( user_set )
     702                                                msg += "sparsity = set_sparsity_enum";
    678703                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
    679704                                }
     
    702727                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
    703728                        --user_j;
    704                         // It might be faster if we add set union to var_sparsity
     729                        // 2DO: It might be faster if we add set union to var_sparsity
    705730                        // where one of the sets is not in var_sparsity.
     731                        if( user_pack )
     732                        {       for(j = 0; j < user_q; j++)
     733                                        if( pack_s[ user_j * user_q + j ] )
     734                                                var_sparsity.add_element(arg[0], j);
     735                        }
    706736                        if( user_bool )
    707737                        {       for(j = 0; j < user_q; j++)
     
    709739                                                var_sparsity.add_element(arg[0], j);
    710740                        }
    711                         else
     741                        if( user_set )
    712742                        {       set_itr = set_s[user_j].begin();
    713743                                set_end = set_s[user_j].end();
     
    729759                        {       // call users function for this operation
    730760                                user_atom->set_id(user_id);
    731                                 if( user_bool)
    732                                         CPPAD_ATOMIC_CALL(
    733                                                 user_q, bool_r, bool_s
    734                                 );
    735                                 else
    736                                         CPPAD_ATOMIC_CALL(
    737                                                 user_q, set_r, set_s
    738                                 );
     761                                if( user_pack )
     762                                        CPPAD_ATOMIC_CALL( user_q, pack_r, pack_s);
     763                                if( user_bool )
     764                                        CPPAD_ATOMIC_CALL( user_q, bool_r, bool_s);
     765                                if( user_set )
     766                                        CPPAD_ATOMIC_CALL( user_q, set_r, set_s);
    739767                                user_state = user_arg;
    740768                        }
     
    749777                        i = var_sparsity.next_element();
    750778                        while( i < user_q )
    751                         {       if( user_bool )
     779                        {       if( user_pack )
     780                                        pack_r[ user_i * user_q + i ] = true;
     781                                if( user_bool )
    752782                                        bool_r[ user_i * user_q + i ] = true;
    753                                         else
    754                                                 set_r[user_i].insert(i);
     783                                if( user_set )
     784                                        set_r[user_i].insert(i);
    755785                                i = var_sparsity.next_element();
    756786                        }
     
    758788                        {       // call users function for this operation
    759789                                user_atom->set_id(user_id);
    760                                 if( user_bool)
    761                                         CPPAD_ATOMIC_CALL(
    762                                                 user_q, bool_r, bool_s
    763                                 );
    764                                 else
    765                                         CPPAD_ATOMIC_CALL(
    766                                                 user_q, set_r, set_s
    767                                 );
     790                                if( user_pack )
     791                                        CPPAD_ATOMIC_CALL( user_q, pack_r, pack_s);
     792                                if( user_bool )
     793                                        CPPAD_ATOMIC_CALL( user_q, bool_r, bool_s);
     794                                if( user_set )
     795                                        CPPAD_ATOMIC_CALL( user_q, set_r, set_s);
    768796                                user_state = user_arg;
    769797                        }
  • trunk/cppad/thread_alloc.hpp

    r3408 r3717  
    44
    55/* --------------------------------------------------------------------------
    6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
     6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    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
     
    2020
    2121# ifdef _MSC_VER
    22 // Supress warning that Microsoft compiler changed its behavior and is now 
     22// Supress warning that Microsoft compiler changed its behavior and is now
    2323// doing the correct thing at the statement:
    2424//                      new(array + i) Type();
     
    6464
    6565/*
    66 Note that Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for 
     66Note that Section 3.6.2 of ISO/IEC 14882:1998(E) states: "The storage for
    6767objects with static storage duration (3.7.1) shall be zero-initialized
    6868(8.5) before any other initialization takes place."
     
    8282// ============================================================================
    8383private:
    84        
     84
    8585        class capacity_t {
    8686        public:
     
    9191                /// ctor
    9292                capacity_t(void)
    93                 {       // Cannot figure out how to call thread_alloc::in_parallel here. 
    94                         // CPPAD_ASSERT_UNKNOWN( 
    95                         //      ! thread_alloc::in_parallel() , "thread_alloc: "
     93                {       // Cannot figure out how to call thread_alloc::in_parallel here.
     94                        // CPPAD_ASSERT_UNKNOWN(
     95                        //      ! thread_alloc::in_parallel() , "thread_alloc: "
    9696                        //      "parallel mode and parallel_setup not yet called."
    9797                        // );
     
    103103                                // next capactiy is 3/2 times the current one
    104104                                capacity        = 3 * ( (capacity + 1) / 2 );
    105                         }               
     105                        }
    106106                        CPPAD_ASSERT_UNKNOWN( number > 0 );
    107107                }
     
    119119                /// make default constructor private. It is only used by constructor
    120120                /// for `root arrays below.
    121                 block_t(void) : extra_(0), tc_index_(0), next_(CPPAD_NULL) 
     121                block_t(void) : extra_(0), tc_index_(0), next_(CPPAD_NULL)
    122122                { }
    123123        };
     
    133133        /// Structure of information for each thread
    134134        struct thread_alloc_info {
    135                 /// count of available bytes for this thread 
     135                /// count of available bytes for this thread
    136136                size_t  count_inuse_;
    137                 /// count of inuse bytes for this thread 
     137                /// count of inuse bytes for this thread
    138138                size_t  count_available_;
    139139                /// root of available list for this thread and each capacity
     
    146146        // ---------------------------------------------------------------------
    147147        /*!
    148         Set and Get hold available memory flag.
     148        Set and Get hold available memory flag.
    149149
    150150        \param set [in]
     
    181181        If \a clear is false, and the current pointer is CPPAD_NULL,
    182182        a new infromation record is allocated and its pointer returned.
    183         In this case, if \c info is the retured pointer, 
     183        In this case, if \c info is the retured pointer,
    184184        <code>info->count_inuse == 0</code> and
    185185        <code>info->count_available == 0</code>.
     
    243243        // -----------------------------------------------------------------------
    244244        /*!
    245         Increase the number of bytes of memory that are currently in use; i.e.,
    246         that been obtained with \c get_memory and not yet returned. 
     245        Increase the number of bytes of memory that are currently in use; i.e.,
     246        that been obtained with \c get_memory and not yet returned.
    247247
    248248        \param inc [in]
     
    252252        Thread for which we are increasing the number of bytes in use
    253253        (must be less than \c num_threads).
    254         Durring parallel execution, this must be the thread 
     254        Durring parallel execution, this must be the thread
    255255        that is currently executing.
    256256        */
    257257        static void inc_inuse(size_t inc, size_t thread)
    258         {       
     258        {
    259259                CPPAD_ASSERT_UNKNOWN( thread < num_threads() );
    260                 CPPAD_ASSERT_UNKNOWN( 
    261                         thread == thread_num() || (! in_parallel()) 
     260                CPPAD_ASSERT_UNKNOWN(
     261                        thread == thread_num() || (! in_parallel())
    262262                );
    263263                thread_alloc_info* info = thread_info(thread);
    264                
     264
    265265                // do the addition
    266266                size_t result = info->count_inuse_ + inc;
     
    271271        // -----------------------------------------------------------------------
    272272        /*!
    273         Increase the number of bytes of memory that are currently avaialble; i.e.,
     273        Increase the number of bytes of memory that are currently avaialble; i.e.,
    274274        have been obtained obtained from the system and are being held future use.
    275275
     
    277277        */
    278278        static void inc_available(size_t inc, size_t thread)
    279         {       
     279        {
    280280                CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
    281                 CPPAD_ASSERT_UNKNOWN( 
    282                         thread == thread_num() || (! in_parallel()) 
     281                CPPAD_ASSERT_UNKNOWN(
     282                        thread == thread_num() || (! in_parallel())
    283283                );
    284284                thread_alloc_info* info = thread_info(thread);
     
    291291        // -----------------------------------------------------------------------
    292292        /*!
    293         Decrease the number of bytes of memory that are currently in use; i.e.,
    294         that been obtained with \c get_memory and not yet returned. 
     293        Decrease the number of bytes of memory that are currently in use; i.e.,
     294        that been obtained with \c get_memory and not yet returned.
    295295
    296296        \param dec [in]
     
    300300        Thread for which we are decreasing the number of bytes in use
    301301        (must be less than \c num_threads).
    302         Durring parallel execution, this must be the thread 
     302        Durring parallel execution, this must be the thread
    303303        that is currently executing.
    304304        */
    305305        static void dec_inuse(size_t dec, size_t thread)
    306         {       
     306        {
    307307                CPPAD_ASSERT_UNKNOWN(
    308308                        thread < num_threads() || (! in_parallel())
    309309                );
    310                 CPPAD_ASSERT_UNKNOWN( 
    311                         thread == thread_num() || (! in_parallel()) 
     310                CPPAD_ASSERT_UNKNOWN(
     311                        thread == thread_num() || (! in_parallel())
    312312                );
    313313                thread_alloc_info* info = thread_info(thread);
     
    319319        // -----------------------------------------------------------------------
    320320        /*!
    321         Decrease the number of bytes of memory that are currently avaialble; i.e.,
     321        Decrease the number of bytes of memory that are currently avaialble; i.e.,
    322322        have been obtained obtained from the system and are being held future use.
    323323
     
    325325        */
    326326        static void dec_available(size_t dec, size_t thread)
    327         {       
     327        {
    328328                CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
    329                 CPPAD_ASSERT_UNKNOWN( 
    330                         thread == thread_num() || (! in_parallel()) 
     329                CPPAD_ASSERT_UNKNOWN(
     330                        thread == thread_num() || (! in_parallel())
    331331                );
    332332                thread_alloc_info* info = thread_info(thread);
     
    340340        Set and get the number of threads that are sharing memory.
    341341
    342         \param number_new 
     342        \param number_new
    343343        If \c number is zero, we are only retreiving the current maximum
    344344        number of threads. Otherwise, we are setting and retreiving
     
    347347        \return
    348348        the number of threads that are sharing memory.
    349         If \c number_new is non-zero, the return value is equal to 
     349        If \c number_new is non-zero, the return value is equal to
    350350        \c number_new.
    351351        */
     
    363363        }
    364364        /*!
    365         Set and call the routine that determine if we are in parallel 
     365        Set and call the routine that determine if we are in parallel
    366366        execution mode.
    367367
    368         \return 
     368        \return
    369369        value retuned by most recent setting for \a parallel_new.
    370370        If \a set is true,
     
    401401        Set and call the routine that determine the current thread number.
    402402
    403         \return 
     403        \return
    404404        returns value for the most recent setting for \a thread_num_new.
    405405        If \a set is true,
     
    483483$codei%
    484484        size_t %num_threads%
    485 %$$ 
     485%$$
    486486and must be greater than zero.
    487487It specifies the number of threads that are sharing memory.
    488 The case $icode%num_threads% == 1%$$ is a special case that is 
     488The case $icode%num_threads% == 1%$$ is a special case that is
    489489used to terminate a multi-threading environment.
    490490
     
    492492This function has prototype
    493493$codei%
    494         bool %in_parallel%(void) 
     494        bool %in_parallel%(void)
    495495%$$
    496496It must return $code true$$ if there is more than one thread
     
    506506This function has prototype
    507507$codei%
    508         size_t %thread_num%(void) 
     508        size_t %thread_num%(void)
    509509%$$
    510510It must return a thread number that uniquely identifies the
    511 currently executing thread. 
     511currently executing thread.
    512512Furthermore
    513513$codei%
     
    525525
    526526$head Restrictions$$
    527 The function $code parallel_setup$$ must be called before 
     527The function $code parallel_setup$$ must be called before
    528528the program enters $cref/parallel/ta_in_parallel/$$ execution mode.
    529529In addition, this function cannot be called while in parallel mode.
    530530
    531531$head Example$$
    532 The files 
    533 $cref simple_ad_openmp.cpp$$, 
     532The files
     533$cref simple_ad_openmp.cpp$$,
    534534$cref simple_ad_bthread.cpp$$, and
    535 $cref simple_ad_pthread.cpp$$, 
    536 contain examples and tests that use this function.   
     535$cref simple_ad_pthread.cpp$$,
     536contain examples and tests that use this function.
    537537
    538538$end
     
    566566                }
    567567
    568                 CPPAD_ASSERT_KNOWN( 
     568                CPPAD_ASSERT_KNOWN(
    569569                        num_threads <= CPPAD_MAX_NUM_THREADS ,
    570570                        "parallel_setup: num_threads is too large"
    571571                );
    572                 CPPAD_ASSERT_KNOWN( 
     572                CPPAD_ASSERT_KNOWN(
    573573                        num_threads != 0 ,
    574574                        "parallel_setup: num_threads == zero"
    575575                );
    576                 CPPAD_ASSERT_KNOWN( 
     576                CPPAD_ASSERT_KNOWN(
    577577                        in_parallel != CPPAD_NULL ,
    578578                        "parallel_setup: num_threads != 1 and in_parallel == CPPAD_NULL"
    579579                );
    580                 CPPAD_ASSERT_KNOWN( 
     580                CPPAD_ASSERT_KNOWN(
    581581                        thread_num != CPPAD_NULL ,
    582582                        "parallel_setup: num_threads != 1 and thread_num == CPPAD_NULL"
    583583                );
    584584
    585                 // Make sure that constructors for all static variables in this file 
    586                 // are called in sequential mode.       
     585                // Make sure that constructors for all static variables in this file
     586                // are called in sequential mode.
    587587                for(size_t thread = 0; thread < num_threads; thread++)
    588588                        thread_info(thread);
     
    628628$codei%
    629629        size_t %number%
    630 %$$ 
    631 and is equal to the value of 
     630%$$
     631and is equal to the value of
    632632$cref/num_threads/ta_parallel_setup/num_threads/$$
    633633in the previous call to $icode parallel_setup$$.
     
    673673        bool %flag%
    674674%$$
    675 It is true if the current execution is in parallel mode 
     675It is true if the current execution is in parallel mode
    676676(possibly multi-threaded) and false otherwise (sequential mode).
    677677
     
    682682*/
    683683        /// Are we in a parallel execution state; i.e., is it possible that
    684         /// other threads are currently executing. 
     684        /// other threads are currently executing.
    685685        static bool in_parallel(void)
    686686        {       return set_get_in_parallel(0); }
     
    714714%$$
    715715and is the currently executing thread number.
    716 If $code _OPENMP$$ is not defined, $icode thread$$ is zero.
    717716
    718717$head Example$$
     
    721720$end
    722721*/
    723         /// Get current thread number 
     722        /// Get current thread number
    724723        static size_t thread_num(void)
    725724        {       return set_get_thread_num(CPPAD_NULL); }
     
    764763%$$
    765764It's input value does not matter.
    766 Upon return, it is the actual number of bytes (capacity) 
     765Upon return, it is the actual number of bytes (capacity)
    767766that have been allocated for use,
    768767$codei%
     
    775774        void* %v_ptr%
    776775%$$
    777 It is the location where the $icode cap_bytes$$ of memory 
     776It is the location where the $icode cap_bytes$$ of memory
    778777that have been allocated for use begins.
    779778
     
    781780This allocation should be faster if the following conditions hold:
    782781$list number$$
    783 The memory allocated by a previous call to $code get_memory$$ 
     782The memory allocated by a previous call to $code get_memory$$
    784783is currently available for use.
    785784$lnext
    786 The current $icode min_bytes$$ is between 
     785The current $icode min_bytes$$ is between
    787786the previous $icode min_bytes$$ and previous $icode cap_bytes$$.
    788787$lend
     
    800799*/
    801800        /*!
    802         Use thread_alloc to get a specified amount of memory.
    803 
    804         If the memory allocated by a previous call to \c get_memory is now 
     801        Use thread_alloc to get a specified amount of memory.
     802
     803        If the memory allocated by a previous call to \c get_memory is now
    805804        avaialable, and \c min_bytes is between its previous value
    806805        and the previous \c cap_bytes, this memory allocation will have
     
    816815        \return
    817816        pointer to the beginning of the memory allocated for use.
    818         */
     817        */
    819818        static void* get_memory(size_t min_bytes, size_t& cap_bytes)
    820         {       // see first_trace below       
     819        {       // see first_trace below
    821820                CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
    822821
     
    835834                const size_t* capacity_vec = capacity_info()->value;
    836835                while( capacity_vec[c_index] < min_bytes )
    837                 {       ++c_index;     
     836                {       ++c_index;
    838837                        CPPAD_ASSERT_UNKNOWN(c_index < num_cap );
    839838                }
     
    848847                // trace allocation
    849848                static bool first_trace = true;
    850                 if(     cap_bytes == CPPAD_TRACE_CAPACITY && 
     849                if(     cap_bytes == CPPAD_TRACE_CAPACITY &&
    851850                     thread    ==  CPPAD_TRACE_THREAD  && first_trace )
    852                 {       cout << endl;   
     851                {       cout << endl;
    853852                        cout << "thread_alloc: Trace for Thread = " << thread;
    854853                        cout << " and capacity = " << cap_bytes << endl;
     
    857856                }
    858857
    859                 // Root nodes for both lists. Note these are different for different 
     858                // Root nodes for both lists. Note these are different for different
    860859                // threads because tc_index is different for different threads.
    861860                block_t* inuse_root     = info->root_inuse_ + c_index;
     
    880879
    881880                        // trace allocation
    882                         if(     cap_bytes == CPPAD_TRACE_CAPACITY && 
     881                        if(     cap_bytes == CPPAD_TRACE_CAPACITY &&
    883882                             thread    ==  CPPAD_TRACE_THREAD   )
    884                         {       cout << "get_memory:    v_ptr = " << v_ptr << endl; } 
     883                        {       cout << "get_memory:    v_ptr = " << v_ptr << endl; }
    885884# endif
    886885
     
    907906
    908907                // trace allocation
    909                 if( cap_bytes == CPPAD_TRACE_CAPACITY && 
     908                if( cap_bytes == CPPAD_TRACE_CAPACITY &&
    910909                    thread    == CPPAD_TRACE_THREAD    )
    911910                {       cout << "get_memory:    v_ptr = " << v_ptr << endl; }
     
    949948%$$.
    950949It must be a pointer to memory that is currently in use; i.e.
    951 obtained by a previous call to 
     950obtained by a previous call to
    952951$cref/get_memory/ta_get_memory/$$ and not yet returned.
    953952
     
    955954Either the $cref/current thread/ta_thread_num/$$ must be the same as during
    956955the corresponding call to $cref/get_memory/ta_get_memory/$$,
    957 or the current execution mode must be sequential 
     956or the current execution mode must be sequential
    958957(not $cref/parallel/ta_in_parallel/$$).
    959958
     
    961960If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster).
    962961Otherwise, a list of in use pointers is searched to make sure
    963 that $icode v_ptr$$ is in the list. 
     962that $icode v_ptr$$ is in the list.
    964963
    965964$head Example$$
     
    969968*/
    970969        /*!
    971         Return memory that was obtained by \c get_memory.
     970        Return memory that was obtained by \c get_memory.
    972971        If  <code>num_threads() == 1</code>,
    973972        the memory is returned to the system.
    974         Otherwise, it is retained by \c thread_alloc and available for use by 
     973        Otherwise, it is retained by \c thread_alloc and available for use by
    975974        \c get_memory for this thread.
    976975
     
    983982        or the current thread must be the same as for the corresponding call
    984983        to \c get_memory.
    985         */
     984        */
    986985        static void return_memory(void* v_ptr)
    987986        {       size_t num_cap   = capacity_info()->number;
     
    994993
    995994                CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );
    996                 CPPAD_ASSERT_KNOWN( 
     995                CPPAD_ASSERT_KNOWN(
    997996                        thread == thread_num() || (! in_parallel()),
    998997                        "Attempt to return memory for a different thread "
     
    10071006                block_t* previous    = inuse_root;
    10081007                while( (previous->next_ != CPPAD_NULL) & (previous->next_ != v_node) )
    1009                         previous = reinterpret_cast<block_t*>(previous->next_); 
     1008                        previous = reinterpret_cast<block_t*>(previous->next_);
    10101009
    10111010                // check that v_ptr is valid
     
    10151014                        oss << "return_memory: attempt to return memory not in use";
    10161015                        oss << endl;
    1017                         oss << "v_ptr    = " << v_ptr    << endl;   
    1018                         oss << "thread   = " << thread   << endl;   
    1019                         oss << "capacity = " << capacity << endl;   
     1016                        oss << "v_ptr    = " << v_ptr    << endl;
     1017                        oss << "thread   = " << thread   << endl;
     1018                        oss << "capacity = " << capacity << endl;
    10201019                        oss << "See CPPAD_TRACE_THREAD & CPPAD_TRACE_CAPACITY in";
    10211020                        oss << endl << "# include <cppad/thread_alloc.hpp>" << endl;
    1022                         CPPAD_ASSERT_KNOWN(false, oss.str().c_str()     ); 
     1021                        CPPAD_ASSERT_KNOWN(false, oss.str().c_str()     );
    10231022                }
    10241023
     
    10751074In the case where $icode%thread% > 0%$$,
    10761075some extra memory is used to track allocations by the specified thread.
    1077 If 
     1076If
    10781077$codei%
    10791078        thread_alloc::inuse(%thread%) == 0
     
    10871086%$$
    10881087Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
    1089 or the current execution mode must be sequential 
     1088or the current execution mode must be sequential
    10901089(not $cref/parallel/ta_in_parallel/$$).
    10911090
     
    11001099        \param thread [in]
    11011100        this thread that will no longer have any available memory after this call.
    1102         This must either be the thread currently executing, or we must be 
     1101        This must either be the thread currently executing, or we must be
    11031102        in sequential (not parallel) execution mode.
    11041103        */
     
    11081107                        "Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS"
    11091108                );
    1110                 CPPAD_ASSERT_KNOWN( 
     1109                CPPAD_ASSERT_KNOWN(
    11111110                        thread == thread_num() || (! in_parallel()),
    11121111                        "Attempt to free memory for a different thread "
    11131112                        "while in parallel mode"
    11141113                );
    1115        
     1114
    11161115                size_t num_cap = capacity_info()->number;
    11171116                if( num_cap == 0 )
     
    11251124                        void* v_ptr             = available_root->next_;
    11261125                        while( v_ptr != CPPAD_NULL )
    1127                         {       block_t* node = reinterpret_cast<block_t*>(v_ptr); 
     1126                        {       block_t* node = reinterpret_cast<block_t*>(v_ptr);
    11281127                                void* next    = node->next_;
    11291128                                ::operator delete(v_ptr);
     
    11611160instructs $code thread_alloc$$ to hold onto memory,
    11621161and put it in the $cref/available/ta_available/$$ pool,
    1163 after each call to $cref/return_memory/ta_return_memory/$$. 
     1162after each call to $cref/return_memory/ta_return_memory/$$.
    11641163
    11651164$head value$$
     
    11781177*/
    11791178        /*!
    1180         Change the thread_alloc hold memory setting.
     1179        Change the thread_alloc hold memory setting.
    11811180
    11821181        \param value [in]
     
    11861185        {       bool set = true;
    11871186                set_get_hold_memory(set, value);
    1188         }       
    1189        
     1187        }
     1188
    11901189/* -----------------------------------------------------------------------
    11911190$begin ta_inuse$$
     
    12181217%$$
    12191218Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
    1220 or the current execution mode must be sequential 
     1219or the current execution mode must be sequential
    12211220(not $cref/parallel/ta_in_parallel/$$).
    12221221
     
    12391238        Thread for which we are determining the amount of memory
    12401239        (must be < CPPAD_MAX_NUM_THREADS).
    1241         Durring parallel execution, this must be the thread 
     1240        Durring parallel execution, this must be the thread
    12421241        that is currently executing.
    12431242
     
    12461245        */
    12471246        static size_t inuse(size_t thread)
    1248         { 
     1247        {
    12491248                CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
    1250                 CPPAD_ASSERT_UNKNOWN( 
    1251                         thread == thread_num() || (! in_parallel()) 
     1249                CPPAD_ASSERT_UNKNOWN(
     1250                        thread == thread_num() || (! in_parallel())
    12521251                );
    12531252                thread_alloc_info* info = thread_info(thread);
     
    12831282%$$
    12841283Either $cref/thread_num/ta_thread_num/$$ must be the same as $icode thread$$,
    1285 or the current execution mode must be sequential 
     1284or the current execution mode must be sequential
    12861285(not $cref/parallel/ta_in_parallel/$$).
    12871286
     
    13061305        {
    13071306                CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);
    1308                 CPPAD_ASSERT_UNKNOWN( 
    1309                         thread == thread_num() || (! in_parallel()) 
     1307                CPPAD_ASSERT_UNKNOWN(
     1308                        thread == thread_num() || (! in_parallel())
    13101309                );
    13111310                thread_alloc_info* info = thread_info(thread);
     
    13311330
    13321331$head Purpose$$
    1333 Create a new raw array using $cref thread_alloc$$ memory allocator 
     1332Create a new raw array using $cref thread_alloc$$ memory allocator
    13341333(works well in a multi-threading environment)
    13351334and call default constructor for each element.
     
    13521351%$$
    13531352The input value of this argument does not matter.
    1354 Upon return, it is the actual number of elements 
    1355 in $icode array$$ 
     1353Upon return, it is the actual number of elements
     1354in $icode array$$
    13561355($icode% size_min %<=% size_out%$$).
    13571356
     
    13621361%$$
    13631362It is array with $icode size_out$$ elements.
    1364 The default constructor for $icode Type$$ is used to initialize the 
     1363The default constructor for $icode Type$$ is used to initialize the
    13651364elements of $icode array$$.
    13661365Note that $cref/delete_array/ta_delete_array/$$
     
    13681367
    13691368$head Delta$$
    1370 The amount of memory $cref/inuse/ta_inuse/$$ by the current thread, 
     1369The amount of memory $cref/inuse/ta_inuse/$$ by the current thread,
    13711370will increase $icode delta$$ where
    13721371$codei%
     
    13761375(and the allocation will be faster)
    13771376if a previous allocation with $icode size_min$$ between its current value
    1378 and $icode size_out$$ is available. 
     1377and $icode size_out$$ is available.
    13791378
    13801379$head Alignment$$
     
    13871386$cref thread_alloc.cpp$$
    13881387
    1389 $end 
     1388$end
    13901389*/
    13911390        /*!
     
    14041403        \return
    14051404        pointer to the first element of the array.
    1406         The default constructor is used to initialize 
     1405        The default constructor is used to initialize
    14071406        all the elements of the array.
    14081407
     
    14151414        {       // minimum number of bytes to allocate
    14161415                size_t min_bytes = size_min * sizeof(Type);
    1417                 // do the allocation 
     1416                // do the allocation
    14181417                size_t num_bytes;
    14191418                void*  v_ptr     = get_memory(min_bytes, num_bytes);
     
    14531452
    14541453$head Purpose$$
    1455 Returns memory corresponding to an array created by 
    1456 (create by $cref/create_array/ta_create_array/$$) to the 
     1454Returns memory corresponding to an array created by
     1455(create by $cref/create_array/ta_create_array/$$) to the
    14571456$cref/available/ta_available/$$ memory pool for the current thread.
    14581457
     
    14781477The amount of memory $cref/inuse/ta_inuse/$$ will decrease by $icode delta$$,
    14791478and the $cref/available/ta_available/$$ memory will increase by $icode delta$$,
    1480 where $cref/delta/ta_create_array/Delta/$$ 
     1479where $cref/delta/ta_create_array/Delta/$$
    14811480is the same as for the corresponding call to $code create_array$$.
    14821481
     
    14841483$cref thread_alloc.cpp$$
    14851484
    1486 $end 
     1485$end
    14871486*/
    14881487        /*!
     
    14951494        \param array [in]
    14961495        A value returned by \c create_array that has not yet been deleted.
    1497         The \c Type destructor is used to destroy each of the elements 
     1496        The \c Type destructor is used to destroy each of the elements
    14981497        of the array.
    14991498
     
    15241523$$
    15251524
    1526 $section Free All Memory That Was Allocated for Use by thread_alloc$$ 
     1525$section Free All Memory That Was Allocated for Use by thread_alloc$$
    15271526
    15281527$index free, all thread_alloc$$
     
    15411540%$$
    15421541Its value will be $code true$$ if all the memory can be freed.
    1543 This requires that for all $icode thread$$ indices, there is no memory 
     1542This requires that for all $icode thread$$ indices, there is no memory
    15441543$cref/inuse/ta_inuse/$$; i.e.,
    15451544$codei%
     
    15531552$head Example$$
    15541553$cref thread_alloc.cpp$$
    1555 $end 
     1554$end
    15561555*/
    15571556        /*!
     
    15591558
    15601559        \return
    1561         If no \c thread_alloc memory is currently inuse, 
     1560        If no \c thread_alloc memory is currently inuse,
    15621561        all memory is returned to the system and the return value is true.
    15631562        Otherwise the return value is false.
  • trunk/example/atomic/CMakeLists.txt

    r3505 r3717  
    11# $Id$
    22# -----------------------------------------------------------------------------
    3 # CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
     3# CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44#
    55# CppAD is distributed under multiple licenses. This distribution is under
    6 # the terms of the 
     6# the terms of the
    77#                     Eclipse Public License Version 1.0.
    88#
     
    1010# Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
    1111# -----------------------------------------------------------------------------
    12 # Build the example/atomic directory tests 
     12# Build the example/atomic directory tests
    1313
    14 # Specifies build type for this directory. Possible values are 
     14# Specifies build type for this directory. Possible values are
    1515# empty, Debug, Release, RelWithDebInfo and MinSizeRel
    1616SET(CMAKE_BUILD_TYPE DEBUG)
    1717
    1818#
    19 ADD_EXECUTABLE(example_atomic EXCLUDE_FROM_ALL 
     19ADD_EXECUTABLE(example_atomic EXCLUDE_FROM_ALL
    2020        atomic.cpp
    2121        checkpoint.cpp
     
    2525        norm_sq.cpp
    2626        reciprocal.cpp
     27        sparsity.cpp
    2728        tangent.cpp
    2829        old_reciprocal.cpp
     
    3738
    3839# Add the check_example_atomic target
    39 ADD_CUSTOM_TARGET(check_example_atomic 
    40         example_atomic 
    41         DEPENDS example_atomic 
     40ADD_CUSTOM_TARGET(check_example_atomic
     41        example_atomic
     42        DEPENDS example_atomic
    4243)
  • trunk/example/atomic/atomic.cpp

    r3505 r3717  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
    6 the terms of the 
     6the terms of the
    77                    Eclipse Public License Version 1.0.
    88
     
    2727extern bool norm_sq(void);
    2828extern bool reciprocal(void);
     29extern bool sparsity(void);
    2930extern bool tangent(void);
    3031extern bool old_mat_mul(void);
     
    6667        ok &= Run( norm_sq,             "norm_sq"        );
    6768        ok &= Run( reciprocal,          "reciprocal"     );
     69        ok &= Run( sparsity,            "sparsity"       );
    6870        ok &= Run( tangent,             "tangent"        );
    6971        ok &= Run( old_mat_mul,         "old_mat_mul"    );
  • trunk/example/atomic/checkpoint.cpp

    r3715 r3717  
    9191        for(j = 0; j < n; j++)
    9292                ax[j] = double(j);
     93        // could also use bool_sparsity_enum or set_sparsity_enum
    9394        CppAD::atomic_base<double>::option_enum sparsity =
    94                 CppAD::atomic_base<double>::bool_sparsity_enum;
     95                CppAD::atomic_base<double>::pack_sparsity_enum;
    9596        checkpoint<double> atom_f("atom_f", f_algo, ax, ay, sparsity);
    9697        checkpoint<double> atom_g("atom_g", g_algo, ay, az, sparsity);
  • trunk/example/atomic/makefile.am

    r3505 r3717  
    11# $Id$
    22# -----------------------------------------------------------------------------
    3 # CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
     3# CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44#
    55# CppAD is distributed under multiple licenses. This distribution is under
    6 # the terms of the 
     6# the terms of the
    77#                     Eclipse Public License Version 1.0.
    88#
     
    1717check_PROGRAMS    = atomic
    1818#
    19 AM_CXXFLAGS       = -g $(CXX_FLAGS) 
     19AM_CXXFLAGS       = -g $(CXX_FLAGS)
    2020#
    2121AM_CPPFLAGS       = -I. \
    2222        -I$(top_srcdir) \
    2323        $(BOOST_INCLUDE) \
    24         $(EIGEN_INCLUDE) 
     24        $(EIGEN_INCLUDE)
    2525#
    2626atomic_SOURCES   = \
     
    3232        norm_sq.cpp \
    3333        reciprocal.cpp \
     34        sparsity.cpp \
    3435        tangent.cpp \
    3536        old_mat_mul.hpp \
     
    3839        old_tan.cpp \
    3940        old_usead_1.cpp \
    40         old_usead_2.cpp 
     41        old_usead_2.cpp
    4142
    4243test: check
  • trunk/example/atomic/makefile.in

    r3705 r3717  
    100100am_atomic_OBJECTS = atomic.$(OBJEXT) checkpoint.$(OBJEXT) \
    101101        get_started.$(OBJEXT) hes_sparse.$(OBJEXT) mat_mul.$(OBJEXT) \
    102         norm_sq.$(OBJEXT) reciprocal.$(OBJEXT) tangent.$(OBJEXT) \
    103         old_mat_mul.$(OBJEXT) old_reciprocal.$(OBJEXT) \
    104         old_tan.$(OBJEXT) old_usead_1.$(OBJEXT) old_usead_2.$(OBJEXT)
     102        norm_sq.$(OBJEXT) reciprocal.$(OBJEXT) sparsity.$(OBJEXT) \
     103        tangent.$(OBJEXT) old_mat_mul.$(OBJEXT) \
     104        old_reciprocal.$(OBJEXT) old_tan.$(OBJEXT) \
     105        old_usead_1.$(OBJEXT) old_usead_2.$(OBJEXT)
    105106atomic_OBJECTS = $(am_atomic_OBJECTS)
    106107atomic_LDADD = $(LDADD)
     
    365366        norm_sq.cpp \
    366367        reciprocal.cpp \
     368        sparsity.cpp \
    367369        tangent.cpp \
    368370        old_mat_mul.hpp \
     
    371373        old_tan.cpp \
    372374        old_usead_1.cpp \
    373         old_usead_2.cpp 
     375        old_usead_2.cpp
    374376
    375377all: all-am
     
    432434@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/old_usead_2.Po@am__quote@
    433435@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reciprocal.Po@am__quote@
     436@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparsity.Po@am__quote@
    434437@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tangent.Po@am__quote@
    435438
  • trunk/example/atomic/norm_sq.cpp

    r3715 r3717  
    1515$spell
    1616        sq
     17        bool
     18        enum
    1719$$
    1820
    19 $section Euclidean Norm Squared: Example and Test$$
     21$section Atomic Euclidean Norm Squared: Example and Test$$
    2022
    2123$head Theory$$
     
    2830\] $$
    2931
     32$head sparsity$$
     33$index bool_sparsity_enum$$
     34This example only uses bool sparsity patterns.
     35
    3036$nospell
    3137
     
    4349        // constructor (could use const char* for name)
    4450        atomic_norm_sq(const std::string& name) :
    45         // this example uses boolean sparsity patterns
     51        // this example only uses boolean sparsity patterns
    4652        CppAD::atomic_base<double>(name, atomic_base<double>::bool_sparsity_enum)
    4753        { }
  • trunk/example/atomic/reciprocal.cpp

    r3715 r3717  
    1313/*
    1414$begin atomic_reciprocal.cpp$$
     15$spell
     16        enum
     17$$
    1518
    1619$section Reciprocal as an Atomic Operation: Example and Test$$
     
    2124$latex f : \B{R}^n \rightarrow \B{R}^m$$ where
    2225$latex n = 1$$, $latex m = 1$$, and $latex f(x) = 1 / x$$.
     26
     27$head sparsity$$
     28$index set_sparsity_enum$$
     29This example only uses set sparsity patterns.
    2330
    2431$nospell
     
    5360        // constructor (could use const char* for name)
    5461        atomic_reciprocal(const std::string& name) :
    55         // this exmaple uses set sparsity patterns
     62        // this exmaple only uses set sparsity patterns
    5663        CppAD::atomic_base<double>(name, atomic_base<double>::set_sparsity_enum)
    5764        { }
  • trunk/example/atomic/tangent.cpp

    r3160 r3717  
    11// $Id$
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
    6 the terms of the 
     6the terms of the
    77                    Eclipse Public License Version 1.0.
    88
     
    1515$spell
    1616        Tanh
     17        bool
    1718$$
    1819
     
    2728functions as user atomic operations.
    2829
     30$head sparsity$$
     31This atomic operation can use both set and bool sparsity patterns.
     32
    2933$nospell
    3034
     
    3236$codep */
    3337# include <cppad/cppad.hpp>
    34 namespace { // Begin empty namespace 
     38namespace { // Begin empty namespace
    3539using CppAD::vector;
    3640//
     
    5963        public:
    6064        // constructor
    61         atomic_tangent(const char* name, bool hyperbolic) 
     65        atomic_tangent(const char* name, bool hyperbolic)
    6266        : CppAD::atomic_base<float>(name),
    6367        hyperbolic_(hyperbolic)
     
    99103                        // y^{(0)} = z^{(0)} * z^{(0)}
    100104                        tzy[q1 + 0] = tzy[0] * tzy[0];
    101                
     105
    102106                        p++;
    103107                }
     
    108112
    109113                        // z^{(j)} = x^{(j)} +- sum_{k=1}^j k x^{(k)} y^{(j-k)} / j
    110                         tzy[j] = tx[j]; 
     114                        tzy[j] = tx[j];
    111115                        for(k = 1; k <= j; k++)
    112116                                tzy[j] += tx[k] * tzy[q1 + j-k] * k * j_inv;
     
    134138        {       size_t q1 = q + 1;
    135139                size_t n  = tx.size()  / q1;
    136                 size_t m  = tzy.size() / q1;   
     140                size_t m  = tzy.size() / q1;
    137141                assert( px.size()  == n * q1 );
    138142                assert( pzy.size() == m * q1 );
     
    158162                        px[j] += qzy[j];
    159163                        for(k = 1; k <= j; k++)
    160                                 px[k] += qzy[j] * tzy[q1 + j-k] * k * j_inv; 
     164                                px[k] += qzy[j] * tzy[q1 + j-k] * k * j_inv;
    161165
    162166                        // H_{y^{j-k)} += +- H_{z^{(j)} x^{(k)} * k / j
    163167                        for(k = 1; k <= j; k++)
    164                                 qzy[q1 + j-k] += qzy[j] * tx[k] * k * j_inv; 
    165 
    166                         // H_{z^{(k)}} += H_{y^{(j-1)}} * z^{(j-k-1)} * 2. 
     168                                qzy[q1 + j-k] += qzy[j] * tx[k] * k * j_inv;
     169
     170                        // H_{z^{(k)}} += H_{y^{(j-1)}} * z^{(j-k-1)} * 2.
    167171                        for(k = 0; k < j; k++)
    168                                 qzy[k] += qzy[q1 + j-1] * tzy[j-k-1] * 2.f; 
     172                                qzy[k] += qzy[q1 + j-1] * tzy[j-k-1] * 2.f;
    169173                }
    170174
     
    175179                        px[0] += qzy[0] * (1.f + tzy[q1 + 0]);
    176180
    177                 return true; 
     181                return true;
    178182        }
    179183/* $$
     
    231235                        st[j] = rt[0 * p + j] | rt[1 * p + j];
    232236
    233                 return true; 
     237                return true;
    234238        }
    235239        // reverse Jacobian sparsity routine called by CppAD
     
    245249                // sparsity for S(x)^T = f'(x)^T * R^T
    246250                my_union(st[0], rt[0], rt[1]);
    247                 return true; 
     251                return true;
    248252        }
    249253/* $$
     
    271275                // so it is not necessary to vx.
    272276
    273                 // sparsity for T(x) = S(x) * f'(x) 
     277                // sparsity for T(x) = S(x) * f'(x)
    274278                t[0] =  s[0] | s[1];
    275279
    276                 // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R 
     280                // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R
    277281                // U(x) = g''(y) * f'(x) * R
    278282                // S(x) = g'(y)
    279                
    280                 // back propagate the sparsity for U, note both components 
     283
     284                // back propagate the sparsity for U, note both components
    281285                // of f'(x) may be non-zero;
    282286                size_t j;
     
    313317                // so it is not necessary to vx.
    314318
    315                 // sparsity for T(x) = S(x) * f'(x) 
     319                // sparsity for T(x) = S(x) * f'(x)
    316320                t[0] =  s[0] | s[1];
    317321
    318                 // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R 
     322                // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R
    319323                // U(x) = g''(y) * f'(x) * R
    320324                // S(x) = g'(y)
    321                
    322                 // back propagate the sparsity for U, note both components 
     325
     326                // back propagate the sparsity for U, note both components
    323327                // of f'(x) may be non-zero;
    324328                my_union(v[0], u[0], u[1]);
     
    363367        CppAD::Independent(ax);
    364368
    365         // range space vector 
     369        // range space vector
    366370        size_t m = 3;
    367371        CppAD::vector< AD<float> > af(m);
     
    383387        one[0] = 1.;
    384388        my_tanh(one, az);
    385         af[2] = az[0]; 
     389        af[2] = az[0];
    386390
    387391        // create f: x -> f and stop tape recording
    388392        CppAD::ADFun<float> F;
    389         F.Dependent(ax, af); 
     393        F.Dependent(ax, af);
    390394/* $$
    391395$subhead forward$$
    392396$codep */
    393         // check function value 
     397        // check function value
    394398        float tan = std::tan(x0);
    395399        ok &= NearEqual(af[0] , tan,  eps, eps);
     
    418422        dw    = F.Reverse(1, w);
    419423
    420         // tan'(x)   = 1 + tan(x)  * tan(x) 
    421         // tanh'(x)  = 1 - tanh(x) * tanh(x) 
    422         float tanp  = 1.f + tan * tan; 
    423         float tanhp = 1.f - tanh * tanh; 
     424        // tan'(x)   = 1 + tan(x)  * tan(x)
     425        // tanh'(x)  = 1 - tanh(x) * tanh(x)
     426        float tanp  = 1.f + tan * tan;
     427        float tanhp = 1.f - tanh * tanh;
    424428        ok   &= NearEqual(df[0], tanp, eps, eps);
    425429        ok   &= NearEqual(df[1], tanhp, eps, eps);
     
    435439        ddw   = F.Reverse(2, w);
    436440
    437         // tan''(x)   = 2 *  tan(x) * tan'(x) 
    438         // tanh''(x)  = - 2 * tanh(x) * tanh'(x) 
     441        // tan''(x)   = 2 *  tan(x) * tan'(x)
     442        // tanh''(x)  = - 2 * tanh(x) * tanh'(x)
    439443        // Note that second order Taylor coefficient for u half the
    440444        // corresponding second derivative.
     
    501505        tanhp = 0.;
    502506        ok   &= NearEqual(df[1], tanhp, eps, eps);
    503  
     507
    504508        return ok;
    505509}
  • trunk/omh/atomic_base.omh

    r3715 r3717  
    3131
    3232$section User Defined Atomic AD Functions$$
    33 $index atomic, user function$$
    34 $index user, atomic function$$
    35 $index operation, user atomic$$
    36 $index function, user atomic$$
    3733
    3834
     
    8581        example/atomic/norm_sq.cpp%
    8682        example/atomic/reciprocal.cpp%
     83        example/atomic/sparsity.cpp%
    8784        example/atomic/tangent.cpp%
    8885        example/atomic/hes_sparse.cpp%
  • trunk/omh/example_list.omh

    r3711 r3717  
    104104$cref atomic_norm_sq.cpp$$
    105105$cref atomic_reciprocal.cpp$$
     106$cref atomic_sparsity.cpp$$
    106107$cref atomic_tangent.cpp$$
    107108$rref base_adolc.hpp$$
  • trunk/omh/whats_new/whats_new_15.omh

    r3716 r3717  
    5353        resize
    5454        bool
     55        alloc
    5556$$
    5657
     
    6263The purpose of this section is to
    6364assist you in learning about changes between various versions of CppAD.
     65
     66$head 08-31$$
     67$list number$$
     68Add the
     69$cref/pack/atomic_option/atomic_sparsity/pack_sparsity_enum/$$
     70sparsity option for $cref atomic_base$$ operations.
     71$lnext
     72Add the pack sparsity option to
     73$cref/checkpoint/checkpoint/sparsity/$$ functions.
     74$lnext
     75Added the $cref atomic_sparsity.cpp$$ example.
     76$lnext
     77Remove mention of OpenMP from $cref/thread_alloc::thread_num/ta_thread_num/$$
     78($cref thread_alloc$$ never was OpenMP specific).
     79$lend
    6480
    6581$head 08-30$$
  • trunk/test_more/checkpoint.cpp

    r3713 r3717  
    160160                ADFun<double> h(ax, ay);
    161161
    162                 for(size_t k = 0; k < 2; k++)
     162                for(size_t k = 0; k < 3; k++)
    163163                {       if( k == 0 )
     164                                h_check.option(CppAD::atomic_base<double>::pack_sparsity_enum);
     165                        if( k == 1 )
    164166                                h_check.option(CppAD::atomic_base<double>::bool_sparsity_enum);
    165                         else
     167                        if( k == 2 )
    166168                                h_check.option(CppAD::atomic_base<double>::set_sparsity_enum);
    167169
Note: See TracChangeset for help on using the changeset viewer.