#include #include #include #include #include #include /* The following tests do not check for the numerical accuracy of the operations. That is tested in a separate program (complex_accuracy.cpp) which requires mpfr, and takes a lot of time to run. */ template struct TestComplexSizeAndAlignment { void operator()() { THRUST_STATIC_ASSERT( sizeof(thrust::complex) == sizeof(T) * 2 ); THRUST_STATIC_ASSERT( THRUST_ALIGNOF(thrust::complex) == THRUST_ALIGNOF(T) * 2 ); THRUST_STATIC_ASSERT( sizeof(thrust::complex) == sizeof(T) * 2 ); THRUST_STATIC_ASSERT( THRUST_ALIGNOF(thrust::complex) == THRUST_ALIGNOF(T) * 2 ); } }; SimpleUnitTest TestComplexSizeAndAlignmentInstance; template struct TestComplexConstructors { void operator()(void) { thrust::host_vector data = unittest::random_samples(2); thrust::complex a(data[0],data[1]); thrust::complex b(a); a = thrust::complex(data[0],data[1]); ASSERT_ALMOST_EQUAL(a,b); a = thrust::complex(data[0]); ASSERT_EQUAL(data[0], a.real()); ASSERT_EQUAL(T(0), a.imag()); a = thrust::complex(); ASSERT_ALMOST_EQUAL(a,std::complex(0)); a = thrust::complex(thrust::complex(static_cast(data[0]),static_cast(data[1]))); ASSERT_ALMOST_EQUAL(a,b); a = thrust::complex(thrust::complex(static_cast(data[0]),static_cast(data[1]))); ASSERT_ALMOST_EQUAL(a,b); a = thrust::complex(std::complex(static_cast(data[0]),static_cast(data[1]))); ASSERT_ALMOST_EQUAL(a,b); a = thrust::complex(std::complex(static_cast(data[0]),static_cast(data[1]))); ASSERT_ALMOST_EQUAL(a,b); } }; SimpleUnitTest TestComplexConstructorsInstance; template struct TestComplexGetters { void operator()(void) { thrust::host_vector data = unittest::random_samples(2); thrust::complex z(data[0], data[1]); ASSERT_EQUAL(data[0], z.real()); ASSERT_EQUAL(data[1], z.imag()); z.real(data[1]); z.imag(data[0]); ASSERT_EQUAL(data[1], z.real()); ASSERT_EQUAL(data[0], z.imag()); volatile thrust::complex v(data[0], data[1]); ASSERT_EQUAL(data[0], v.real()); ASSERT_EQUAL(data[1], v.imag()); v.real(data[1]); v.imag(data[0]); ASSERT_EQUAL(data[1], v.real()); ASSERT_EQUAL(data[0], v.imag()); } }; SimpleUnitTest TestComplexGettersInstance; template struct TestComplexMemberOperators { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::host_vector data_b = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); thrust::complex b(data_b[0], data_b[1]); std::complex c(a); std::complex d(b); a += b; c += d; ASSERT_ALMOST_EQUAL(a,c); a -= b; c -= d; ASSERT_ALMOST_EQUAL(a,c); a *= b; c *= d; ASSERT_ALMOST_EQUAL(a,c); a /= b; c /= d; ASSERT_ALMOST_EQUAL(a,c); // casting operator c = (std::complex)a; } }; SimpleUnitTest TestComplexMemberOperatorsInstance; template struct TestComplexBasicArithmetic { void operator()(void) { thrust::host_vector data = unittest::random_samples(2); thrust::complex a(data[0], data[1]); std::complex b(a); // Test the basic arithmetic functions against std ASSERT_ALMOST_EQUAL(abs(a),abs(b)); ASSERT_ALMOST_EQUAL(arg(a),arg(b)); ASSERT_ALMOST_EQUAL(norm(a),norm(b)); ASSERT_EQUAL(conj(a),conj(b)); ASSERT_ALMOST_EQUAL(thrust::polar(data[0],data[1]),std::polar(data[0],data[1])); // random_samples does not seem to produce infinities so proj(z) == z ASSERT_EQUAL(proj(a),a); } }; SimpleUnitTest TestComplexBasicArithmeticInstance; template struct TestComplexBinaryArithmetic { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::host_vector data_b = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); thrust::complex b(data_b[0], data_b[1]); ASSERT_ALMOST_EQUAL(a*b,std::complex(a) * std::complex(b)); ASSERT_ALMOST_EQUAL(a*data_b[0],std::complex(a) * data_b[0]); ASSERT_ALMOST_EQUAL(data_a[0]*b,data_b[0] * std::complex(b)); ASSERT_ALMOST_EQUAL(a / b, std::complex(a) / std::complex(b)); ASSERT_ALMOST_EQUAL(a / data_b[0], std::complex(a) / data_b[0]); ASSERT_ALMOST_EQUAL(data_a[0] / b, data_b[0] / std::complex(b)); ASSERT_EQUAL(a + b, std::complex(a) + std::complex(b)); ASSERT_EQUAL(a + data_b[0], std::complex(a) + data_b[0]); ASSERT_EQUAL(data_a[0] + b, data_b[0] + std::complex(b)); ASSERT_EQUAL(a - b, std::complex(a) - std::complex(b)); ASSERT_EQUAL(a - data_b[0], std::complex(a) - data_b[0]); ASSERT_EQUAL(data_a[0] - b, data_b[0] - std::complex(b)); } }; SimpleUnitTest TestComplexBinaryArithmeticInstance; template struct TestComplexUnaryArithmetic { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); ASSERT_EQUAL(+a,+std::complex(a)); ASSERT_EQUAL(-a,-std::complex(a)); } }; SimpleUnitTest TestComplexUnaryArithmeticInstance; template struct TestComplexExponentialFunctions { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); std::complex b(a); ASSERT_ALMOST_EQUAL(exp(a),exp(b)); ASSERT_ALMOST_EQUAL(log(a),log(b)); ASSERT_ALMOST_EQUAL(log10(a),log10(b)); } }; SimpleUnitTest TestComplexExponentialFunctionsInstance; template struct TestComplexPowerFunctions { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::host_vector data_b = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); thrust::complex b(data_b[0], data_b[1]); std::complex c(a); std::complex d(b); ASSERT_ALMOST_EQUAL(pow(a,b),pow(c,d)); ASSERT_ALMOST_EQUAL(pow(a,b.real()),pow(c,d.real())); ASSERT_ALMOST_EQUAL(pow(a.real(),b),pow(c.real(),d)); ASSERT_ALMOST_EQUAL(sqrt(a),sqrt(c)); } }; SimpleUnitTest TestComplexPowerFunctionsInstance; template struct TestComplexTrigonometricFunctions { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); std::complex c(a); ASSERT_ALMOST_EQUAL(cos(a),cos(c)); ASSERT_ALMOST_EQUAL(sin(a),sin(c)); ASSERT_ALMOST_EQUAL(tan(a),tan(c)); ASSERT_ALMOST_EQUAL(cosh(a),cosh(c)); ASSERT_ALMOST_EQUAL(sinh(a),sinh(c)); ASSERT_ALMOST_EQUAL(tanh(a),tanh(c)); #if THRUST_CPP_DIALECT >= 2011 ASSERT_ALMOST_EQUAL(acos(a),acos(c)); ASSERT_ALMOST_EQUAL(asin(a),asin(c)); ASSERT_ALMOST_EQUAL(atan(a),atan(c)); ASSERT_ALMOST_EQUAL(acosh(a),acosh(c)); ASSERT_ALMOST_EQUAL(asinh(a),asinh(c)); ASSERT_ALMOST_EQUAL(atanh(a),atanh(c)); #endif } }; SimpleUnitTest TestComplexTrigonometricFunctionsInstance; template struct TestComplexStreamOperators { void operator()(void) { thrust::host_vector data_a = unittest::random_samples(2); thrust::complex a(data_a[0], data_a[1]); std::stringstream out; out << a; thrust::complex b; out >> b; ASSERT_ALMOST_EQUAL(a,b); } }; SimpleUnitTest TestComplexStreamOperatorsInstance; #if THRUST_CPP_DIALECT >= 2011 template struct TestComplexStdComplexDeviceInterop { void operator()() { thrust::host_vector data = unittest::random_samples(6); std::vector > vec(10); vec[0] = std::complex(data[0], data[1]); vec[1] = std::complex(data[2], data[3]); vec[2] = std::complex(data[4], data[5]); thrust::device_vector > device_vec = vec; ASSERT_ALMOST_EQUAL(vec[0].real(), thrust::complex(device_vec[0]).real()); ASSERT_ALMOST_EQUAL(vec[0].imag(), thrust::complex(device_vec[0]).imag()); ASSERT_ALMOST_EQUAL(vec[1].real(), thrust::complex(device_vec[1]).real()); ASSERT_ALMOST_EQUAL(vec[1].imag(), thrust::complex(device_vec[1]).imag()); ASSERT_ALMOST_EQUAL(vec[2].real(), thrust::complex(device_vec[2]).real()); ASSERT_ALMOST_EQUAL(vec[2].imag(), thrust::complex(device_vec[2]).imag()); } }; SimpleUnitTest TestComplexStdComplexDeviceInteropInstance; #endif