Prev Next atomic_four_mat_mul_sparsity.cpp

@(@\newcommand{\W}[1]{ \; #1 \; } \newcommand{\R}[1]{ {\rm #1} } \newcommand{\B}[1]{ {\bf #1} } \newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} } \newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} } \newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} } \newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }@)@This is cppad-20221105 documentation. Here is a link to its current documentation .
Atomic Matrix Multiply Sparsity Patterns: Example and Test

Purpose
This example demonstrates computing sparsity patterns with the atomic_four_mat_mul class.

f(x)
For a matrix @(@ A @)@ we define the function @(@ \R{rvec} ( A ) @)@ to be the elements of @(@ A @)@ in row major order. For this example, the function @(@ f(x) @)@ is @[@ f(x) = \R{rvec} \left[ \left( \begin{array}{cc} x_0 & x_1 \\ x_2 & x_3 \\ \end{array} \right) \left( \begin{array}{cc} x_4 & x_5 \\ x_6 & x_7 \end{array} \right) \right] = \R{rvec} \left( \begin{array}{cc} x_0 x_4 + x_1 x_6 & x_0 x_5 + x_1 x_7 \\ x_2 x_4 + x_3 x_6 & x_2 x_5 + x_3 x_7 \\ \end{array} \right) @]@ @[@ f(x) = \left( \begin{array}{c} x_0 x_4 + x_1 x_6 \\ x_0 x_5 + x_1 x_7 \\ x_2 x_4 + x_3 x_6 \\ x_2 x_5 + x_3 x_7 \end{array} \right) @]@

Jacobian of f(x)
The Jacobian of @(@ f(x) @)@ is @[@ f^{(1)} (x) = \left( \begin{array}{cccccccc} % 0 1 2 3 4 5 6 7 x_4 & x_6 & 0 & 0 & x_0 & 0 & x_1 & 0 \\ % 0 x_5 & x_7 & 0 & 0 & 0 & x_0 & 0 & x_1 \\ % 1 0 & 0 & x_4 & x_6 & x_2 & 0 & x_3 & 0 \\ % 2 0 & 0 & x_5 & x_7 & 0 & x_2 & 0 & x_3 \\ % 3 \end{array} \right) @]@

Hessian
The function @(@ f_2 (x) @)@ is @[@ f_2 (x) = x_2 x_4 + x_3 x_6 @]@ The Hessian of @(@ f_2(x) @)@ is @[@ f_2^{(2)} (x) = \left( \begin{array}{cccccccccc} & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\ & - & - & - & - & - & - & - & - \\ 0 \; | & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 1 \; | & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 2 \; | & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 3 \; | & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 4 \; | & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 5 \; | & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 6 \; | & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 7 \; | & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right) @]@ where the first row is the column index, and the first column is the row index, for the corresponding matrix entries above.

Source

# include <cppad/cppad.hpp>
# include <cppad/example/atomic_four/mat_mul/mat_mul.hpp>

bool sparsity(void)
{   // ok, eps
    bool ok = true;
    //
    // AD
    using CppAD::AD;
    using CppAD::sparse_rc;
    // -----------------------------------------------------------------------
    // Record f
    // -----------------------------------------------------------------------
    //
    // afun
    CppAD::atomic_mat_mul<double> afun("atomic_mat_mul");
    //
    // nleft, n_middle, n_right
    size_t n_left = 2, n_middle = 2, n_right = 2;
    //
    // nx, ax
    size_t nx = n_middle * (n_left + n_right);
    CPPAD_TESTVECTOR( AD<double> ) ax(nx);
    for(size_t j = 0; j < nx; ++j)
        ax[j] = AD<double>(j + 2);
    CppAD::Independent(ax);
    //
    // ny, ay
    size_t ny = n_left * n_right;
    CPPAD_TESTVECTOR( AD<double> ) ay(ny);
    //
    // ay
    size_t call_id = afun.set(n_left, n_middle, n_right);
    afun(call_id, ax, ay);
    //
    // f
    CppAD::ADFun<double> f(ax, ay);
    //
    // s_vector
    typedef CPPAD_TESTVECTOR(size_t) s_vector;
    //
    // eye_sparsity
    // nx by nx identitty matrix
    sparse_rc<s_vector> eye_sparsity;
    eye_sparsity.resize(nx, nx, nx);
    for(size_t i = 0; i < nx; ++i)
        eye_sparsity.set(i, i, i);
    //
    // -----------------------------------------------------------------------
    // jac_sparsity
    bool transpose     = false;
    bool dependency    = false;
    bool internal_bool = false;
    sparse_rc<s_vector> jac_sparsity;
    f.for_jac_sparsity(
        eye_sparsity, transpose, dependency, internal_bool, jac_sparsity
    );
    {   // check jac_sparsity
        //
        // row, col
        const s_vector& row       = jac_sparsity.row();
        const s_vector& col       = jac_sparsity.col();
        s_vector        row_major = jac_sparsity.row_major();
        //
        // ok
        ok &= jac_sparsity.nnz() == 16;
        for(size_t k = 0; k < jac_sparsity.nnz(); ++k)
            ok &= row[ row_major[k] ] == k / 4;
        // row 0
        ok &= col[ row_major[0] ]  == 0;
        ok &= col[ row_major[1] ]  == 1;
        ok &= col[ row_major[2] ]  == 4;
        ok &= col[ row_major[3] ]  == 6;
        // row 1
        ok &= col[ row_major[4] ]  == 0;
        ok &= col[ row_major[5] ]  == 1;
        ok &= col[ row_major[6] ]  == 5;
        ok &= col[ row_major[7] ]  == 7;
        // row 2
        ok &= col[ row_major[8] ]  == 2;
        ok &= col[ row_major[9] ]  == 3;
        ok &= col[ row_major[10] ] == 4;
        ok &= col[ row_major[11] ] == 6;
        // row 3
        ok &= col[ row_major[12] ] == 2;
        ok &= col[ row_major[13] ] == 3;
        ok &= col[ row_major[14] ] == 5;
        ok &= col[ row_major[15] ] == 7;
    }
    // ----------------------------------------------------------------
    //
    // select_y
    // corresponding to f_2
    CPPAD_TESTVECTOR(bool) select_y(ny);
    for(size_t i = 0; i < ny; ++i)
        select_y[i] = false;
    select_y[2]   = true;
    //
    // hes_sparsity
    transpose     = false;
    internal_bool = false;
    sparse_rc<s_vector> hes_sparsity;
    f.rev_hes_sparsity(select_y, transpose, internal_bool, hes_sparsity);
    {   // check hes_sparsity
        //
        // row, col
        const s_vector& row       = hes_sparsity.row();
        const s_vector& col       = hes_sparsity.col();
        s_vector        row_major = hes_sparsity.row_major();
        //
        // ok
        ok &= hes_sparsity.nnz() == 4;
        //
        ok &= row[ row_major[0] ] == 2;
        ok &= col[ row_major[0] ] == 4;
        //
        ok &= row[ row_major[1] ] == 3;
        ok &= col[ row_major[1] ] == 6;
        //
        ok &= row[ row_major[2] ] == 4;
        ok &= col[ row_major[2] ] == 2;
        //
        ok &= row[ row_major[3] ] == 6;
        ok &= col[ row_major[3] ] == 3;
    }
    return ok;
}

Input File: example/atomic_four/mat_mul/sparsity.cpp