예제 #1
0
// check a compilation issue with numext::max
double bug_1261() {
  typedef AutoDiffScalar<Matrix2d> AD;
  typedef Matrix<AD,2,1> VectorAD;

  VectorAD v;
  const AD maxVal = v.maxCoeff();
  const AD minVal = v.minCoeff();
  return maxVal.value() + minVal.value();
}
void test_autodiff_vector()
{
  Vector2f p = Vector2f::Random();
  typedef AutoDiffScalar<Vector2f> AD;
  typedef Matrix<AD,2,1> VectorAD;
  VectorAD ap = p.cast<AD>();
  ap.x().derivatives() = Vector2f::UnitX();
  ap.y().derivatives() = Vector2f::UnitY();

  AD res = foo<VectorAD>(ap);
  VERIFY_IS_APPROX(res.value(), foo(p));
}
예제 #3
0
void ADTape<Base>::Independent(VectorAD &x)
{
	// check VectorAD is Simple Vector class with AD<Base> elements
	CheckSimpleVector< AD<Base>, VectorAD>();

	// dimension of the domain space
	size_t n = x.size();
	CPPAD_ASSERT_KNOWN(
		n > 0,
		"Indepdendent: the argument vector x has zero size"
	);
	CPPAD_ASSERT_UNKNOWN( Rec_.num_rec_var() == 0 );

	// mark the beginning of the tape and skip the first variable index 
	// (zero) because parameters use taddr zero
	CPPAD_ASSERT_NARG_NRES(BeginOp, 0, 1);
	Rec_.PutOp(BeginOp);

	// place each of the independent variables in the tape
	CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1);
	size_t j;
	for(j = 0; j < n; j++)
	{	// tape address for this independent variable
		x[j].taddr_ = Rec_.PutOp(InvOp);
		x[j].tape_id_    = id_;
		CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == j+1 );
		CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) );
	}

	// done specifying all of the independent variables
	size_independent_ = n;
}
예제 #4
0
ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y)
{
	CPPAD_ASSERT_KNOWN(
		x.size() > 0,
		"ADFun<Base>: independent variable vector has size zero."
	);
	CPPAD_ASSERT_KNOWN(
		Variable(x[0]),
		"ADFun<Base>: independent variable vector has been changed."
	);
	ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_);
	CPPAD_ASSERT_KNOWN(
		tape->size_independent_ == size_t ( x.size() ),
		"ADFun<Base>: independent variable vector has been changed."
	);
	size_t j, n = x.size();
# ifndef NDEBUG
	size_t i, m = y.size();
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_KNOWN(
		size_t(x[j].taddr_) == (j+1),
		"ADFun<Base>: independent variable vector has been changed."
		);
		CPPAD_ASSERT_KNOWN(
		x[j].tape_id_ == x[0].tape_id_,
		"ADFun<Base>: independent variable vector has been changed."
		);
	}
	for(i = 0; i < m; i++)
	{	CPPAD_ASSERT_KNOWN(
		CppAD::Parameter( y[i] ) | (y[i].tape_id_ == x[0].tape_id_) ,
		"ADFun<Base>: dependent vector contains variables for"
		"\na different tape than the independent variables."
		);
	}
# endif

	// stop the tape and store the operation sequence
	Dependent(tape, y);


	// ad_fun.hpp member values not set by dependent
	check_for_nan_ = true;

	// allocate memory for one zero order taylor_ coefficient
	CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 );
	CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 );
	size_t c = 1;
	size_t r = 1;
	capacity_order(c, r);
	CPPAD_ASSERT_UNKNOWN( cap_order_taylor_     == c );
	CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r );

	// set zero order coefficients corresponding to indpendent variables
	CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );
	for(j = 0; j < n; j++)
	{	CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
		CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) );
		taylor_[ ind_taddr_[j] ]  = x[j].value_;
	}

	// use independent variable values to fill in values for others
	CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_op_rec() );
	CPPAD_ASSERT_UNKNOWN( load_op_.size()  == play_.num_load_op_rec() );
	forward0sweep(std::cout, false,
		n, num_var_tape_, &play_, cap_order_taylor_, taylor_.data(),
		cskip_op_.data(), load_op_,
		compare_change_count_,
		compare_change_number_,
		compare_change_op_index_
	);
	CPPAD_ASSERT_UNKNOWN( compare_change_count_    == 1 );
	CPPAD_ASSERT_UNKNOWN( compare_change_number_   == 0 );
	CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 );

	// now set the number of orders stored
	num_order_taylor_ = 1;

