CppAD: A C++ Algorithmic Differentiation Package  20130918
link_mat_mul.cpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 /* --------------------------------------------------------------------------
00003 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
00004 
00005 CppAD is distributed under multiple licenses. This distribution is under
00006 the terms of the 
00007                     Eclipse Public License Version 1.0.
00008 
00009 A copy of this license is included in the COPYING file of this distribution.
00010 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00011 -------------------------------------------------------------------------- */
00012 
00013 /*
00014 $begin link_mat_mul$$
00015 $spell
00016      mul
00017      bool
00018      CppAD
00019      dz
00020 $$
00021 
00022 $index link_mat_mul$$
00023 $index matrix, multiply speed test$$
00024 $index multiply, matrix speed test$$
00025 $index speed, test matrix multiple$$
00026 $index test, matrix multiple speed$$
00027 
00028 $section Speed Testing Derivative of Matrix Multiply$$
00029 
00030 $head Prototype$$
00031 $codei%extern bool link_mat_mul(
00032      size_t                         %size%    , 
00033      size_t                         %repeat%  , 
00034      CppAD::vector<double>&         %x%       ,
00035      CppAD::vector<double>&         %z%       ,
00036      CppAD::vector<double>&         %dz%      
00037 );
00038 %$$
00039 
00040 $head Purpose$$
00041 Each $cref/package/speed_main/package/$$
00042 must define a version of this routine as specified below.
00043 This is used by the $cref speed_main$$ program 
00044 to run the corresponding speed and correctness tests.
00045 
00046 $head Return Value$$
00047 If this speed test is not yet
00048 supported by a particular $icode package$$,
00049 the corresponding return value for $code link_mat_mul$$ 
00050 should be $code false$$.
00051 
00052 $head n$$
00053 The argument $icode n$$ is the number of rows and columns
00054 in the square matrix $icode x$$.
00055 
00056 $head repeat$$
00057 The argument $icode repeat$$ is the number of different argument values
00058 that the derivative of $icode z$$ (or just the value of $icode z$$) 
00059 will be computed. 
00060 
00061 $head x$$
00062 The argument $icode x$$ is a vector with 
00063 $icode%x%.size() = %size% * %size%$$ elements.
00064 The input value of its elements does not matter. 
00065 The output value of its elements is the last random matrix
00066 that is multiplied and then summed to form $icode z$$;
00067 $latex \[
00068      x_{i,j} = x[ i * s + j ]
00069 \] $$
00070 where $icode%s% = %size%$$.
00071 
00072 $head z$$
00073 The argument $icode z$$ is a vector with one element.
00074 The input value of the element does not matter.
00075 The output of its element the sum of the elements of 
00076 $icode%y% = %x% * %x%$$; i.e.,
00077 $latex \[
00078 \begin{array}{rcl}
00079      y_{i,j} & = & \sum_{k=0}^{s-1} x_{i,k} x_{k, j} 
00080      \\
00081      z       & = & \sum_{i=0}^{s-1} \sum_{j=0}^{s-1} y_{i,j}
00082 \end{array}
00083 \] $$
00084 
00085 $head dz$$
00086 The argument $icode dz$$ is a vector with 
00087 $icode%dz%.size() = %size% * %size%$$.
00088 The input values of its elements do not matter.
00089 The output value of its elements form the
00090 derivative of $icode z$$ with respect to $icode x$$.
00091 
00092 $end 
00093 -----------------------------------------------------------------------------
00094 */
00095 # include <cppad/vector.hpp>
00096 # include <cppad/near_equal.hpp>
00097 
00098 extern bool link_mat_mul(
00099      size_t                     size     , 
00100      size_t                     repeat   , 
00101      CppAD::vector<double>&      x       ,
00102      CppAD::vector<double>&      z       ,
00103      CppAD::vector<double>&      dz     
00104 );
00105 bool available_mat_mul(void)
00106 {    size_t size   = 2;
00107      size_t repeat = 1;
00108      CppAD::vector<double>  x(size * size), z(1), dz(size * size);
00109 
00110      return link_mat_mul(size, repeat, x, z, dz);
00111 }
00112 bool correct_mat_mul(bool is_package_double)
00113 {    size_t size   = 2;
00114      size_t repeat = 1;
00115      CppAD::vector<double>  x(size * size), z(1), dz(size * size);
00116 
00117      link_mat_mul(size, repeat, x, z, dz);
00118 
00119      double x00 = x[0 * size + 0];
00120      double x01 = x[0 * size + 1];
00121      double x10 = x[1 * size + 0];
00122      double x11 = x[1 * size + 1];
00123      bool ok = true;
00124      double check;
00125      if( is_package_double )
00126      {    check  = 0;
00127           check += x00 * x00 + x01 * x10; // y00
00128           check += x00 * x01 + x01 * x11; // y01
00129           check += x10 * x00 + x11 * x10; // y10
00130           check += x10 * x01 + x11 * x11; // y11
00131           ok &= CppAD::NearEqual(check, z[0], 1e-10, 1e-10);
00132           return ok;
00133      }
00134      // partial w.r.t. x00
00135      check = x00 + x00 + x01 + x10;
00136      ok   &= CppAD::NearEqual(check, dz[0 * size + 0], 1e-10, 1e-10);
00137      // partial w.r.t. x01
00138      check = x10 + x00 + x11 + x10;
00139      ok   &= CppAD::NearEqual(check, dz[0 * size + 1], 1e-10, 1e-10);
00140      // partial w.r.t. x10
00141      check = x01 + x00 + x11 + x01;
00142      ok   &= CppAD::NearEqual(check, dz[1 * size + 0], 1e-10, 1e-10);
00143      // partial w.r.t. x11
00144      check = x01 + x10 + x11 + x11;
00145      ok   &= CppAD::NearEqual(check, dz[1 * size + 1], 1e-10, 1e-10);
00146      
00147      return ok;
00148 }
00149 
00150 void speed_mat_mul(size_t size, size_t repeat)
00151 {    CppAD::vector<double>  x(size * size), z(1), dz(size * size);
00152 
00153      link_mat_mul(size, repeat, x, z, dz);
00154      return;
00155 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines