SundanceMultipleDeriv.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef SUNDANCE_MULTIPLEDERIV_H
00043 #define SUNDANCE_MULTIPLEDERIV_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "SundanceDeriv.hpp"
00047 #include "SundanceMultiSet.hpp"
00048 #include "SundanceOrderedTuple.hpp"
00049 #include "SundanceMap.hpp"
00050 #include "Teuchos_Array.hpp"
00051 
00052 
00053 
00054 namespace Sundance
00055 {
00056 using namespace Sundance;
00057 class MultipleDeriv;
00058 /** */
00059 typedef OrderedPair<MultipleDeriv, MultipleDeriv> DerivPair; 
00060 
00061 /** */
00062 typedef Sundance::Map<DerivPair, int> ProductRulePerms;
00063 /** Class MultipleDeriv is a multiple functional derivative operator
00064  * represented as a multiset of first-order derivatives.
00065  * The derivatives are each Deriv objects, so the multiple
00066  * derivative can be an arbitrary mixture of spatial and
00067  * functional derivatives.
00068  *
00069  * <h3> Product rule application </h3>
00070  *
00071  * Class MultipleDeriv contains a utility method for computing the
00072  * derivatives that appear in the general product rule, as
00073  * used in automatic differentiation of products and spatial
00074  * derivatives.
00075  * The arbitrary order, multivariable product rule gives
00076  * the derivative of a product \f$L\cdot R\f$
00077  * with respect to a multiset of variables
00078  * \f$\{u_1, u_2, \dots, u_N\}\f$ as the sum
00079  * \f[ D_{u_1} D_{u_2} \cdots D_{u_N} (L \cdot R)
00080  * =\sum_{i=1}^{2^N} \left[\prod_{j=1}^N D_{u_j}^{b_{i,j}}\right] L
00081  * \times \left[\prod_{j=1}^N D_{u_j}^{1-b_{i,j}}\right] R\f]
00082  * where \f$b_{i,j}\f$ is the \f$j\f$-th bit in the binary
00083  * representation of \f$i\f$. Method productRulePermutations()
00084  * enumerates all the permutations that apply to the left and right
00085  * operands in this sum, and returns the
00086  * arrays of left operators and right operators
00087  * through non-const reference arguments.
00088  * The left and right arguments return
00089  *
00090  * \f[ {\rm left = Array}_{i=1}^{2^N}
00091  * \{\prod_{j=1}^N D_{u_j}^{b_{i,j}}\}\f]
00092  *
00093  * \f[ {\rm right = Array}_{i=1}^{2^N}
00094  * \{\prod_{j=1}^N D_{u_j}^{1-b_{i,j}}\}\f]
00095  *
00096  * Each element in these arrays is a multiple derivative, and
00097  * is naturally represented with a MultipleDeriv object.
00098  */
00099 class MultipleDeriv : public MultiSet<Deriv>
00100 {
00101 public:
00102 
00103   /** Construct an empty multiple derivative */
00104   MultipleDeriv();
00105 
00106   /** Construct a first-order multiple deriv */
00107   MultipleDeriv(const Deriv& d);
00108 
00109   /** Construct a second-order multiple deriv */
00110   MultipleDeriv(const Deriv& d1, const Deriv& d2);
00111 
00112   /** Return the order of this derivative. Since a
00113    * multiple derivative is a multiset of first-order
00114    * derivatives, the order of the multiple derivative is the
00115    * size of the set. */
00116   int order() const {return this->size();}
00117 
00118   /** Return the order of spatial differentiation in this
00119    * derivative */
00120   int spatialOrder() const ;
00121 
00122   /** Return a multiindex representing the spatial derivs in this
00123    * multiple derivative */
00124   MultiIndex spatialDeriv() const ;
00125           
00126           
00127   /** Return by reference argument the partitioning of
00128    * derivatives when this derivative is applied to a product.
00129    */
00130   void productRulePermutations(ProductRulePerms& perms) const ;
00131 
00132   /** return the product of two multiple derivatives, which
00133    * is the union of the two multisets */
00134   MultipleDeriv product(const MultipleDeriv& other) const ;
00135 
00136 
00137   /** 
00138    * Return a copy of this derivative, but with the specified single
00139    * derivative removed. For example, if <t>this</t> is
00140    * \f$ \{u,v,w\} \f$, calling <t>factorOutDeriv(v)</t> will
00141    * return \f$\{u,w\}\f$.
00142    */
00143   MultipleDeriv factorOutDeriv(const Deriv& x) const ;
00144 
00145 
00146   /** 
00147    * Return a copy of this derivative, but with all single derivs
00148    * in the the argument removed. For example, if <t>this</t> is
00149    * \f$ \{u,v,w\} \f$, calling <t>factorOutDeriv(u,v)</t> will
00150    * return \f$\{w\}\f$.
00151    */
00152   MultipleDeriv factorOutDeriv(const MultipleDeriv& x) const ;
00153 
00154 
00155   /** 
00156    * Return true is all single derivatives appearing in x also appear in this.
00157    */
00158   bool containsDeriv(const MultipleDeriv& x) const ;
00159 
00160 
00161   /** 
00162    *
00163    */
00164   bool isInRequiredSet(const Set<MultiSet<int> >& funcCombinations,
00165     const Set<MultiIndex>& multiIndices) const ;
00166 
00167   /** */
00168   MultiSet<FunctionIdentifier> funcIDs() const ;
00169 
00170   /** */
00171   MultiSet<int> dofIDs() const ;
00172 
00173   /** \name Utilities used in computing product rule permutations */
00174   //@
00175   /** Compute the n-th power of 2 */
00176   static int pow2(int n);
00177 
00178   /** Compute the n bits of an integer x < 2^n. The bits are ordered
00179    * least-to-most significant.
00180    */
00181   static Array<int> bitsOfAnInteger(int x, int n);
00182   //@}
00183 private:
00184 };
00185 
00186 
00187 /** 
00188  * \brief Tranform the input set S as follows: for each multiple derivative
00189  * in S, apply the multiindex x to each of its component functional derivatives 
00190  * in turn. Note that the multiindex may have negative indices. Results with
00191  * negative multiindices are ignored.
00192  */
00193 Set<MultipleDeriv> applyTx(const Set<MultipleDeriv>& S,
00194   const MultiIndex& x);
00195 /** 
00196  * \brief Filter the input set W, allowing only coordinate derivatives in the 
00197  * direction x and functional derivatives whose associated functions
00198  * have nonzero evaluation points. This function is used 
00199  * in the spatial/functional chain rule to identify those terms resulting
00200  * from differentiation wrt x or functional derivatives. 
00201  */
00202 Set<MultipleDeriv> applyZx(const Set<MultipleDeriv>& W,
00203   const MultiIndex& x);
00204 
00205 
00206 /** */
00207 Set<MultipleDeriv> Xx(const MultiIndex& x) ;
00208 
00209 /** */
00210 int factorial(const MultipleDeriv& ms);
00211 
00212 
00213 /**
00214  *
00215  */
00216 template <class T> class increasingOrder
00217 : std::binary_function<T, T, bool>
00218 {
00219 public:
00220   bool operator()(const MultipleDeriv& a,
00221     const MultipleDeriv& b) const;
00222 };
00223 /**
00224  * Functor increasingOrder() is used as a comparison method
00225  * for MultipleDeriv objects. When used in a set, it will sort
00226  * derivatives in order of increasing order of differentiation.
00227  * Sorting by differentiation order is useful in evaluation of
00228  * product and chain rules: if we evaluate higher-order derivatives
00229  * first, we can evaluate in place without destroying lower-order
00230  * derivatives.
00231  */
00232 template <> class increasingOrder<MultipleDeriv>
00233 {
00234 public:
00235   bool operator()(const MultipleDeriv& a,
00236     const MultipleDeriv& b) const
00237     {
00238       if (a.order() < b.order()) return true;
00239       if (a.order() > b.order()) return false;
00240 
00241       MultipleDeriv::const_iterator aIter;
00242       MultipleDeriv::const_iterator bIter;
00243 
00244       for (aIter=a.begin(), bIter=b.begin();
00245            aIter != a.end() && bIter != b.end();
00246            aIter++, bIter++)
00247       {
00248         if (*aIter < *bIter) return true;
00249         if (*bIter < *aIter) return false;
00250       }
00251 
00252       return false;
00253     }
00254 };
00255 
00256 
00257 /** */
00258 MultipleDeriv makeMultiDeriv(const Deriv& d);
00259 
00260 /** */
00261 bool hasParameter(const MultipleDeriv& d) ;
00262 
00263 
00264 }
00265 
00266 
00267 #endif

Site Contact