Prev Next

Enable use of AD<Base> where Base is std::complex<double>

Example
The file ComplexPoly.cpp contains an example use of std::complex<double> type for a CppAD Base type. It returns true if it succeeds and false otherwise.

See Also
The file not_complex_ad.cpp contains an example using complex arithmetic where the function is not complex differentiable.

CondExpOp
The conditional expressions CondExp requires ordered comparisons (e.g., <) and the C++ standard complex types do not allow for ordered comparisons. Thus, we make it an error to use the conditional comparisons with complex types:
 
namespace CppAD {
	inline std::complex<double> CondExpOp(
		enum CppAD::CompareOp      cop        ,
		const std::complex<double> &left      ,
		const std::complex<double> &right     ,
		const std::complex<double> &trueCase  ,
		const std::complex<double> &falseCase )
	{	CppAD::ErrorHandler::Call(
			true     , __LINE__ , __FILE__ ,
			"std::complex<float> CondExpOp(...)",
			"Error: cannot use CondExp with a complex type"
		);
		return std::complex<double>(0);
	}
}


EqualOpSeq
Complex numbers do not carry operation sequence information. Thus they are equal in this sense if and only if there values are equal.
 
namespace CppAD {
	inline bool EqualOpSeq(
		const std::complex<double> &x , 
		const std::complex<double> &y )
	{	return x == y; 
	}
}


Identical
Complex numbers do not carry operation sequence information. Thus they are all parameters so the identical functions just check values.
 
namespace CppAD {
	inline bool IdenticalPar(const std::complex<double> &x)
	{	return true; }
	inline bool IdenticalZero(const std::complex<double> &x)
	{	return (x == std::complex<double>(0., 0.) ); }
	inline bool IdenticalOne(const std::complex<double> &x)
	{	return (x == std::complex<double>(1., 0.) ); }
	inline bool IdenticalEqualPar(
		const std::complex<double> &x, const std::complex<double> &y)
	{	return (x == y); }
}


Ordered
 
namespace CppAD {
	inline bool GreaterThanZero(const std::complex<double> &x)
	{	CppAD::ErrorHandler::Call(
			true     , __LINE__ , __FILE__ ,
			"GreaterThanZero(x)",
			"Error: cannot use GreaterThanZero with complex"
		);
		return false;
	}
	inline bool GreaterThanOrZero(const std::complex<double> &x)
	{	CppAD::ErrorHandler::Call(
			true     , __LINE__ , __FILE__ ,
			"GreaterThanZero(x)",
			"Error: cannot use GreaterThanZero with complex"
		);
		return false;
	}
	inline bool LessThanZero(const std::complex<double> &x)
	{	CppAD::ErrorHandler::Call(
			true     , __LINE__ , __FILE__ ,
			"LessThanZero(x)",
			"Error: cannot use LessThanZero with complex"
		);
		return false;
	}
	inline bool LessThanOrZero(const std::complex<double> &x)
	{	CppAD::ErrorHandler::Call(
			true     , __LINE__ , __FILE__ ,
			"LessThanZero(x)",
			"Error: cannot use LessThanZero with complex"
		);
		return false;
	}
}


Integer
The implementation of this function must agree with the CppAD user specifications for complex arguments to the Integer function:
 
namespace CppAD {
	inline int Integer(const std::complex<double> &x)
	{	return static_cast<int>( x.real() ); }
}


Standard Functions
The following standard math functions, that are required by base_require , are defined by std::complex: cos, cosh, exp, log, pow, sin, sinh, sqrt. The other standard math functions, (and abs) required by base_require are not defined for complex types (see abs and StdMathUnary ). Hence we make it an error to use them.
 
# define CPPAD_INVALID_COMPLEX_CASE(function)                                 \
inline std::complex<double> function(const std::complex<double> &x)           \
{	CppAD::ErrorHandler::Call(                                            \
		true     , __LINE__ , __FILE__ ,                              \
		"std::complex<double>",                                       \
			"Error: cannot use " #function " with a complex type" \
	);                                                                    \
	return std::complex<double>(0);                                       \
}
namespace CppAD {
	CPPAD_INVALID_COMPLEX_CASE(abs)
	CPPAD_INVALID_COMPLEX_CASE(acos)
	CPPAD_INVALID_COMPLEX_CASE(asin)
	CPPAD_INVALID_COMPLEX_CASE(atan)
	CPPAD_INVALID_COMPLEX_CASE(erf)
}
# undef CPPAD_INVALID_COMPLEX_CASE

Input File: cppad/local/base_complex.hpp