Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonsmooth diagnostics - review first before merging, should be coordinated with the respective pull request in cppad #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 43 additions & 0 deletions pycppad/adfun.py
Expand Up @@ -200,6 +200,49 @@ def independent(x) :
msg = 'only implemented where x[j] is int, float, or a_float'
raise NotImplementedError(msg)

def independentdiag(x, opIndex) :
"""
a_x = independent(x): create independent variable vector a_x, equal to x,
and start recording operations that use the class corresponding to ad( x[0] ).
"""
#
# It would be better faster if all this type checking were done in the C++
#
if not isinstance(x, numpy.ndarray) :
raise NotImplementedError('independent(x): x is not of type numpy.array')
#
x0 = x[0]
if isinstance(x0, int) :
for j in range( len(x) ) :
if not isinstance(x[j], int) :
other = 'x[' + str(j) + '] is ' + type(x[j]).__name__
msg = 'independent(x): mixed types x[0] is int and ' + other
raise NotImplementedError(msg)
x = numpy.array(x, dtype=int) # incase dtype of x is object
return cppad_.independentdiag(x, 1, opIndex) # level = 1
#
if isinstance(x0, float) :
for j in range( len(x) ) :
if not isinstance(x[j], float) :
other = 'x[' + str(j) + '] is ' + type(x[j]).__name__
msg = 'independent(x): mixed types x[0] is float and ' + other
raise NotImplementedError(msg)
x = numpy.array(x, dtype=float) # incase dtype of x is object
return cppad_.independentdiag(x, 1, opIndex) # level = 1
#
if isinstance(x0, cppad_.a_float) :
for j in range( len(x) ) :
if not isinstance(x[j], cppad_.a_float) :
other = 'x[' + str(j) + '] is ' + type(x[j]).__name__
msg = 'independent(x): mixed types x[0] is a_float and ' + other
raise NotImplementedError(msg)
return cppad_.independentdiag(x, 2, opIndex) # level = 2
#
msg = 'independent(x): x[0] has type' + type(x0).__name__ + '\n'
msg = 'only implemented where x[j] is int, float, or a_float'
raise NotImplementedError(msg)


class adfun_float(cppad_.adfun_float) :
"""
Create a level zero function object (evaluates using floats).
Expand Down
22 changes: 22 additions & 0 deletions pycppad/pycppad.cpp
Expand Up @@ -646,6 +646,27 @@ namespace pycppad {
CppAD::Independent(a_x);
return vec2array(a_x);
}
array IndependentDiag(array& x_array, int level, int opIndex)
{ PYCPPAD_ASSERT(
level == 1 || level == 2,
"independent: level argument must be 1 or 2."
);
if( level == 1 )
{
double_vec x(x_array);
AD_double_vec a_x(x.size() );
for(size_t j = 0; j < x.size(); j++)
a_x[j] = x[j];
CppAD::IndependentDiag(a_x, opIndex);
return vec2array(a_x);
}
AD_double_vec x(x_array);
AD_AD_double_vec a_x(x.size() );
for(size_t j = 0; j < x.size(); j++)
a_x[j] = x[j];
CppAD::IndependentDiag(a_x, opIndex);
return vec2array(a_x);
}
// -------------------------------------------------------------
double double_(const AD_double& x)
{ return Value(x); }
Expand Down Expand Up @@ -694,6 +715,7 @@ BOOST_PYTHON_MODULE(cppad_)
array::set_module_and_type("numpy", "ndarray");
// --------------------------------------------------------------------
def("independent", pycppad::Independent);
def("independentdiag", pycppad::IndependentDiag);
def("float_", pycppad::double_);
def("a_float_", pycppad::AD_double_);
// documented in adfun.py
Expand Down