# ifndef NDEBUG
	// on MS Visual Studio 2012, CppAD required in front of isnan ?
	for(i = 0; i < m; i++) 
	if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) )
	{	using std::endl;
		std::ostringstream buf;
		buf << "A dependent variable value is not equal to "
		    << "its tape evaluation value," << endl
		    << "perhaps it is nan." << endl
		    << "Dependent variable value = " 
		    <<  y[i].value_ << endl
		    << "Tape evaluation value    = " 
		    <<  taylor_[dep_taddr_[i]]  << endl
		    << "Difference               = " 
		    <<  y[i].value_ -  taylor_[dep_taddr_[i]]  << endl
		;
		CPPAD_ASSERT_KNOWN(
			0,
			buf.str().c_str()
		);
	}
# endif
}
예제 #5
0
ADFun<Base>::ADFun(const VectorAD &x, const VectorAD &y)
    : total_num_var_(0), taylor_(CPPAD_NULL)
{
    CPPAD_ASSERT_KNOWN(
        x.size() > 0,
        "ADFun<Base>: independent variable vector has size zero."
    );
    CPPAD_ASSERT_KNOWN(
        Variable(x[0]),
        "ADFun<Base>: independent variable vector has been changed."
    );
    ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].id_);
    CPPAD_ASSERT_KNOWN(
        tape->size_independent_ == x.size(),
        "ADFun<Base>: independent variable vector has been changed."
    );
    size_t j, n = x.size();
# ifndef NDEBUG
    size_t i, m = y.size();
    for(j = 0; j < n; j++)
    {   CPPAD_ASSERT_KNOWN(
            x[j].taddr_ == (j+1),
            "ADFun<Base>: independent variable vector has been changed."
        );
        CPPAD_ASSERT_KNOWN(
            x[j].id_ == x[0].id_,
            "ADFun<Base>: independent variable vector has been changed."
        );
    }
    for(i = 0; i < m; i++)
    {   CPPAD_ASSERT_KNOWN(
            CppAD::Parameter( y[i] ) | (y[i].id_ == x[0].id_) ,
            "ADFun<Base>: dependent vector contains variables for"
            "\na different tape than the independent variables."
        );
    }
# endif

    // stop the tape and store the operation sequence
    Dependent(tape, y);

    // allocate memory for one zero order taylor_ coefficient
    taylor_per_var_  = 1;
    taylor_col_dim_  = 1;
    taylor_          = CPPAD_TRACK_NEW_VEC(total_num_var_, taylor_);

    // set zero order coefficients corresponding to indpendent variables
    CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );
    for(j = 0; j < n; j++)
    {   CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );
        CPPAD_ASSERT_UNKNOWN( x[j].taddr_  == (j+1) );
        taylor_[ ind_taddr_[j] ]  = x[j].value_;
    }

    // use independent variable values to fill in values for others
# if CPPAD_USE_FORWARD0SWEEP
    compare_change_ = forward0sweep(
                          false, n, total_num_var_, &play_, taylor_col_dim_, taylor_
                      );
# else
    size_t p = 0;
    compare_change_ = forward_sweep(
                          false, p, n, total_num_var_, &play_, taylor_col_dim_, taylor_
                      );
# endif
    CPPAD_ASSERT_UNKNOWN( compare_change_ == 0 );

# ifndef NDEBUG
    for(i = 0; i < m; i++) if( taylor_[dep_taddr_[i]] != y[i].value_ )
        {   using std::endl;
            std::ostringstream buf;
            buf << "A dependent variable value is not equal to "
                << "its tape evaluation value," << endl
                << "perhaps it is nan." << endl
                << "Dependent variable value = "
                <<  y[i].value_ << endl
                << "Tape evaluation value    = "
                <<  taylor_[dep_taddr_[i]]  << endl
                << "Difference               = "
                <<  y[i].value_ -  taylor_[dep_taddr_[i]]  << endl
                ;
            CPPAD_ASSERT_KNOWN(
                0,
                buf.str().c_str()
            );
        }
# endif
}