![]() |
Prev | Next | sparse_hes_pattern_xam.pm | Headings |
package sparse_hes_pattern_xam; sub sparse_hes_pattern_xam() { # check for standard perl programming conventions use strict; use warnings; # # load the Cppad Swig library use pm_cppad; # # initilaize return variable my $ok = 1; # --------------------------------------------------------------------- # number of dependent and independent variables my $n = 3; # # create the independent variables ax my $x = new pm_cppad::vec_double($n); for(my $i = 0; $i < $n ; $i++) { $x->set($i, $i + 2.0); } my $ax = pm_cppad::independent($x); # # create dependent variables ay with ay[i] = ax[j] * ax[i] # where i = mod(j + 1, n) my $ay = new pm_cppad::vec_a_double($n); for(my $j = 0; $j < $n ; $j++) { my $i = $j+1; if( $i >= $n ) { $i = $i - $n; } my $ay_i = $ax->get($i) * $ax->get($j); $ay->set($i, $ay_i); } # # define af corresponding to f(x) my $af = new pm_cppad::a_fun($ax, $ay); # # Set select_d (domain) to all true, initial select_r (range) to all false my $select_d = new pm_cppad::vec_bool($n); my $select_r = new pm_cppad::vec_bool($n); for(my $i = 0; $i < $n; $i++) { $select_d->set($i, 1); $select_r->set($i, 0); } # # only select component 0 of the range function # f_0 (x) = x_0 * x_{n-1} $select_r->set(0, 1); # # loop over forward and reverse mode for(my $mode = 0; $mode < 2; $mode++) { my $pat_out = new pm_cppad::sparse_rc(); if( $mode == 0 ) { $af->for_hes_sparsity($select_d, $select_r, $pat_out); } if( $mode == 1 ) { $af->rev_hes_sparsity($select_d, $select_r, $pat_out); } # # check that result is sparsity pattern for Hessian of f_0 (x) $ok = $ok && $pat_out->nnz() == 2 ; my $row = $pat_out->row(); my $col = $pat_out->col(); for(my $k = 0; $k < 2; $k++) { my $r = $row->get($k); my $c = $col->get($k); if( $r <= $c ) { $ok = $ok && $r == 0; $ok = $ok && $c == $n-1; } if( $r >= $c ) { $ok = $ok && $r == $n-1; $ok = $ok && $c == 0; } } } # return( $ok ); }