|
Prev
| Next
|
|
|
|
|
|
lu_vec_ad_ok.cpp |
Headings |
@(@\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
.
Lu Factor and Solve With Recorded Pivoting: Example and Test
# include <cppad/cppad.hpp>
# include "lu_vec_ad.hpp"
# include <cppad/speed/det_by_minor.hpp>
bool lu_vec_ad_ok(void)
{ bool ok = true;
using namespace CppAD;
typedef AD<double> ADdouble;
using CppAD::NearEqual;
double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
size_t n = 3;
size_t m = 2;
double a1[] = {
3., 0., 0., // (1,1) is first pivot
1., 2., 1., // (2,2) is second pivot
1., 0., .5 // (3,3) is third pivot
};
double a2[] = {
1., 2., 1., // (1,2) is second pivot
3., 0., 0., // (2,1) is first pivot
1., 0., .5 // (3,3) is third pivot
};
double rhs[] = {
1., 3.,
2., 2.,
3., 1.
};
VecAD<double> Copy (n * n);
VecAD<double> Rhs (n * m);
VecAD<double> Result (n * m);
ADdouble logdet;
ADdouble signdet;
// routine for checking determinants using expansion by minors
det_by_minor<ADdouble> Det(n);
// matrix we are computing the determinant of
CPPAD_TESTVECTOR(ADdouble) A(n * n);
// dependent variable values
CPPAD_TESTVECTOR(ADdouble) Y(1 + n * m);
size_t i;
size_t j;
size_t k;
// Original matrix
for(i = 0; i < n * n; i++)
A[i] = a1[i];
// right hand side
for(j = 0; j < n; j++)
for(k = 0; k < m; k++)
Rhs[ j * m + k ] = rhs[ j * m + k ];
// Declare independent variables
Independent(A);
// Copy the matrix
ADdouble index(0);
for(i = 0; i < n*n; i++)
{ Copy[index] = A[i];
index += 1.;
}
// Solve the equation
signdet = lu_vec_ad(n, m, Copy, Rhs, Result, logdet);
// Result is the first n * m dependent variables
index = 0.;
for(i = 0; i < n * m; i++)
{ Y[i] = Result[index];
index += 1.;
}
// Determinant is last component of the solution
Y[ n * m ] = signdet * exp( logdet );
// construct f: A -> Y
ADFun<double> f(A, Y);
// check determinant using minors routine
ADdouble determinant = Det( A );
ok &= NearEqual(Y[n * m], determinant, eps99, eps99);
// Check solution of Rhs = A * Result
double sum;
for(k = 0; k < m; k++)
{ for(i = 0; i < n; i++)
{ sum = 0.;
for(j = 0; j < n; j++)
sum += a1[i * n + j] * Value( Y[j * m + k] );
ok &= NearEqual( rhs[i * m + k], sum, eps99, eps99);
}
}
CPPAD_TESTVECTOR(double) y2(1 + n * m);
CPPAD_TESTVECTOR(double) A2(n * n);
for(i = 0; i < n * n; i++)
A[i] = A2[i] = a2[i];
y2 = f.Forward(0, A2);
determinant = Det(A);
ok &= NearEqual(y2[ n * m], Value(determinant), eps99, eps99);
// Check solution of Rhs = A2 * Result
for(k = 0; k < m; k++)
{ for(i = 0; i < n; i++)
{ sum = 0.;
for(j = 0; j < n; j++)
sum += a2[i * n + j] * y2[j * m + k];
ok &= NearEqual( rhs[i * m + k], sum, eps99, eps99);
}
}
return ok;
}
Input File: example/general/lu_vec_ad_ok.cpp